1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-10 13:00:37 +00:00

Merge pull request #10060 from endragor/nativescript-frame

Forward frame call to GDNative libraries
This commit is contained in:
Thomas Herzog
2017-08-03 13:52:44 +02:00
committed by GitHub
3 changed files with 32 additions and 44 deletions

View File

@@ -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; call_libraries_cb(_thread_enter_call_name);
{
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);
}
} }
void NativeScriptLanguage::thread_exit() { void NativeScriptLanguage::thread_exit() {
Vector<Ref<GDNative> > libs; call_libraries_cb(_thread_exit_call_name);
{
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);
}
} }
#endif // NO_THREADS #endif // NO_THREADS

View File

@@ -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();

View File

@@ -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->_noarg_call_type, noarg_call_cb);
GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_thread_cb_call_type, thread_call_cb);
#endif
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);