Up to date
This page is up to date for Godot 4.3.
If you still find outdated information, please open an issue.
处理兼容问题
听说你为方法添加了新参数、更改了返回类型、更改了参数的类型或默认值,而现在自动测试却在抱怨兼容性问题?
我们应该避免破坏兼容性,但如果必须破坏,也有相应的系统来处理这种情况,使过渡尽可能顺畅。
实际案例
这些修改取自拉取请求 #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);
修改后:
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_compt_ 加上引入该修改的 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 验证环节中汇报的改动加入到相关的验证文件中。因为这个 PR 是在 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 文件中,应当通过正确绑定兼容性方法来修复。
这样就大功告成了!你可能还会遇到更加复杂的情况,比如重新排列参数、修改返回类型等,但这个系统的基本用法就是这样的。
详情见拉取请求 #76446。