Browse Source

Merge pull request #10060 from endragor/nativescript-frame

Forward frame call to GDNative libraries
Thomas Herzog 8 years ago
parent
commit
056b5f9e56

+ 19 - 33
modules/nativescript/nativescript.cpp

@@ -1052,9 +1052,21 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) {
 #endif
 #endif
 }
 }
 
 
-#ifndef NO_THREADS
+void NativeScriptLanguage::call_libraries_cb(const StringName &name) {
+	// library_gdnatives is modified only from the main thread, so it's safe not to use mutex here
+	for (Map<String, Ref<GDNative> >::Element *L = library_gdnatives.front(); L; L = L->next()) {
+		L->get()->call_native_raw(
+				_noarg_call_type,
+				name,
+				NULL,
+				0,
+				NULL,
+				NULL);
+	}
+}
 
 
 void NativeScriptLanguage::frame() {
 void NativeScriptLanguage::frame() {
+#ifndef NO_THREADS
 	if (has_objects_to_register) {
 	if (has_objects_to_register) {
 		MutexLock lock(mutex);
 		MutexLock lock(mutex);
 		for (Set<Ref<GDNativeLibrary> >::Element *L = libs_to_init.front(); L; L = L->next()) {
 		for (Set<Ref<GDNativeLibrary> >::Element *L = libs_to_init.front(); L; L = L->next()) {
@@ -1067,44 +1079,18 @@ void NativeScriptLanguage::frame() {
 		scripts_to_register.clear();
 		scripts_to_register.clear();
 		has_objects_to_register = false;
 		has_objects_to_register = false;
 	}
 	}
+#endif
+	call_libraries_cb(_frame_call_name);
 }
 }
 
 
+#ifndef NO_THREADS
+
 void NativeScriptLanguage::thread_enter() {
 void NativeScriptLanguage::thread_enter() {
-	Vector<Ref<GDNative> > libs;
-	{
-		MutexLock lock(mutex);
-		for (Map<String, Ref<GDNative> >::Element *L = library_gdnatives.front(); L; L = L->next()) {
-			libs.push_back(L->get());
-		}
-	}
-	for (int i = 0; i < libs.size(); ++i) {
-		libs[i]->call_native_raw(
-				_thread_cb_call_type,
-				_thread_enter_call_name,
-				NULL,
-				0,
-				NULL,
-				NULL);
-	}
+	call_libraries_cb(_thread_enter_call_name);
 }
 }
 
 
 void NativeScriptLanguage::thread_exit() {
 void NativeScriptLanguage::thread_exit() {
-	Vector<Ref<GDNative> > libs;
-	{
-		MutexLock lock(mutex);
-		for (Map<String, Ref<GDNative> >::Element *L = library_gdnatives.front(); L; L = L->next()) {
-			libs.push_back(L->get());
-		}
-	}
-	for (int i = 0; i < libs.size(); ++i) {
-		libs[i]->call_native_raw(
-				_thread_cb_call_type,
-				_thread_exit_call_name,
-				NULL,
-				0,
-				NULL,
-				NULL);
-	}
+	call_libraries_cb(_thread_exit_call_name);
 }
 }
 
 
 #endif // NO_THREADS
 #endif // NO_THREADS

+ 10 - 2
modules/nativescript/nativescript.h

@@ -220,7 +220,10 @@ private:
 	void register_script(NativeScript *script);
 	void register_script(NativeScript *script);
 	void unregister_script(NativeScript *script);
 	void unregister_script(NativeScript *script);
 
 
+	void call_libraries_cb(const StringName &name);
+
 public:
 public:
+	// These two maps must only be touched on the main thread
 	Map<String, Map<StringName, NativeScriptDesc> > library_classes;
 	Map<String, Map<StringName, NativeScriptDesc> > library_classes;
 	Map<String, Ref<GDNative> > library_gdnatives;
 	Map<String, Ref<GDNative> > library_gdnatives;
 
 
@@ -229,9 +232,14 @@ public:
 	const StringName _init_call_type = "nativescript_init";
 	const StringName _init_call_type = "nativescript_init";
 	const StringName _init_call_name = "godot_nativescript_init";
 	const StringName _init_call_name = "godot_nativescript_init";
 
 
-	const StringName _thread_cb_call_type = "godot_nativescript_thread_cb";
+	const StringName _noarg_call_type = "nativescript_no_arg";
+
+	const StringName _frame_call_name = "godot_nativescript_frame";
+
+#ifndef NO_THREADS
 	const StringName _thread_enter_call_name = "godot_nativescript_thread_enter";
 	const StringName _thread_enter_call_name = "godot_nativescript_thread_enter";
 	const StringName _thread_exit_call_name = "godot_nativescript_thread_exit";
 	const StringName _thread_exit_call_name = "godot_nativescript_thread_exit";
+#endif
 
 
 	NativeScriptLanguage();
 	NativeScriptLanguage();
 	~NativeScriptLanguage();
 	~NativeScriptLanguage();
@@ -245,9 +253,9 @@ public:
 #ifndef NO_THREADS
 #ifndef NO_THREADS
 	virtual void thread_enter();
 	virtual void thread_enter();
 	virtual void thread_exit();
 	virtual void thread_exit();
+#endif
 
 
 	virtual void frame();
 	virtual void frame();
-#endif
 
 
 	virtual String get_name() const;
 	virtual String get_name() const;
 	virtual void init();
 	virtual void init();

+ 3 - 9
modules/nativescript/register_types.cpp

@@ -62,13 +62,11 @@ void init_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p
 	fn(args[0]);
 	fn(args[0]);
 }
 }
 
 
-#ifndef NO_THREADS
-
 typedef void (*native_script_empty_callback)();
 typedef void (*native_script_empty_callback)();
 
 
-void thread_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p_num_args, void **args, void *r_ret) {
+void noarg_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p_num_args, void **args, void *r_ret) {
 	if (p_handle == NULL) {
 	if (p_handle == NULL) {
-		ERR_PRINT("No valid library handle, can't call nativescript thread enter/exit callback");
+		ERR_PRINT("No valid library handle, can't call nativescript callback");
 		return;
 		return;
 	}
 	}
 
 
@@ -87,8 +85,6 @@ void thread_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int
 	fn();
 	fn();
 }
 }
 
 
-#endif // NO_THREADS
-
 ResourceFormatLoaderNativeScript *resource_loader_gdns = NULL;
 ResourceFormatLoaderNativeScript *resource_loader_gdns = NULL;
 ResourceFormatSaverNativeScript *resource_saver_gdns = NULL;
 ResourceFormatSaverNativeScript *resource_saver_gdns = NULL;
 
 
@@ -100,9 +96,7 @@ void register_nativescript_types() {
 	ScriptServer::register_language(native_script_language);
 	ScriptServer::register_language(native_script_language);
 
 
 	GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_init_call_type, init_call_cb);
 	GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_init_call_type, init_call_cb);
-#ifndef NO_THREADS
-	GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_thread_cb_call_type, thread_call_cb);
-#endif
+	GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_noarg_call_type, noarg_call_cb);
 
 
 	resource_saver_gdns = memnew(ResourceFormatSaverNativeScript);
 	resource_saver_gdns = memnew(ResourceFormatSaverNativeScript);
 	ResourceSaver::add_resource_format_saver(resource_saver_gdns);
 	ResourceSaver::add_resource_format_saver(resource_saver_gdns);