Преглед изворни кода

Added a simpler/faster way to bind script languages instance wrappers to Godot

Juan Linietsky пре 8 година
родитељ
комит
4366b7c8b0
4 измењених фајлова са 37 додато и 6 уклоњено
  1. 24 0
      core/object.cpp
  2. 9 0
      core/object.h
  3. 0 5
      core/script_language.cpp
  4. 4 1
      core/script_language.h

+ 24 - 0
core/object.cpp

@@ -1817,6 +1817,23 @@ uint32_t Object::get_edited_version() const {
 }
 }
 #endif
 #endif
 
 
+void *Object::get_script_instance_binding(int p_script_language_index) {
+#ifdef DEBUG_ENABLED
+	ERR_FAIL_INDEX_V(p_script_language_index, MAX_SCRIPT_INSTANCE_BINDINGS, NULL);
+#endif
+
+	//it's up to the script language to make this thread safe, if the function is called twice due to threads being out of syncro
+	//just return the same pointer.
+	//if you want to put a big lock in the entire function and keep allocated pointers in a map or something, feel free to do it
+	//as it should not really affect performance much (won't be called too often), as in far most caes the condition below will be false afterwards
+
+	if (!_script_instance_bindings[p_script_language_index]) {
+		_script_instance_bindings[p_script_language_index] = ScriptServer::get_language(p_script_language_index)->alloc_instance_binding_data(this);
+	}
+
+	return _script_instance_bindings[p_script_language_index];
+}
+
 Object::Object() {
 Object::Object() {
 
 
 	_class_ptr = NULL;
 	_class_ptr = NULL;
@@ -1826,6 +1843,7 @@ Object::Object() {
 	_instance_ID = ObjectDB::add_instance(this);
 	_instance_ID = ObjectDB::add_instance(this);
 	_can_translate = true;
 	_can_translate = true;
 	_is_queued_for_deletion = false;
 	_is_queued_for_deletion = false;
+	memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS);
 	script_instance = NULL;
 	script_instance = NULL;
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 
 
@@ -1877,6 +1895,12 @@ Object::~Object() {
 	ObjectDB::remove_instance(this);
 	ObjectDB::remove_instance(this);
 	_instance_ID = 0;
 	_instance_ID = 0;
 	_predelete_ok = 2;
 	_predelete_ok = 2;
+
+	for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
+		if (_script_instance_bindings[i]) {
+			ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]);
+		}
+	}
 }
 }
 
 
 bool predelete_handler(Object *p_object) {
 bool predelete_handler(Object *p_object) {

+ 9 - 0
core/object.h

@@ -381,6 +381,10 @@ public:
 	};
 	};
 
 
 private:
 private:
+	enum {
+		MAX_SCRIPT_INSTANCE_BINDINGS = 8
+	};
+
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
 	friend class _ObjectDebugLock;
 	friend class _ObjectDebugLock;
 #endif
 #endif
@@ -447,6 +451,8 @@ private:
 	void _set_bind(const String &p_set, const Variant &p_value);
 	void _set_bind(const String &p_set, const Variant &p_value);
 	Variant _get_bind(const String &p_name) const;
 	Variant _get_bind(const String &p_name) const;
 
 
+	void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS];
+
 	void property_list_changed_notify();
 	void property_list_changed_notify();
 
 
 protected:
 protected:
@@ -683,6 +689,9 @@ public:
 	bool editor_is_section_unfolded(const String &p_section);
 	bool editor_is_section_unfolded(const String &p_section);
 #endif
 #endif
 
 
+	//used by script languages to store binding data
+	void *get_script_instance_binding(int p_script_language_index);
+
 	void clear_internal_resource_paths();
 	void clear_internal_resource_paths();
 
 
 	Object();
 	Object();

+ 0 - 5
core/script_language.cpp

@@ -66,11 +66,6 @@ bool ScriptServer::is_scripting_enabled() {
 	return scripting_enabled;
 	return scripting_enabled;
 }
 }
 
 
-int ScriptServer::get_language_count() {
-
-	return _language_count;
-}
-
 ScriptLanguage *ScriptServer::get_language(int p_idx) {
 ScriptLanguage *ScriptServer::get_language(int p_idx) {
 
 
 	ERR_FAIL_INDEX_V(p_idx, _language_count, NULL);
 	ERR_FAIL_INDEX_V(p_idx, _language_count, NULL);

+ 4 - 1
core/script_language.h

@@ -57,7 +57,7 @@ public:
 
 
 	static void set_scripting_enabled(bool p_enabled);
 	static void set_scripting_enabled(bool p_enabled);
 	static bool is_scripting_enabled();
 	static bool is_scripting_enabled();
-	static int get_language_count();
+	_FORCE_INLINE_ static int get_language_count() { return _language_count; }
 	static ScriptLanguage *get_language(int p_idx);
 	static ScriptLanguage *get_language(int p_idx);
 	static void register_language(ScriptLanguage *p_language);
 	static void register_language(ScriptLanguage *p_language);
 	static void unregister_language(ScriptLanguage *p_language);
 	static void unregister_language(ScriptLanguage *p_language);
@@ -274,6 +274,9 @@ public:
 	virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) = 0;
 	virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) = 0;
 	virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) = 0;
 	virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) = 0;
 
 
+	virtual void *alloc_instance_binding_data(Object *p_object) { return NULL; } //optional, not used by all languages
+	virtual void free_instance_binding_data(void *p_data) {} //optional, not used by all languages
+
 	virtual void frame();
 	virtual void frame();
 
 
 	virtual ~ScriptLanguage(){};
 	virtual ~ScriptLanguage(){};