Устранение неполадок совместимости

Итак, вы добавили новый параметр в метод, изменили тип возвращаемого значения, изменили тип параметра или изменили его значение по умолчанию, и теперь автоматизированное тестирование жалуется на нарушения совместимости?

Следует избегать нарушения совместимости, но при необходимости существуют системы, которые справляются с этим таким образом, чтобы переход был максимально плавным.

Практический пример

Эти изменения взяты из запроса на включение изменений #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 в данном случае:

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:

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 (включая изменения, не показанные в этом примере):

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.