You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-24 15:26:15 +00:00
C#: Add DynamicGodotObject class
Expands to Object.call, Object.set and Object.get for accessing members. This means it can also access members from scripts written in other languages, like GDScript.
(cherry picked from commit bb6814aef0)
This commit is contained in:
committed by
Hein-Pieter van Braam-Stewart
parent
7851d828a2
commit
4c10a322d1
@@ -36,9 +36,11 @@
|
||||
#include "core/string_name.h"
|
||||
|
||||
#include "../csharp_script.h"
|
||||
#include "../mono_gd/gd_mono_class.h"
|
||||
#include "../mono_gd/gd_mono_internals.h"
|
||||
#include "../mono_gd/gd_mono_utils.h"
|
||||
#include "../signal_awaiter_utils.h"
|
||||
#include "arguments_vector.h"
|
||||
|
||||
Object *godot_icall_Object_Ctor(MonoObject *p_obj) {
|
||||
Object *instance = memnew(Object);
|
||||
@@ -75,7 +77,7 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
|
||||
}
|
||||
}
|
||||
|
||||
void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, bool p_is_finalizer) {
|
||||
void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
CRASH_COND(p_ptr == NULL);
|
||||
// This is only called with Reference derived classes
|
||||
@@ -155,6 +157,67 @@ Error godot_icall_SignalAwaiter_connect(Object *p_source, MonoString *p_signal,
|
||||
return SignalAwaiterUtils::connect_signal_awaiter(p_source, signal, p_target, p_awaiter);
|
||||
}
|
||||
|
||||
MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) {
|
||||
List<PropertyInfo> property_list;
|
||||
p_ptr->get_property_list(&property_list);
|
||||
|
||||
MonoArray *result = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), property_list.size());
|
||||
|
||||
int i = 0;
|
||||
for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
|
||||
MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get().name);
|
||||
mono_array_set(result, MonoString *, i, boxed);
|
||||
i++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MonoBoolean godot_icall_DynamicGodotObject_InvokeMember(Object *p_ptr, MonoString *p_name, MonoArray *p_args, MonoObject **r_result) {
|
||||
String name = GDMonoMarshal::mono_string_to_godot(p_name);
|
||||
|
||||
int argc = mono_array_length(p_args);
|
||||
|
||||
ArgumentsVector<Variant> arg_store(argc);
|
||||
ArgumentsVector<const Variant *> args(argc);
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
MonoObject *elem = mono_array_get(p_args, MonoObject *, i);
|
||||
arg_store.set(i, GDMonoMarshal::mono_object_to_variant(elem));
|
||||
args.set(i, &arg_store.get(i));
|
||||
}
|
||||
|
||||
Variant::CallError error;
|
||||
Variant result = p_ptr->call(StringName(name), args.ptr(), argc, error);
|
||||
|
||||
*r_result = GDMonoMarshal::variant_to_mono_object(result);
|
||||
|
||||
return error.error == OK;
|
||||
}
|
||||
|
||||
MonoBoolean godot_icall_DynamicGodotObject_GetMember(Object *p_ptr, MonoString *p_name, MonoObject **r_result) {
|
||||
String name = GDMonoMarshal::mono_string_to_godot(p_name);
|
||||
|
||||
bool valid;
|
||||
Variant value = p_ptr->get(StringName(name), &valid);
|
||||
|
||||
if (valid) {
|
||||
*r_result = GDMonoMarshal::variant_to_mono_object(value);
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
MonoBoolean godot_icall_DynamicGodotObject_SetMember(Object *p_ptr, MonoString *p_name, MonoObject *p_value) {
|
||||
String name = GDMonoMarshal::mono_string_to_godot(p_name);
|
||||
Variant value = GDMonoMarshal::mono_object_to_variant(p_value);
|
||||
|
||||
bool valid;
|
||||
p_ptr->set(StringName(name), value, &valid);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
void godot_register_object_icalls() {
|
||||
mono_add_internal_call("Godot.Object::godot_icall_Object_Ctor", (void *)godot_icall_Object_Ctor);
|
||||
mono_add_internal_call("Godot.Object::godot_icall_Object_Disposed", (void *)godot_icall_Object_Disposed);
|
||||
@@ -162,6 +225,10 @@ void godot_register_object_icalls() {
|
||||
mono_add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", (void *)godot_icall_Object_ClassDB_get_method);
|
||||
mono_add_internal_call("Godot.Object::godot_icall_Object_weakref", (void *)godot_icall_Object_weakref);
|
||||
mono_add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", (void *)godot_icall_SignalAwaiter_connect);
|
||||
mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMemberList", (void *)godot_icall_DynamicGodotObject_SetMemberList);
|
||||
mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_InvokeMember", (void *)godot_icall_DynamicGodotObject_InvokeMember);
|
||||
mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_GetMember", (void *)godot_icall_DynamicGodotObject_GetMember);
|
||||
mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMember", (void *)godot_icall_DynamicGodotObject_SetMember);
|
||||
}
|
||||
|
||||
#endif // MONO_GLUE_ENABLED
|
||||
|
||||
Reference in New Issue
Block a user