Allow method binds to take Object subclasses as arguments
This commit adds a condition to VariantCaster that casts Variants of type OBJECT to any type T, if T is derived from Object. This change enables a fair bit of code cleanup. First, the Variant implicit cast operators for Node and Control can be removed, which allows for some invalid includes to be removed. Second, helper methods in Tree whose sole purpose was to cast arguments to TreeItem * are no longer necessary. A few small changes also had to be made to other files, due to the changes cascading down all the includes.
This commit is contained in:
parent
2f4d76f068
commit
051ef479c9
@ -37,6 +37,8 @@
|
|||||||
#include "core/templates/safe_refcount.h"
|
#include "core/templates/safe_refcount.h"
|
||||||
#include "core/templates/self_list.h"
|
#include "core/templates/self_list.h"
|
||||||
|
|
||||||
|
class Node;
|
||||||
|
|
||||||
#define RES_BASE_EXTENSION(m_ext) \
|
#define RES_BASE_EXTENSION(m_ext) \
|
||||||
public: \
|
public: \
|
||||||
static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension(m_ext, get_class_static()); } \
|
static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension(m_ext, get_class_static()); } \
|
||||||
|
@ -44,24 +44,42 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// Variant cannot define an implicit cast operator for every Object subclass, so the
|
||||||
|
// casting is done here, to allow binding methods with parameters more specific than Object *
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct VariantCaster {
|
struct VariantCaster {
|
||||||
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
|
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
|
||||||
return p_variant;
|
using TStripped = std::remove_pointer_t<T>;
|
||||||
|
if constexpr (std::is_base_of<Object, TStripped>::value) {
|
||||||
|
return Object::cast_to<TStripped>(p_variant);
|
||||||
|
} else {
|
||||||
|
return p_variant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct VariantCaster<T &> {
|
struct VariantCaster<T &> {
|
||||||
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
|
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
|
||||||
return p_variant;
|
using TStripped = std::remove_pointer_t<T>;
|
||||||
|
if constexpr (std::is_base_of<Object, TStripped>::value) {
|
||||||
|
return Object::cast_to<TStripped>(p_variant);
|
||||||
|
} else {
|
||||||
|
return p_variant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct VariantCaster<const T &> {
|
struct VariantCaster<const T &> {
|
||||||
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
|
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
|
||||||
return p_variant;
|
using TStripped = std::remove_pointer_t<T>;
|
||||||
|
if constexpr (std::is_base_of<Object, TStripped>::value) {
|
||||||
|
return Object::cast_to<TStripped>(p_variant);
|
||||||
|
} else {
|
||||||
|
return p_variant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -135,7 +153,13 @@ struct PtrToArg<char32_t> {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct VariantObjectClassChecker {
|
struct VariantObjectClassChecker {
|
||||||
static _FORCE_INLINE_ bool check(const Variant &p_variant) {
|
static _FORCE_INLINE_ bool check(const Variant &p_variant) {
|
||||||
return true;
|
using TStripped = std::remove_pointer_t<T>;
|
||||||
|
if constexpr (std::is_base_of<Object, TStripped>::value) {
|
||||||
|
Object *obj = p_variant;
|
||||||
|
return Object::cast_to<TStripped>(p_variant) || !obj;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -151,24 +175,6 @@ struct VariantObjectClassChecker<const Ref<T> &> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
struct VariantObjectClassChecker<Node *> {
|
|
||||||
static _FORCE_INLINE_ bool check(const Variant &p_variant) {
|
|
||||||
Object *obj = p_variant;
|
|
||||||
Node *node = p_variant;
|
|
||||||
return node || !obj;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct VariantObjectClassChecker<Control *> {
|
|
||||||
static _FORCE_INLINE_ bool check(const Variant &p_variant) {
|
|
||||||
Object *obj = p_variant;
|
|
||||||
Control *control = p_variant;
|
|
||||||
return control || !obj;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
#ifdef DEBUG_METHODS_ENABLED
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -38,8 +38,6 @@
|
|||||||
#include "core/math/math_funcs.h"
|
#include "core/math/math_funcs.h"
|
||||||
#include "core/string/print_string.h"
|
#include "core/string/print_string.h"
|
||||||
#include "core/variant/variant_parser.h"
|
#include "core/variant/variant_parser.h"
|
||||||
#include "scene/gui/control.h"
|
|
||||||
#include "scene/main/node.h"
|
|
||||||
|
|
||||||
String Variant::get_type_name(Variant::Type p_type) {
|
String Variant::get_type_name(Variant::Type p_type) {
|
||||||
switch (p_type) {
|
switch (p_type) {
|
||||||
@ -2006,22 +2004,6 @@ Object *Variant::get_validated_object() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator Node *() const {
|
|
||||||
if (type == OBJECT) {
|
|
||||||
return Object::cast_to<Node>(_get_obj().obj);
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant::operator Control *() const {
|
|
||||||
if (type == OBJECT) {
|
|
||||||
return Object::cast_to<Control>(_get_obj().obj);
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant::operator Dictionary() const {
|
Variant::operator Dictionary() const {
|
||||||
if (type == DICTIONARY) {
|
if (type == DICTIONARY) {
|
||||||
return *reinterpret_cast<const Dictionary *>(_data._mem);
|
return *reinterpret_cast<const Dictionary *>(_data._mem);
|
||||||
@ -3416,7 +3398,7 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
|
|||||||
}
|
}
|
||||||
|
|
||||||
String class_name = p_base->get_class();
|
String class_name = p_base->get_class();
|
||||||
Ref<Script> script = p_base->get_script();
|
Ref<Resource> script = p_base->get_script();
|
||||||
if (script.is_valid() && script->get_path().is_resource_file()) {
|
if (script.is_valid() && script->get_path().is_resource_file()) {
|
||||||
class_name += "(" + script->get_path().get_file() + ")";
|
class_name += "(" + script->get_path().get_file() + ")";
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,6 @@
|
|||||||
#include "core/variant/dictionary.h"
|
#include "core/variant/dictionary.h"
|
||||||
|
|
||||||
class Object;
|
class Object;
|
||||||
class Node; // helper
|
|
||||||
class Control; // helper
|
|
||||||
|
|
||||||
struct PropertyInfo;
|
struct PropertyInfo;
|
||||||
struct MethodInfo;
|
struct MethodInfo;
|
||||||
@ -339,8 +337,6 @@ public:
|
|||||||
operator ::RID() const;
|
operator ::RID() const;
|
||||||
|
|
||||||
operator Object *() const;
|
operator Object *() const;
|
||||||
operator Node *() const;
|
|
||||||
operator Control *() const;
|
|
||||||
|
|
||||||
operator Callable() const;
|
operator Callable() const;
|
||||||
operator Signal() const;
|
operator Signal() const;
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
</method>
|
</method>
|
||||||
<method name="create_item">
|
<method name="create_item">
|
||||||
<return type="TreeItem" />
|
<return type="TreeItem" />
|
||||||
<argument index="0" name="parent" type="Object" default="null" />
|
<argument index="0" name="parent" type="TreeItem" default="null" />
|
||||||
<argument index="1" name="idx" type="int" default="-1" />
|
<argument index="1" name="idx" type="int" default="-1" />
|
||||||
<description>
|
<description>
|
||||||
Creates an item in the tree and adds it as a child of [code]parent[/code].
|
Creates an item in the tree and adds it as a child of [code]parent[/code].
|
||||||
@ -170,7 +170,7 @@
|
|||||||
</method>
|
</method>
|
||||||
<method name="get_item_area_rect" qualifiers="const">
|
<method name="get_item_area_rect" qualifiers="const">
|
||||||
<return type="Rect2" />
|
<return type="Rect2" />
|
||||||
<argument index="0" name="item" type="Object" />
|
<argument index="0" name="item" type="TreeItem" />
|
||||||
<argument index="1" name="column" type="int" default="-1" />
|
<argument index="1" name="column" type="int" default="-1" />
|
||||||
<description>
|
<description>
|
||||||
Returns the rectangle area for the specified item. If [code]column[/code] is specified, only get the position and size of that column, otherwise get the rectangle containing all columns.
|
Returns the rectangle area for the specified item. If [code]column[/code] is specified, only get the position and size of that column, otherwise get the rectangle containing all columns.
|
||||||
@ -185,7 +185,7 @@
|
|||||||
</method>
|
</method>
|
||||||
<method name="get_next_selected">
|
<method name="get_next_selected">
|
||||||
<return type="TreeItem" />
|
<return type="TreeItem" />
|
||||||
<argument index="0" name="from" type="Object" />
|
<argument index="0" name="from" type="TreeItem" />
|
||||||
<description>
|
<description>
|
||||||
Returns the next selected item after the given one, or [code]null[/code] if the end is reached.
|
Returns the next selected item after the given one, or [code]null[/code] if the end is reached.
|
||||||
If [code]from[/code] is [code]null[/code], this returns the first selected item.
|
If [code]from[/code] is [code]null[/code], this returns the first selected item.
|
||||||
@ -239,7 +239,7 @@
|
|||||||
</method>
|
</method>
|
||||||
<method name="scroll_to_item">
|
<method name="scroll_to_item">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<argument index="0" name="item" type="Object" />
|
<argument index="0" name="item" type="TreeItem" />
|
||||||
<description>
|
<description>
|
||||||
Causes the [Tree] to jump to the specified item.
|
Causes the [Tree] to jump to the specified item.
|
||||||
</description>
|
</description>
|
||||||
|
@ -2695,7 +2695,7 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!base_node && get_edited_object()->has_method("get_root_path")) {
|
if (!base_node && get_edited_object()->has_method("get_root_path")) {
|
||||||
base_node = get_edited_object()->call("get_root_path");
|
base_node = Object::cast_to<Node>(get_edited_object()->call("get_root_path"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!base_node && Object::cast_to<RefCounted>(get_edited_object())) {
|
if (!base_node && Object::cast_to<RefCounted>(get_edited_object())) {
|
||||||
|
@ -3977,7 +3977,7 @@ void CanvasItemEditor::_selection_changed() {
|
|||||||
|
|
||||||
void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
|
void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
|
||||||
Array selection = editor_selection->get_selected_nodes();
|
Array selection = editor_selection->get_selected_nodes();
|
||||||
if (selection.size() != 1 || (Node *)selection[0] != p_canvas_item) {
|
if (selection.size() != 1 || Object::cast_to<Node>(selection[0]) != p_canvas_item) {
|
||||||
drag_type = DRAG_NONE;
|
drag_type = DRAG_NONE;
|
||||||
|
|
||||||
// Clear the selection
|
// Clear the selection
|
||||||
|
@ -6623,7 +6623,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
|
|||||||
// For snapping to be performed, there must be solid geometry under at least one of the selected nodes.
|
// For snapping to be performed, there must be solid geometry under at least one of the selected nodes.
|
||||||
// We need to check this before snapping to register the undo/redo action only if needed.
|
// We need to check this before snapping to register the undo/redo action only if needed.
|
||||||
for (int i = 0; i < keys.size(); i++) {
|
for (int i = 0; i < keys.size(); i++) {
|
||||||
Node *node = keys[i];
|
Node *node = Object::cast_to<Node>(keys[i]);
|
||||||
Node3D *sp = Object::cast_to<Node3D>(node);
|
Node3D *sp = Object::cast_to<Node3D>(node);
|
||||||
Dictionary d = snap_data[node];
|
Dictionary d = snap_data[node];
|
||||||
Vector3 from = d["from"];
|
Vector3 from = d["from"];
|
||||||
@ -6645,7 +6645,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
|
|||||||
|
|
||||||
// Perform snapping if at least one node can be snapped
|
// Perform snapping if at least one node can be snapped
|
||||||
for (int i = 0; i < keys.size(); i++) {
|
for (int i = 0; i < keys.size(); i++) {
|
||||||
Node *node = keys[i];
|
Node *node = Object::cast_to<Node>(keys[i]);
|
||||||
Node3D *sp = Object::cast_to<Node3D>(node);
|
Node3D *sp = Object::cast_to<Node3D>(node);
|
||||||
Dictionary d = snap_data[node];
|
Dictionary d = snap_data[node];
|
||||||
Vector3 from = d["from"];
|
Vector3 from = d["from"];
|
||||||
|
@ -2802,7 +2802,7 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (String(d["type"]) == "script_list_element") {
|
if (String(d["type"]) == "script_list_element") {
|
||||||
Node *node = d["script_list_element"];
|
Node *node = Object::cast_to<Node>(d["script_list_element"]);
|
||||||
|
|
||||||
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
|
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
|
||||||
if (se) {
|
if (se) {
|
||||||
@ -2875,7 +2875,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (String(d["type"]) == "script_list_element") {
|
if (String(d["type"]) == "script_list_element") {
|
||||||
Node *node = d["script_list_element"];
|
Node *node = Object::cast_to<Node>(d["script_list_element"]);
|
||||||
|
|
||||||
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
|
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
|
||||||
EditorHelp *eh = Object::cast_to<EditorHelp>(node);
|
EditorHelp *eh = Object::cast_to<EditorHelp>(node);
|
||||||
|
@ -362,7 +362,7 @@ void RenameDialog::_post_popup() {
|
|||||||
Array selected_node_list = editor_selection->get_selected_nodes();
|
Array selected_node_list = editor_selection->get_selected_nodes();
|
||||||
ERR_FAIL_COND(selected_node_list.size() == 0);
|
ERR_FAIL_COND(selected_node_list.size() == 0);
|
||||||
|
|
||||||
preview_node = selected_node_list[0];
|
preview_node = Object::cast_to<Node>(selected_node_list[0]);
|
||||||
|
|
||||||
_update_preview();
|
_update_preview();
|
||||||
_update_substitute();
|
_update_substitute();
|
||||||
|
@ -585,7 +585,7 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S
|
|||||||
stack.push_back(owner_scene_node);
|
stack.push_back(owner_scene_node);
|
||||||
|
|
||||||
while (!stack.is_empty()) {
|
while (!stack.is_empty()) {
|
||||||
current = stack.pop_back();
|
current = Object::cast_to<Node>(stack.pop_back());
|
||||||
Ref<GDScript> script = current->get_script();
|
Ref<GDScript> script = current->get_script();
|
||||||
if (script.is_valid() && script->get_path() == path) {
|
if (script.is_valid() && script->get_path() == path) {
|
||||||
break;
|
break;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "core/variant/array.h"
|
#include "core/variant/array.h"
|
||||||
|
|
||||||
class Script;
|
class Script;
|
||||||
|
class Node;
|
||||||
|
|
||||||
class SceneDebugger {
|
class SceneDebugger {
|
||||||
public:
|
public:
|
||||||
|
@ -4752,7 +4752,7 @@ bool Tree::get_allow_reselect() const {
|
|||||||
|
|
||||||
void Tree::_bind_methods() {
|
void Tree::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("clear"), &Tree::clear);
|
ClassDB::bind_method(D_METHOD("clear"), &Tree::clear);
|
||||||
ClassDB::bind_method(D_METHOD("create_item", "parent", "idx"), &Tree::_create_item, DEFVAL(Variant()), DEFVAL(-1));
|
ClassDB::bind_method(D_METHOD("create_item", "parent", "idx"), &Tree::create_item, DEFVAL(Variant()), DEFVAL(-1));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_root"), &Tree::get_root);
|
ClassDB::bind_method(D_METHOD("get_root"), &Tree::get_root);
|
||||||
ClassDB::bind_method(D_METHOD("set_column_custom_minimum_width", "column", "min_width"), &Tree::set_column_custom_minimum_width);
|
ClassDB::bind_method(D_METHOD("set_column_custom_minimum_width", "column", "min_width"), &Tree::set_column_custom_minimum_width);
|
||||||
@ -4767,7 +4767,7 @@ void Tree::_bind_methods() {
|
|||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_hide_root", "enable"), &Tree::set_hide_root);
|
ClassDB::bind_method(D_METHOD("set_hide_root", "enable"), &Tree::set_hide_root);
|
||||||
ClassDB::bind_method(D_METHOD("is_root_hidden"), &Tree::is_root_hidden);
|
ClassDB::bind_method(D_METHOD("is_root_hidden"), &Tree::is_root_hidden);
|
||||||
ClassDB::bind_method(D_METHOD("get_next_selected", "from"), &Tree::_get_next_selected);
|
ClassDB::bind_method(D_METHOD("get_next_selected", "from"), &Tree::get_next_selected);
|
||||||
ClassDB::bind_method(D_METHOD("get_selected"), &Tree::get_selected);
|
ClassDB::bind_method(D_METHOD("get_selected"), &Tree::get_selected);
|
||||||
ClassDB::bind_method(D_METHOD("get_selected_column"), &Tree::get_selected_column);
|
ClassDB::bind_method(D_METHOD("get_selected_column"), &Tree::get_selected_column);
|
||||||
ClassDB::bind_method(D_METHOD("get_pressed_button"), &Tree::get_pressed_button);
|
ClassDB::bind_method(D_METHOD("get_pressed_button"), &Tree::get_pressed_button);
|
||||||
@ -4781,7 +4781,7 @@ void Tree::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("get_edited_column"), &Tree::get_edited_column);
|
ClassDB::bind_method(D_METHOD("get_edited_column"), &Tree::get_edited_column);
|
||||||
ClassDB::bind_method(D_METHOD("edit_selected"), &Tree::edit_selected);
|
ClassDB::bind_method(D_METHOD("edit_selected"), &Tree::edit_selected);
|
||||||
ClassDB::bind_method(D_METHOD("get_custom_popup_rect"), &Tree::get_custom_popup_rect);
|
ClassDB::bind_method(D_METHOD("get_custom_popup_rect"), &Tree::get_custom_popup_rect);
|
||||||
ClassDB::bind_method(D_METHOD("get_item_area_rect", "item", "column"), &Tree::_get_item_rect, DEFVAL(-1));
|
ClassDB::bind_method(D_METHOD("get_item_area_rect", "item", "column"), &Tree::get_item_rect, DEFVAL(-1));
|
||||||
ClassDB::bind_method(D_METHOD("get_item_at_position", "position"), &Tree::get_item_at_position);
|
ClassDB::bind_method(D_METHOD("get_item_at_position", "position"), &Tree::get_item_at_position);
|
||||||
ClassDB::bind_method(D_METHOD("get_column_at_position", "position"), &Tree::get_column_at_position);
|
ClassDB::bind_method(D_METHOD("get_column_at_position", "position"), &Tree::get_column_at_position);
|
||||||
ClassDB::bind_method(D_METHOD("get_drop_section_at_position", "position"), &Tree::get_drop_section_at_position);
|
ClassDB::bind_method(D_METHOD("get_drop_section_at_position", "position"), &Tree::get_drop_section_at_position);
|
||||||
@ -4805,7 +4805,7 @@ void Tree::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("get_column_title_language", "column"), &Tree::get_column_title_language);
|
ClassDB::bind_method(D_METHOD("get_column_title_language", "column"), &Tree::get_column_title_language);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_scroll"), &Tree::get_scroll);
|
ClassDB::bind_method(D_METHOD("get_scroll"), &Tree::get_scroll);
|
||||||
ClassDB::bind_method(D_METHOD("scroll_to_item", "item"), &Tree::_scroll_to_item);
|
ClassDB::bind_method(D_METHOD("scroll_to_item", "item"), &Tree::scroll_to_item);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_h_scroll_enabled", "h_scroll"), &Tree::set_h_scroll_enabled);
|
ClassDB::bind_method(D_METHOD("set_h_scroll_enabled", "h_scroll"), &Tree::set_h_scroll_enabled);
|
||||||
ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &Tree::is_h_scroll_enabled);
|
ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &Tree::is_h_scroll_enabled);
|
||||||
|
@ -609,23 +609,6 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
//bind helpers
|
|
||||||
TreeItem *_create_item(Object *p_parent, int p_idx = -1) {
|
|
||||||
return create_item(Object::cast_to<TreeItem>(p_parent), p_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeItem *_get_next_selected(Object *p_item) {
|
|
||||||
return get_next_selected(Object::cast_to<TreeItem>(p_item));
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect2 _get_item_rect(Object *p_item, int p_column) const {
|
|
||||||
return get_item_rect(Object::cast_to<TreeItem>(p_item), p_column);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _scroll_to_item(Object *p_item) {
|
|
||||||
scroll_to_item(Object::cast_to<TreeItem>(p_item));
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
||||||
|
|
||||||
|
@ -51,9 +51,15 @@ public:
|
|||||||
TEST_METHODRC,
|
TEST_METHODRC,
|
||||||
TEST_METHODRC_ARGS,
|
TEST_METHODRC_ARGS,
|
||||||
TEST_METHOD_DEFARGS,
|
TEST_METHOD_DEFARGS,
|
||||||
|
TEST_METHOD_OBJECT_CAST,
|
||||||
TEST_MAX
|
TEST_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ObjectSubclass : public Object {
|
||||||
|
public:
|
||||||
|
int value = 1;
|
||||||
|
};
|
||||||
|
|
||||||
int test_num = 0;
|
int test_num = 0;
|
||||||
|
|
||||||
bool test_valid[TEST_MAX];
|
bool test_valid[TEST_MAX];
|
||||||
@ -98,6 +104,10 @@ public:
|
|||||||
test_valid[TEST_METHOD_DEFARGS] = p_arg1 == 1 && p_arg2 == 2 && p_arg3 == 3 && p_arg4 == 4 && p_arg5 == 5; //temporary
|
test_valid[TEST_METHOD_DEFARGS] = p_arg1 == 1 && p_arg2 == 2 && p_arg3 == 3 && p_arg4 == 4 && p_arg5 == 5; //temporary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_method_object_cast(ObjectSubclass *p_object) {
|
||||||
|
test_valid[TEST_METHOD_OBJECT_CAST] = p_object->value == 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void _bind_methods() {
|
static void _bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("test_method"), &MethodBindTester::test_method);
|
ClassDB::bind_method(D_METHOD("test_method"), &MethodBindTester::test_method);
|
||||||
ClassDB::bind_method(D_METHOD("test_method_args"), &MethodBindTester::test_method_args);
|
ClassDB::bind_method(D_METHOD("test_method_args"), &MethodBindTester::test_method_args);
|
||||||
@ -108,6 +118,7 @@ public:
|
|||||||
ClassDB::bind_method(D_METHOD("test_methodrc"), &MethodBindTester::test_methodrc);
|
ClassDB::bind_method(D_METHOD("test_methodrc"), &MethodBindTester::test_methodrc);
|
||||||
ClassDB::bind_method(D_METHOD("test_methodrc_args"), &MethodBindTester::test_methodrc_args);
|
ClassDB::bind_method(D_METHOD("test_methodrc_args"), &MethodBindTester::test_methodrc_args);
|
||||||
ClassDB::bind_method(D_METHOD("test_method_default_args"), &MethodBindTester::test_method_default_args, DEFVAL(9) /* wrong on purpose */, DEFVAL(4), DEFVAL(5));
|
ClassDB::bind_method(D_METHOD("test_method_default_args"), &MethodBindTester::test_method_default_args, DEFVAL(9) /* wrong on purpose */, DEFVAL(4), DEFVAL(5));
|
||||||
|
ClassDB::bind_method(D_METHOD("test_method_object_cast", "object"), &MethodBindTester::test_method_object_cast);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void run_tests() {
|
virtual void run_tests() {
|
||||||
@ -134,6 +145,10 @@ public:
|
|||||||
test_valid[TEST_METHODRC_ARGS] = int(call("test_methodrc_args", test_num)) == test_num && test_valid[TEST_METHODRC_ARGS];
|
test_valid[TEST_METHODRC_ARGS] = int(call("test_methodrc_args", test_num)) == test_num && test_valid[TEST_METHODRC_ARGS];
|
||||||
|
|
||||||
call("test_method_default_args", 1, 2, 3, 4);
|
call("test_method_default_args", 1, 2, 3, 4);
|
||||||
|
|
||||||
|
ObjectSubclass *obj = memnew(ObjectSubclass);
|
||||||
|
call("test_method_object_cast", obj);
|
||||||
|
memdelete(obj);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -152,6 +167,7 @@ TEST_CASE("[MethodBind] check all method binds") {
|
|||||||
CHECK(mbt->test_valid[MethodBindTester::TEST_METHODRC]);
|
CHECK(mbt->test_valid[MethodBindTester::TEST_METHODRC]);
|
||||||
CHECK(mbt->test_valid[MethodBindTester::TEST_METHODRC_ARGS]);
|
CHECK(mbt->test_valid[MethodBindTester::TEST_METHODRC_ARGS]);
|
||||||
CHECK(mbt->test_valid[MethodBindTester::TEST_METHOD_DEFARGS]);
|
CHECK(mbt->test_valid[MethodBindTester::TEST_METHOD_DEFARGS]);
|
||||||
|
CHECK(mbt->test_valid[MethodBindTester::TEST_METHOD_OBJECT_CAST]);
|
||||||
|
|
||||||
memdelete(mbt);
|
memdelete(mbt);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user