diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/extension/gdextension.cpp | 4 | ||||
-rw-r--r-- | core/extension/gdextension_interface.h | 3 | ||||
-rw-r--r-- | core/input/input.cpp | 31 | ||||
-rw-r--r-- | core/input/input.h | 1 | ||||
-rw-r--r-- | core/object/class_db.cpp | 9 | ||||
-rw-r--r-- | core/object/class_db.h | 19 | ||||
-rw-r--r-- | core/object/object.cpp | 21 | ||||
-rw-r--r-- | core/object/object.h | 2 | ||||
-rw-r--r-- | core/object/script_language_extension.h | 4 | ||||
-rw-r--r-- | core/variant/variant_utility.cpp | 85 |
10 files changed, 172 insertions, 7 deletions
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 9674acb894..bd3f14c430 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -286,12 +286,14 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library const GDExtensionClassCreationInfo2 class_info2 = { p_extension_funcs->is_virtual, // GDExtensionBool is_virtual; p_extension_funcs->is_abstract, // GDExtensionBool is_abstract; + true, // GDExtensionBool is_exposed; p_extension_funcs->set_func, // GDExtensionClassSet set_func; p_extension_funcs->get_func, // GDExtensionClassGet get_func; p_extension_funcs->get_property_list_func, // GDExtensionClassGetPropertyList get_property_list_func; p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func; p_extension_funcs->property_can_revert_func, // GDExtensionClassPropertyCanRevert property_can_revert_func; p_extension_funcs->property_get_revert_func, // GDExtensionClassPropertyGetRevert property_get_revert_func; + nullptr, // GDExtensionClassValidateProperty validate_property_func; nullptr, // GDExtensionClassNotification2 notification_func; p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func; p_extension_funcs->reference_func, // GDExtensionClassReference reference_func; @@ -352,12 +354,14 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr extension->gdextension.editor_class = self->level_initialized == INITIALIZATION_LEVEL_EDITOR; extension->gdextension.is_virtual = p_extension_funcs->is_virtual; extension->gdextension.is_abstract = p_extension_funcs->is_abstract; + extension->gdextension.is_exposed = p_extension_funcs->is_exposed; extension->gdextension.set = p_extension_funcs->set_func; extension->gdextension.get = p_extension_funcs->get_func; extension->gdextension.get_property_list = p_extension_funcs->get_property_list_func; extension->gdextension.free_property_list = p_extension_funcs->free_property_list_func; extension->gdextension.property_can_revert = p_extension_funcs->property_can_revert_func; extension->gdextension.property_get_revert = p_extension_funcs->property_get_revert_func; + extension->gdextension.validate_property = p_extension_funcs->validate_property_func; #ifndef DISABLE_DEPRECATED if (p_deprecated_funcs) { extension->gdextension.notification = p_deprecated_funcs->notification_func; diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h index 4379e520b7..9d9ae20c51 100644 --- a/core/extension/gdextension_interface.h +++ b/core/extension/gdextension_interface.h @@ -258,6 +258,7 @@ typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExte typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list); typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name); typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret); +typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property); typedef void (*GDExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionClassNotification2 instead. typedef void (*GDExtensionClassNotification2)(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed); typedef void (*GDExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out); @@ -291,12 +292,14 @@ typedef struct { typedef struct { GDExtensionBool is_virtual; GDExtensionBool is_abstract; + GDExtensionBool is_exposed; GDExtensionClassSet set_func; GDExtensionClassGet get_func; GDExtensionClassGetPropertyList get_property_list_func; GDExtensionClassFreePropertyList free_property_list_func; GDExtensionClassPropertyCanRevert property_can_revert_func; GDExtensionClassPropertyGetRevert property_get_revert_func; + GDExtensionClassValidateProperty validate_property_func; GDExtensionClassNotification2 notification_func; GDExtensionClassToString to_string_func; GDExtensionClassReference reference_func; diff --git a/core/input/input.cpp b/core/input/input.cpp index e89c71d762..19ea8c7317 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -701,18 +701,39 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em if (!p_event->is_echo()) { if (p_event->is_action_pressed(E.key)) { - action.pressed++; + if (jm.is_valid()) { + // If axis is already pressed, don't increase the pressed counter. + if (!action.axis_pressed) { + action.pressed++; + action.axis_pressed = true; + } + } else { + action.pressed++; + } + is_pressed = true; if (action.pressed == 1) { action.pressed_physics_frame = Engine::get_singleton()->get_physics_frames(); action.pressed_process_frame = Engine::get_singleton()->get_process_frames(); } } else { - if (action.pressed == 1) { - action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); - action.released_process_frame = Engine::get_singleton()->get_process_frames(); + bool is_released = true; + if (jm.is_valid()) { + // Same as above. Don't release axis when not pressed. + if (action.axis_pressed) { + action.axis_pressed = false; + } else { + is_released = false; + } + } + + if (is_released) { + if (action.pressed == 1) { + action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.released_process_frame = Engine::get_singleton()->get_process_frames(); + } + action.pressed = MAX(action.pressed - 1, 0); } - action.pressed = MAX(action.pressed - 1, 0); } action.exact = InputMap::get_singleton()->event_is_action(p_event, E.key, true); } diff --git a/core/input/input.h b/core/input/input.h index 26466bdead..8ce5f64a6a 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -104,6 +104,7 @@ private: uint64_t released_physics_frame = UINT64_MAX; uint64_t released_process_frame = UINT64_MAX; int pressed = 0; + bool axis_pressed = false; bool exact = true; float strength = 0.0f; float raw_strength = 0.0f; diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index e9fd8ad583..9cefd3999d 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -1674,7 +1674,14 @@ void ClassDB::register_extension_class(ObjectGDExtension *p_extension) { c.inherits = parent->name; c.class_ptr = parent->class_ptr; c.inherits_ptr = parent; - c.exposed = true; + c.exposed = p_extension->is_exposed; + if (c.exposed) { + // The parent classes should be exposed if it has an exposed child class. + while (parent && !parent->exposed) { + parent->exposed = true; + parent = classes.getptr(parent->name); + } + } classes[p_extension->class_name] = c; } diff --git a/core/object/class_db.h b/core/object/class_db.h index 57469f03d2..9f86d3ab81 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -212,6 +212,21 @@ public: //nothing } + template <class T> + static void register_internal_class() { + GLOBAL_LOCK_FUNCTION; + static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS."); + T::initialize_class(); + ClassInfo *t = classes.getptr(T::get_class_static()); + ERR_FAIL_COND(!t); + t->creation_func = &creator<T>; + t->exposed = false; + t->is_virtual = false; + t->class_ptr = T::get_class_ptr_static(); + t->api = current_api; + T::register_custom_data_to_otdb(); + } + static void register_extension_class(ObjectGDExtension *p_extension); static void unregister_extension_class(const StringName &p_class); @@ -483,6 +498,10 @@ _FORCE_INLINE_ Vector<Error> errarray(P... p_args) { if (m_class::_class_is_enabled) { \ ::ClassDB::register_abstract_class<m_class>(); \ } +#define GDREGISTER_INTERNAL_CLASS(m_class) \ + if (m_class::_class_is_enabled) { \ + ::ClassDB::register_internal_class<m_class>(); \ + } #define GDREGISTER_NATIVE_STRUCT(m_class, m_code) ClassDB::register_native_struct(#m_class, m_code, sizeof(m_class)) diff --git a/core/object/object.cpp b/core/object/object.cpp index 0a0953f7dc..50026fc266 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -527,6 +527,27 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons void Object::validate_property(PropertyInfo &p_property) const { _validate_propertyv(p_property); + if (_extension && _extension->validate_property) { + // GDExtension uses a StringName rather than a String for property name. + StringName prop_name = p_property.name; + GDExtensionPropertyInfo gdext_prop = { + (GDExtensionVariantType)p_property.type, + &prop_name, + &p_property.class_name, + (uint32_t)p_property.hint, + &p_property.hint_string, + p_property.usage, + }; + if (_extension->validate_property(_extension_instance, &gdext_prop)) { + p_property.type = (Variant::Type)gdext_prop.type; + p_property.name = *reinterpret_cast<StringName *>(gdext_prop.name); + p_property.class_name = *reinterpret_cast<StringName *>(gdext_prop.class_name); + p_property.hint = (PropertyHint)gdext_prop.hint; + p_property.hint_string = *reinterpret_cast<String *>(gdext_prop.hint_string); + p_property.usage = gdext_prop.usage; + }; + } + if (script_instance) { // Call it last to allow user altering already validated properties. script_instance->validate_property(p_property); } diff --git a/core/object/object.h b/core/object/object.h index 309cd34c4b..3a698f7526 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -315,12 +315,14 @@ struct ObjectGDExtension { bool editor_class = false; bool is_virtual = false; bool is_abstract = false; + bool is_exposed = true; GDExtensionClassSet set; GDExtensionClassGet get; GDExtensionClassGetPropertyList get_property_list; GDExtensionClassFreePropertyList free_property_list; GDExtensionClassPropertyCanRevert property_can_revert; GDExtensionClassPropertyGetRevert property_get_revert; + GDExtensionClassValidateProperty validate_property; #ifndef DISABLE_DEPRECATED GDExtensionClassNotification notification; #endif // DISABLE_DEPRECATED diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index c7218d99a6..e06f005320 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -689,9 +689,11 @@ public: } virtual void validate_property(PropertyInfo &p_property) const override { if (native_info->validate_property_func) { + // GDExtension uses a StringName rather than a String for property name. + StringName prop_name = p_property.name; GDExtensionPropertyInfo gdext_prop = { (GDExtensionVariantType)p_property.type, - &p_property.name, + &prop_name, &p_property.class_name, (uint32_t)p_property.hint, &p_property.hint_string, diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index b51df89bec..51ea17e2d2 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -752,6 +752,90 @@ int64_t VariantUtilityFunctions::_typeof(const Variant &obj) { return obj.get_type(); } +Variant VariantUtilityFunctions::type_convert(const Variant &p_variant, const Variant::Type p_type) { + switch (p_type) { + case Variant::Type::NIL: + return Variant(); + case Variant::Type::BOOL: + return p_variant.operator bool(); + case Variant::Type::INT: + return p_variant.operator int64_t(); + case Variant::Type::FLOAT: + return p_variant.operator double(); + case Variant::Type::STRING: + return p_variant.operator String(); + case Variant::Type::VECTOR2: + return p_variant.operator Vector2(); + case Variant::Type::VECTOR2I: + return p_variant.operator Vector2i(); + case Variant::Type::RECT2: + return p_variant.operator Rect2(); + case Variant::Type::RECT2I: + return p_variant.operator Rect2i(); + case Variant::Type::VECTOR3: + return p_variant.operator Vector3(); + case Variant::Type::VECTOR3I: + return p_variant.operator Vector3i(); + case Variant::Type::TRANSFORM2D: + return p_variant.operator Transform2D(); + case Variant::Type::VECTOR4: + return p_variant.operator Vector4(); + case Variant::Type::VECTOR4I: + return p_variant.operator Vector4i(); + case Variant::Type::PLANE: + return p_variant.operator Plane(); + case Variant::Type::QUATERNION: + return p_variant.operator Quaternion(); + case Variant::Type::AABB: + return p_variant.operator ::AABB(); + case Variant::Type::BASIS: + return p_variant.operator Basis(); + case Variant::Type::TRANSFORM3D: + return p_variant.operator Transform3D(); + case Variant::Type::PROJECTION: + return p_variant.operator Projection(); + case Variant::Type::COLOR: + return p_variant.operator Color(); + case Variant::Type::STRING_NAME: + return p_variant.operator StringName(); + case Variant::Type::NODE_PATH: + return p_variant.operator NodePath(); + case Variant::Type::RID: + return p_variant.operator ::RID(); + case Variant::Type::OBJECT: + return p_variant.operator Object *(); + case Variant::Type::CALLABLE: + return p_variant.operator Callable(); + case Variant::Type::SIGNAL: + return p_variant.operator Signal(); + case Variant::Type::DICTIONARY: + return p_variant.operator Dictionary(); + case Variant::Type::ARRAY: + return p_variant.operator Array(); + case Variant::Type::PACKED_BYTE_ARRAY: + return p_variant.operator PackedByteArray(); + case Variant::Type::PACKED_INT32_ARRAY: + return p_variant.operator PackedInt32Array(); + case Variant::Type::PACKED_INT64_ARRAY: + return p_variant.operator PackedInt64Array(); + case Variant::Type::PACKED_FLOAT32_ARRAY: + return p_variant.operator PackedFloat32Array(); + case Variant::Type::PACKED_FLOAT64_ARRAY: + return p_variant.operator PackedFloat64Array(); + case Variant::Type::PACKED_STRING_ARRAY: + return p_variant.operator PackedStringArray(); + case Variant::Type::PACKED_VECTOR2_ARRAY: + return p_variant.operator PackedVector2Array(); + case Variant::Type::PACKED_VECTOR3_ARRAY: + return p_variant.operator PackedVector3Array(); + case Variant::Type::PACKED_COLOR_ARRAY: + return p_variant.operator PackedColorArray(); + case Variant::Type::VARIANT_MAX: + ERR_PRINT("Invalid type argument to type_convert(), use the TYPE_* constants. Returning the unconverted Variant."); + } + return p_variant; +} + String VariantUtilityFunctions::str(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { if (p_arg_count < 1) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; @@ -1615,6 +1699,7 @@ void Variant::_register_variant_utility_functions() { FUNCBINDVR(weakref, sarray("obj"), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDR(_typeof, sarray("variable"), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDR(type_convert, sarray("variant", "type"), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDVARARGS(str, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDR(error_string, sarray("error"), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDVARARGV(print, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |