Core: Bind and document iterator API virtual methods

This commit is contained in:
Danil Alexeev 2024-03-18 18:06:03 +03:00
parent 142d33211c
commit be5068d44b
No known key found for this signature in database
GPG key ID: 124453E157DA8DC7
2 changed files with 101 additions and 20 deletions

View file

@ -1716,33 +1716,65 @@ void Object::_bind_methods() {
#define BIND_OBJ_CORE_METHOD(m_method) \
::ClassDB::add_virtual_method(get_class_static(), m_method, true, Vector<String>(), true);
MethodInfo notification_mi("_notification", PropertyInfo(Variant::INT, "what"));
notification_mi.arguments_metadata.push_back(GodotTypeInfo::Metadata::METADATA_INT_IS_INT32);
BIND_OBJ_CORE_METHOD(notification_mi);
BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value")));
#ifdef TOOLS_ENABLED
MethodInfo miget("_get", PropertyInfo(Variant::STRING_NAME, "property"));
miget.return_val.name = "Variant";
miget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_OBJ_CORE_METHOD(miget);
BIND_OBJ_CORE_METHOD(MethodInfo("_init"));
MethodInfo plget("_get_property_list");
plget.return_val.type = Variant::ARRAY;
plget.return_val.hint = PROPERTY_HINT_ARRAY_TYPE;
plget.return_val.hint_string = "Dictionary";
BIND_OBJ_CORE_METHOD(plget);
BIND_OBJ_CORE_METHOD(MethodInfo(Variant::STRING, "_to_string"));
{
MethodInfo mi("_notification");
mi.arguments.push_back(PropertyInfo(Variant::INT, "what"));
mi.arguments_metadata.push_back(GodotTypeInfo::Metadata::METADATA_INT_IS_INT32);
BIND_OBJ_CORE_METHOD(mi);
}
{
MethodInfo mi("_set");
mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "property"));
mi.arguments.push_back(PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
mi.return_val.type = Variant::BOOL;
BIND_OBJ_CORE_METHOD(mi);
}
#ifdef TOOLS_ENABLED
{
MethodInfo mi("_get");
mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "property"));
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_OBJ_CORE_METHOD(mi);
}
{
MethodInfo mi("_get_property_list");
mi.return_val.type = Variant::ARRAY;
mi.return_val.hint = PROPERTY_HINT_ARRAY_TYPE;
mi.return_val.hint_string = "Dictionary";
BIND_OBJ_CORE_METHOD(mi);
}
BIND_OBJ_CORE_METHOD(MethodInfo(Variant::NIL, "_validate_property", PropertyInfo(Variant::DICTIONARY, "property")));
BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_property_can_revert", PropertyInfo(Variant::STRING_NAME, "property")));
MethodInfo mipgr("_property_get_revert", PropertyInfo(Variant::STRING_NAME, "property"));
mipgr.return_val.name = "Variant";
mipgr.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_OBJ_CORE_METHOD(mipgr);
{
MethodInfo mi("_property_get_revert");
mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "property"));
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_OBJ_CORE_METHOD(mi);
}
// These are actually `Variant` methods, but that doesn't matter since scripts can't inherit built-in types.
BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_iter_init", PropertyInfo(Variant::ARRAY, "iter")));
BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_iter_next", PropertyInfo(Variant::ARRAY, "iter")));
{
MethodInfo mi("_iter_get");
mi.arguments.push_back(PropertyInfo(Variant::NIL, "iter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_OBJ_CORE_METHOD(mi);
}
#endif
BIND_OBJ_CORE_METHOD(MethodInfo("_init"));
BIND_OBJ_CORE_METHOD(MethodInfo(Variant::STRING, "_to_string"));
BIND_CONSTANT(NOTIFICATION_POSTINITIALIZE);
BIND_CONSTANT(NOTIFICATION_PREDELETE);

View file

@ -192,6 +192,55 @@
[b]Note:[/b] If [method _init] is defined with [i]required[/i] parameters, the Object with script may only be created directly. If any other means (such as [method PackedScene.instantiate] or [method Node.duplicate]) are used, the script's initialization will fail.
</description>
</method>
<method name="_iter_get" qualifiers="virtual">
<return type="Variant" />
<param index="0" name="iter" type="Variant" />
<description>
Returns the current iterable value. [param iter] stores the iteration state, but unlike [method _iter_init] and [method _iter_next] the state is supposed to be read-only, so there is no [Array] wrapper.
</description>
</method>
<method name="_iter_init" qualifiers="virtual">
<return type="bool" />
<param index="0" name="iter" type="Array" />
<description>
Initializes the iterator. [param iter] stores the iteration state. Since GDScript does not support passing arguments by reference, a single-element array is used as a wrapper. Returns [code]true[/code] so long as the iterator has not reached the end.
Example:
[codeblock]
class MyRange:
var _from
var _to
func _init(from, to):
assert(from &lt;= to)
_from = from
_to = to
func _iter_init(iter):
iter[0] = _from
return iter[0] &lt; _to
func _iter_next(iter):
iter[0] += 1
return iter[0] &lt; _to
func _iter_get(iter):
return iter
func _ready():
var my_range = MyRange.new(2, 5)
for x in my_range:
print(x) # Prints 2, 3, 4.
[/codeblock]
[b]Note:[/b] Alternatively, you can ignore [param iter] and use the object's state instead, see [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_advanced.html#custom-iterators]online docs[/url] for an example. Note that in this case you will not be able to reuse the same iterator instance in nested loops. Also, make sure you reset the iterator state in this method if you want to reuse the same instance multiple times.
</description>
</method>
<method name="_iter_next" qualifiers="virtual">
<return type="bool" />
<param index="0" name="iter" type="Array" />
<description>
Moves the iterator to the next iteration. [param iter] stores the iteration state. Since GDScript does not support passing arguments by reference, a single-element array is used as a wrapper. Returns [code]true[/code] so long as the iterator has not reached the end.
</description>
</method>
<method name="_notification" qualifiers="virtual">
<return type="void" />
<param index="0" name="what" type="int" />