Merge pull request #9907 from karroffel/nativescript-init-call

NativeScript changes and OS symbol lookup optional error handling
This commit is contained in:
Thomas Herzog 2017-07-27 13:03:10 +02:00 committed by GitHub
commit 3c53b3560f
9 changed files with 70 additions and 17 deletions

View file

@ -184,9 +184,9 @@ public:
virtual void set_ime_position(const Point2 &p_pos) {}
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle) { return ERR_UNAVAILABLE; };
virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; };
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) { return ERR_UNAVAILABLE; };
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle) { return ERR_UNAVAILABLE; }
virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; }
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) { return ERR_UNAVAILABLE; }
virtual void set_keep_screen_on(bool p_enabled);
virtual bool is_keep_screen_on() const;

View file

@ -453,7 +453,7 @@ Error OS_Unix::close_dynamic_library(void *p_library_handle) {
return OK;
}
Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) {
Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
const char *error;
dlerror(); // Clear existing errors
@ -461,8 +461,12 @@ Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const S
error = dlerror();
if (error != NULL) {
ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + error);
ERR_FAIL_V(ERR_CANT_RESOLVE);
if (!p_optional) {
ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + error);
ERR_FAIL_V(ERR_CANT_RESOLVE);
} else {
return ERR_CANT_RESOLVE;
}
}
return OK;
}

View file

@ -85,7 +85,7 @@ public:
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle);
virtual Error close_dynamic_library(void *p_library_handle);
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle);
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
virtual Error set_cwd(const String &p_cwd);

View file

@ -47,7 +47,8 @@ godot_variant cb_standard_varcall(void *handle, godot_string *p_procedure, godot
Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
handle,
*(String *)p_procedure,
library_proc);
library_proc,
true); // we roll our own message
if (err != OK) {
ERR_PRINT((String("GDNative procedure \"" + *(String *)p_procedure) + "\" does not exists and can't be called").utf8().get_data());
godot_variant ret;

View file

@ -203,7 +203,15 @@ ScriptInstance *NativeScript::instance_create(Object *p_this) {
nsi->userdata = script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data);
#endif
#ifndef NO_THREADS
owners_lock->lock();
#endif
instance_owners.insert(p_this);
#ifndef NO_THREADS
owners_lock->unlock();
#endif
return nsi;
}
@ -393,9 +401,6 @@ Variant NativeScript::_new(const Variant **p_args, int p_argcount, Variant::Call
ref = REF(r);
}
// GDScript does it like this: _create_instance(p_args, p_argcount, owner, r != NULL, r_error);
// TODO(karroffel): support varargs for constructors.
NativeScriptInstance *instance = (NativeScriptInstance *)instance_create(owner);
owner->set_script_instance(instance);
@ -407,6 +412,24 @@ Variant NativeScript::_new(const Variant **p_args, int p_argcount, Variant::Call
return Variant();
}
call("_init", p_args, p_argcount, r_error);
if (r_error.error != Variant::CallError::CALL_OK) {
instance->script = Ref<NativeScript>();
instance->owner->set_script_instance(NULL);
#ifndef NO_THREADS
owners_lock->lock();
#endif
instance_owners.erase(owner);
#ifndef NO_THREADS
owners_lock->unlock();
#endif
ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, Variant());
}
if (ref.is_valid()) {
return ref;
} else {
@ -419,11 +442,18 @@ NativeScript::NativeScript() {
library = Ref<GDNative>();
lib_path = "";
class_name = "";
#ifndef NO_THREADS
owners_lock = Mutex::create();
#endif
}
// TODO(karroffel): implement this
NativeScript::~NativeScript() {
NSL->unregister_script(this);
#ifndef NO_THREADS
memdelete(owners_lock);
#endif
}
////// ScriptInstance stuff
@ -754,7 +784,16 @@ NativeScriptInstance::~NativeScriptInstance() {
script_data->destroy_func.destroy_func((godot_object *)owner, script_data->destroy_func.method_data, userdata);
if (owner) {
#ifndef NO_THREADS
script->owners_lock->lock();
#endif
script->instance_owners.erase(owner);
#ifndef NO_THREADS
script->owners_lock->lock();
#endif
}
}

View file

@ -106,6 +106,9 @@ class NativeScript : public Script {
String class_name;
#ifndef NO_THREADS
Mutex *owners_lock;
#endif
Set<Object *> instance_owners;
protected:

View file

@ -50,7 +50,8 @@ void init_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p
Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
p_handle,
*(String *)p_proc_name,
library_proc);
library_proc,
true); // we print our own message
if (err != OK) {
ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
return;
@ -75,7 +76,8 @@ void thread_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int
Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
p_handle,
*(String *)p_proc_name,
library_proc);
library_proc,
true);
if (err != OK) {
// it's fine if thread callbacks are not present in the library.
return;

View file

@ -1569,12 +1569,16 @@ Error OS_Windows::close_dynamic_library(void *p_library_handle) {
return OK;
}
Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) {
Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
char *error;
p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
if (!p_symbol_handle) {
ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + String::num(GetLastError()));
ERR_FAIL_V(ERR_CANT_RESOLVE);
if (!p_optional) {
ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + String::num(GetLastError()));
ERR_FAIL_V(ERR_CANT_RESOLVE);
} else {
return ERR_CANT_RESOLVE;
}
}
return OK;
}

View file

@ -227,7 +227,7 @@ public:
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle);
virtual Error close_dynamic_library(void *p_library_handle);
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle);
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
virtual MainLoop *get_main_loop() const;