處理相容性破壞

你是否曾在方法中新增參數、更改回傳型態、變更參數型態,或修改預設值,然後自動化測試報告出現相容性破壞的錯誤?

應盡量避免破壞相容性,但如有必要,Godot 提供相關機制,以盡可能平順地完成過渡。

實際範例

以下變更取自 pull request #88047,該 PR 為 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_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