Устранение неполадок совместимости
Итак, вы добавили новый параметр в метод, изменили тип возвращаемого значения, изменили тип параметра или изменили его значение по умолчанию, и теперь автоматизированное тестирование жалуется на нарушения совместимости?
Следует избегать нарушения совместимости, но при необходимости существуют системы, которые справляются с этим таким образом, чтобы переход был максимально плавным.
Практический пример
Эти изменения взяты из запроса на включение изменений #88047, который добавил новые возможности построения путей в AStarGrid2D и другие классы AStar. Среди прочих изменений были изменены следующие методы в core/math/a_star_grid_2d.h:
Vector<Vector2> get_point_path(const Vector2i &p_from, const Vector2i &p_to);
TypedArray<Vector2i> get_id_path(const Vector2i &p_from, const Vector2i &p_to);
To:
Vector<Vector2> get_point_path(const Vector2i &p_from, const Vector2i &p_to, bool p_allow_partial_path = false);
TypedArray<Vector2i> get_id_path(const Vector2i &p_from, const Vector2i &p_to, bool p_allow_partial_path = false);
Это означало добавление в файл новых привязок методов совместимости, которые должны находиться в разделе protected кода, обычно размещаемом рядом с _bind_methods():
#ifndef DISABLE_DEPRECATED
TypedArray<Vector2i> _get_id_path_bind_compat_88047(const Vector2i &p_from, const Vector2i &p_to);
Vector<Vector2> _get_point_path_bind_compat_88047(const Vector2i &p_from, const Vector2i &p_to);
static void _bind_compatibility_methods();
#endif
Они должны начинаться с символа _, указывающего на то, что они внутренние, и заканчиваться символом _bind_compat_, за которым следует номер PR, внесшего изменение (88047 в данном примере). Эти методы совместимости необходимо реализовать в отдельном файле, например, core/math/a_star_grid_2d.compat.inc в данном случае:
/**************************************************************************/
/* a_star_grid_2d.compat.inc */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DISABLE_DEPRECATED
#include "core/variant/typed_array.h"
TypedArray<Vector2i> AStarGrid2D::_get_id_path_bind_compat_88047(const Vector2i &p_from_id, const Vector2i &p_to_id) {
return get_id_path(p_from_id, p_to_id, false);
}
Vector<Vector2> AStarGrid2D::_get_point_path_bind_compat_88047(const Vector2i &p_from_id, const Vector2i &p_to_id) {
return get_point_path(p_from_id, p_to_id, false);
}
void AStarGrid2D::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStarGrid2D::_get_id_path_bind_compat_88047);
ClassDB::bind_compatibility_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStarGrid2D::_get_point_path_bind_compat_88047);
}
#endif // DISABLE_DEPRECATED
Если изменение совместимости не является сложным, метод совместимости должен вызывать изменённый метод напрямую, а не дублировать его. Убедитесь, что аргументы по умолчанию для этого метода совпадают (в примере выше это false).
Этот файл всегда должен располагаться рядом с исходным файлом и заканчиваться расширением .compat.inc вместо .cpp или .h. Далее, его необходимо включить в файл .cpp, в который мы добавляем методы совместимости, то есть core/math/a_star_grid_2d.cpp:
#include "a_star_grid_2d.h"
#include "a_star_grid_2d.compat.inc"
#include "core/variant/typed_array.h"
И наконец, изменения, выявленные на этапе валидации API, следует добавить в соответствующий файл валидации. Поскольку это было сделано во время разработки версии 4.3, это будет misc/extension_api_validation/4.2-stable.expected (включая изменения, не показанные в этом примере):
GH-88047
--------
Validate extension JSON: Error: Field 'classes/AStar2D/methods/get_id_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStar2D/methods/get_point_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStar3D/methods/get_id_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStar3D/methods/get_point_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStarGrid2D/methods/get_id_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStarGrid2D/methods/get_point_path/arguments': size changed value in new API, from 2 to 3.
Added optional "allow_partial_path" argument to get_id_path and get_point_path methods in AStar classes.
Compatibility methods registered.
Инструкции по добавлению данных в этот файл находятся в верхней части самого файла.
Если для метода возникает ошибка "Hash changed" (Хеш изменён), это означает, что привязка совместимости отсутствует или неверна. Такие строки не следует добавлять в файл .expected, а следует исправить, привязав соответствующий метод совместимости.
Вот и всё! Возможно, вам придётся столкнуться с более сложными случаями, такими как переупорядочивание аргументов, изменение типов возвращаемых данных и т. д., но здесь описаны основы использования этой системы.
Для получения дополнительной информации см. pull request #76446.