diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/extension/gdextension_interface.cpp | 37 | ||||
-rw-r--r-- | core/extension/gdextension_interface.h | 31 | ||||
-rw-r--r-- | core/object/class_db.h | 3 | ||||
-rw-r--r-- | core/object/object.cpp | 6 | ||||
-rw-r--r-- | core/object/object.h | 3 | ||||
-rw-r--r-- | core/object/script_language.h | 3 | ||||
-rw-r--r-- | core/object/script_language_extension.cpp | 1 | ||||
-rw-r--r-- | core/object/script_language_extension.h | 10 |
8 files changed, 94 insertions, 0 deletions
diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp index b4541de8fe..a70ad5262f 100644 --- a/core/extension/gdextension_interface.cpp +++ b/core/extension/gdextension_interface.cpp @@ -1048,6 +1048,41 @@ static GDExtensionScriptInstancePtr gdextension_script_instance_create(const GDE return reinterpret_cast<GDExtensionScriptInstancePtr>(script_instance_extension); } +static GDExtensionScriptInstancePtr gdextension_placeholder_script_instance_create(GDExtensionObjectPtr p_language, GDExtensionObjectPtr p_script, GDExtensionObjectPtr p_owner) { + ScriptLanguage *language = (ScriptLanguage *)p_language; + Ref<Script> script; + script.reference_ptr((Script *)p_script); + Object *owner = (Object *)p_owner; + + PlaceHolderScriptInstance *placeholder = memnew(PlaceHolderScriptInstance(language, script, owner)); + return reinterpret_cast<GDExtensionScriptInstancePtr>(placeholder); +} + +static void gdextension_placeholder_script_instance_update(GDExtensionScriptInstancePtr p_placeholder, GDExtensionConstTypePtr p_properties, GDExtensionConstTypePtr p_values) { + PlaceHolderScriptInstance *placeholder = dynamic_cast<PlaceHolderScriptInstance *>(reinterpret_cast<ScriptInstance *>(p_placeholder)); + ERR_FAIL_COND_MSG(!placeholder, "Unable to update placeholder, expected a PlaceHolderScriptInstance but received an invalid type."); + + const Array &properties = *reinterpret_cast<const Array *>(p_properties); + const Dictionary &values = *reinterpret_cast<const Dictionary *>(p_values); + + List<PropertyInfo> properties_list; + HashMap<StringName, Variant> values_map; + + for (int i = 0; i < properties.size(); i++) { + Dictionary d = properties[i]; + properties_list.push_back(PropertyInfo::from_dict(d)); + } + + List<Variant> keys; + values.get_key_list(&keys); + + for (const Variant &E : keys) { + values_map.insert(E, values[E]); + } + + placeholder->update(properties_list, values_map); +} + static GDExtensionScriptInstancePtr gdextension_object_get_script_instance(GDExtensionConstObjectPtr p_object, GDExtensionConstObjectPtr p_language) { if (!p_object || !p_language) { return nullptr; @@ -1235,6 +1270,8 @@ void gdextension_setup_interface() { REGISTER_INTERFACE_FUNC(ref_get_object); REGISTER_INTERFACE_FUNC(ref_set_object); REGISTER_INTERFACE_FUNC(script_instance_create); + REGISTER_INTERFACE_FUNC(placeholder_script_instance_create); + REGISTER_INTERFACE_FUNC(placeholder_script_instance_update); REGISTER_INTERFACE_FUNC(object_get_script_instance); REGISTER_INTERFACE_FUNC(classdb_construct_object); REGISTER_INTERFACE_FUNC(classdb_get_method_bind); diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h index cfc21473d6..a86abf2a7e 100644 --- a/core/extension/gdextension_interface.h +++ b/core/extension/gdextension_interface.h @@ -2127,6 +2127,37 @@ typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExte typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)(const GDExtensionScriptInstanceInfo *p_info, GDExtensionScriptInstanceDataPtr p_instance_data); /** + * @name placeholder_script_instance_create + * @since 4.2 + * + * Creates a placeholder script instance for a given script and instance. + * + * This interface is optional as a custom placeholder could also be created with script_instance_create(). + * + * @param p_language A pointer to a ScriptLanguage. + * @param p_script A pointer to a Script. + * @param p_owner A pointer to an Object. + * + * @return A pointer to a PlaceHolderScriptInstance object. + */ +typedef GDExtensionScriptInstancePtr (*GDExtensionInterfacePlaceHolderScriptInstanceCreate)(GDExtensionObjectPtr p_language, GDExtensionObjectPtr p_script, GDExtensionObjectPtr p_owner); + +/** + * @name placeholder_script_instance_update + * @since 4.2 + * + * Updates a placeholder script instance with the given properties and values. + * + * The passed in placeholder must be an instance of PlaceHolderScriptInstance + * such as the one returned by placeholder_script_instance_create(). + * + * @param p_placeholder A pointer to a PlaceHolderScriptInstance. + * @param p_properties A pointer to an Array of Dictionary representing PropertyInfo. + * @param p_values A pointer to a Dictionary mapping StringName to Variant values. + */ +typedef void (*GDExtensionInterfacePlaceHolderScriptInstanceUpdate)(GDExtensionScriptInstancePtr p_placeholder, GDExtensionConstTypePtr p_properties, GDExtensionConstTypePtr p_values); + +/** * @name object_get_script_instance * @since 4.2 * diff --git a/core/object/class_db.h b/core/object/class_db.h index 3aae3b452e..57469f03d2 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -187,6 +187,7 @@ public: template <class T> static void register_class(bool p_virtual = false) { 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); @@ -201,6 +202,7 @@ public: template <class T> static void register_abstract_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); @@ -221,6 +223,7 @@ public: template <class T> static void register_custom_instance_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); diff --git a/core/object/object.cpp b/core/object/object.cpp index 4ae0ecdefd..b803d57cd9 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -526,6 +526,10 @@ 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 (script_instance) { // Call it last to allow user altering already validated properties. + script_instance->validate_property(p_property); + } } bool Object::property_can_revert(const StringName &p_name) const { @@ -1604,6 +1608,8 @@ void Object::_bind_methods() { plget.return_val.hint_string = "Dictionary"; BIND_OBJ_CORE_METHOD(plget); + 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"; diff --git a/core/object/object.h b/core/object/object.h index 318dbf98de..561e5b8fe3 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -382,6 +382,7 @@ private: friend class ::ClassDB; \ \ public: \ + typedef m_class self_type; \ static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \ virtual String get_class() const override { \ if (_get_extension()) { \ @@ -557,6 +558,8 @@ class ScriptInstance; class Object { public: + typedef Object self_type; + enum ConnectFlags { CONNECT_DEFERRED = 1, CONNECT_PERSIST = 2, // hint for scene to save this connection diff --git a/core/object/script_language.h b/core/object/script_language.h index 3ea6a6e4c3..9d83a12bbd 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -141,6 +141,7 @@ public: #ifdef TOOLS_ENABLED virtual Vector<DocData::ClassDoc> get_documentation() const = 0; + virtual String get_class_icon_path() const = 0; virtual PropertyInfo get_class_category() const; #endif // TOOLS_ENABLED @@ -179,6 +180,7 @@ public: virtual bool get(const StringName &p_name, Variant &r_ret) const = 0; virtual void get_property_list(List<PropertyInfo> *p_properties) const = 0; virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const = 0; + virtual void validate_property(PropertyInfo &p_property) const = 0; virtual bool property_can_revert(const StringName &p_name) const = 0; virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const = 0; @@ -462,6 +464,7 @@ public: virtual bool get(const StringName &p_name, Variant &r_ret) const override; virtual void get_property_list(List<PropertyInfo> *p_properties) const override; virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const override; + virtual void validate_property(PropertyInfo &p_property) const override {} virtual bool property_can_revert(const StringName &p_name) const override { return false; }; virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const override { return false; }; diff --git a/core/object/script_language_extension.cpp b/core/object/script_language_extension.cpp index 0df9d58334..bf8bac476a 100644 --- a/core/object/script_language_extension.cpp +++ b/core/object/script_language_extension.cpp @@ -52,6 +52,7 @@ void ScriptExtension::_bind_methods() { GDVIRTUAL_BIND(_reload, "keep_state"); GDVIRTUAL_BIND(_get_documentation); + GDVIRTUAL_BIND(_get_class_icon_path); GDVIRTUAL_BIND(_has_method, "method"); GDVIRTUAL_BIND(_get_method_info, "method"); diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 1a0ec29479..6edbcdaeee 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -77,6 +77,7 @@ public: EXBIND1R(Error, reload, bool) GDVIRTUAL0RC(TypedArray<Dictionary>, _get_documentation) + GDVIRTUAL0RC(String, _get_class_icon_path) #ifdef TOOLS_ENABLED virtual Vector<DocData::ClassDoc> get_documentation() const override { TypedArray<Dictionary> doc; @@ -89,6 +90,12 @@ public: return class_doc; } + + virtual String get_class_icon_path() const override { + String ret; + GDVIRTUAL_CALL(_get_class_icon_path, ret); + return ret; + } #endif // TOOLS_ENABLED EXBIND1RC(bool, has_method, const StringName &) @@ -675,6 +682,9 @@ public: } return Variant::NIL; } + virtual void validate_property(PropertyInfo &p_property) const override { + // TODO + } virtual bool property_can_revert(const StringName &p_name) const override { if (native_info->property_can_revert_func) { |