summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdnative/gdnative.cpp3
-rw-r--r--modules/gdnative/godot/gdnative.h1
-rw-r--r--modules/gdnative/register_types.cpp3
-rw-r--r--modules/nativescript/nativescript.cpp65
-rw-r--r--modules/nativescript/nativescript.h6
-rw-r--r--modules/nativescript/register_types.cpp6
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp2
-rw-r--r--modules/visual_script/visual_script_editor.cpp10
8 files changed, 86 insertions, 10 deletions
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index e810c33f1c..158f7fd94d 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -185,6 +185,8 @@ void GDNative::_bind_methods() {
}
void GDNative::set_library(Ref<GDNativeLibrary> p_library) {
+ ERR_EXPLAIN("Tried to change library of GDNative when it is already set");
+ ERR_FAIL_COND(library.is_valid());
library = p_library;
}
@@ -229,6 +231,7 @@ bool GDNative::initialize() {
options.core_api_hash = ClassDB::get_api_hash(ClassDB::API_CORE);
options.editor_api_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR);
options.no_api_hash = ClassDB::get_api_hash(ClassDB::API_NONE);
+ options.gd_native_library = (godot_object *)(get_library().ptr());
library_init_fpointer(&options);
diff --git a/modules/gdnative/godot/gdnative.h b/modules/gdnative/godot/gdnative.h
index 510bf36cd4..b0343272ef 100644
--- a/modules/gdnative/godot/gdnative.h
+++ b/modules/gdnative/godot/gdnative.h
@@ -265,6 +265,7 @@ typedef struct {
uint64_t core_api_hash;
uint64_t editor_api_hash;
uint64_t no_api_hash;
+ godot_object *gd_native_library; // pointer to GDNativeLibrary that is being initialized
} godot_gdnative_init_options;
typedef struct {
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 20ac1ecc0c..d180d5aada 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -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;
diff --git a/modules/nativescript/nativescript.cpp b/modules/nativescript/nativescript.cpp
index f3db33cce2..e7445e6da9 100644
--- a/modules/nativescript/nativescript.cpp
+++ b/modules/nativescript/nativescript.cpp
@@ -203,7 +203,21 @@ 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
+
+ // try to call _init
+ // we don't care if it doesn't exist, so we ignore errors.
+ Variant::CallError err;
+ call("_init", NULL, 0, err);
+
return nsi;
}
@@ -274,9 +288,13 @@ ScriptLanguage *NativeScript::get_language() const {
bool NativeScript::has_script_signal(const StringName &p_signal) const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data)
- return false;
- return script_data->signals_.has(p_signal);
+
+ while (script_data) {
+ if (script_data->signals_.has(p_signal))
+ return true;
+ script_data = script_data->base_data;
+ }
+ return false;
}
void NativeScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
@@ -393,9 +411,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);
@@ -419,11 +434,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
@@ -628,6 +650,28 @@ void NativeScriptInstance::notification(int p_notification) {
call_multilevel("_notification", args, 1);
}
+void NativeScriptInstance::refcount_incremented() {
+ Variant::CallError err;
+ call("_refcount_incremented", NULL, 0, err);
+ if (err.error != Variant::CallError::CALL_OK && err.error != Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ ERR_PRINT("Failed to invoke _refcount_incremented - should not happen");
+ }
+}
+
+bool NativeScriptInstance::refcount_decremented() {
+ Variant::CallError err;
+ Variant ret = call("_refcount_decremented", NULL, 0, err);
+ if (err.error != Variant::CallError::CALL_OK && err.error != Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ ERR_PRINT("Failed to invoke _refcount_decremented - should not happen");
+ return true; // assume we can destroy the object
+ }
+ if (err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ // the method does not exist, default is true
+ return true;
+ }
+ return ret;
+}
+
Ref<Script> NativeScriptInstance::get_script() const {
return script;
}
@@ -732,7 +776,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->unlock();
+#endif
}
}
diff --git a/modules/nativescript/nativescript.h b/modules/nativescript/nativescript.h
index cf3a64e9b8..95b4954171 100644
--- a/modules/nativescript/nativescript.h
+++ b/modules/nativescript/nativescript.h
@@ -106,6 +106,9 @@ class NativeScript : public Script {
String class_name;
+#ifndef NO_THREADS
+ Mutex *owners_lock;
+#endif
Set<Object *> instance_owners;
protected:
@@ -185,6 +188,9 @@ public:
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
+ virtual void refcount_incremented();
+ virtual bool refcount_decremented();
+
~NativeScriptInstance();
};
diff --git a/modules/nativescript/register_types.cpp b/modules/nativescript/register_types.cpp
index a8a931343b..dfa16d8a2a 100644
--- a/modules/nativescript/register_types.cpp
+++ b/modules/nativescript/register_types.cpp
@@ -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;
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index c645a55703..7b8b2abebb 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -39,7 +39,7 @@ void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fra
int todo = p_frames;
- while (todo) {
+ while (todo && active) {
int mixed = stb_vorbis_get_samples_float_interleaved(ogg_stream, 2, (float *)p_buffer, todo * 2);
todo -= mixed;
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index ba3463445d..35358d5a1f 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -2328,6 +2328,16 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
undo_redo->add_do_method(script.ptr(), "sequence_connect", edited_func, p_from.to_int(), from_port, p_to.to_int());
undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", edited_func, p_from.to_int(), from_port, p_to.to_int());
} else {
+
+ // disconect current, and connect the new one
+ if (script->is_input_value_port_connected(edited_func, p_to.to_int(), to_port)) {
+ int conn_from;
+ int conn_port;
+ script->get_input_value_port_connection_source(edited_func, p_to.to_int(), to_port, &conn_from, &conn_port);
+ undo_redo->add_do_method(script.ptr(), "data_disconnect", edited_func, conn_from, conn_port, p_to.to_int(), to_port);
+ undo_redo->add_undo_method(script.ptr(), "data_connect", edited_func, conn_from, conn_port, p_to.to_int(), to_port);
+ }
+
undo_redo->add_do_method(script.ptr(), "data_connect", edited_func, p_from.to_int(), from_port, p_to.to_int(), to_port);
undo_redo->add_undo_method(script.ptr(), "data_disconnect", edited_func, p_from.to_int(), from_port, p_to.to_int(), to_port);
//update nodes in sgraph