summaryrefslogtreecommitdiffstats
path: root/modules/mono/glue/runtime_interop.cpp
diff options
context:
space:
mode:
authorIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2021-09-12 19:50:13 +0200
committerIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2022-08-22 03:35:59 +0200
commit5e37d073bb86492e8c415964ffd554a2fa08920d (patch)
tree1023544131f8117ac5b61d12bdc6b6f790513429 /modules/mono/glue/runtime_interop.cpp
parent9a51430441eecafbd07a7b9eb46967e2c3dd8b5d (diff)
downloadredot-engine-5e37d073bb86492e8c415964ffd554a2fa08920d.tar.gz
C#: Re-write GD and some other icalls as P/Invoke
Diffstat (limited to 'modules/mono/glue/runtime_interop.cpp')
-rw-r--r--modules/mono/glue/runtime_interop.cpp214
1 files changed, 212 insertions, 2 deletions
diff --git a/modules/mono/glue/runtime_interop.cpp b/modules/mono/glue/runtime_interop.cpp
index f5a04bf05c..2860386127 100644
--- a/modules/mono/glue/runtime_interop.cpp
+++ b/modules/mono/glue/runtime_interop.cpp
@@ -29,8 +29,10 @@
/*************************************************************************/
#include "core/config/engine.h"
+#include "core/io/marshalls.h"
#include "core/object/class_db.h"
#include "core/object/method_bind.h"
+#include "core/os/os.h"
#include "core/string/string_name.h"
#include "../interop_types.h"
@@ -839,12 +841,194 @@ GD_PINVOKE_EXPORT bool godotsharp_node_path_is_absolute(const NodePath *p_self)
return p_self->is_absolute();
}
+GD_PINVOKE_EXPORT void godotsharp_randomize() {
+ Math::randomize();
+}
+
+GD_PINVOKE_EXPORT uint32_t godotsharp_randi() {
+ return Math::rand();
+}
+
+GD_PINVOKE_EXPORT float godotsharp_randf() {
+ return Math::randf();
+}
+
+GD_PINVOKE_EXPORT int32_t godotsharp_randi_range(int32_t p_from, int32_t p_to) {
+ return Math::random(p_from, p_to);
+}
+
+GD_PINVOKE_EXPORT double godotsharp_randf_range(double p_from, double p_to) {
+ return Math::random(p_from, p_to);
+}
+
+GD_PINVOKE_EXPORT double godotsharp_randfn(double p_mean, double p_deviation) {
+ return Math::randfn(p_mean, p_deviation);
+}
+
+GD_PINVOKE_EXPORT void godotsharp_seed(uint64_t p_seed) {
+ Math::seed(p_seed);
+}
+
+GD_PINVOKE_EXPORT uint32_t godotsharp_rand_from_seed(uint64_t p_seed, uint64_t *r_new_seed) {
+ uint32_t ret = Math::rand_from_seed(&p_seed);
+ *r_new_seed = p_seed;
+ return ret;
+}
+
+GD_PINVOKE_EXPORT void godotsharp_weakref(Object *p_ptr, Ref<RefCounted> *r_weak_ref) {
+ if (!p_ptr) {
+ return;
+ }
+
+ Ref<WeakRef> wref;
+ RefCounted *rc = Object::cast_to<RefCounted>(p_ptr);
+
+ if (rc) {
+ Ref<RefCounted> r = rc;
+ if (!r.is_valid()) {
+ return;
+ }
+
+ wref.instantiate();
+ wref->set_ref(r);
+ } else {
+ wref.instantiate();
+ wref->set_obj(p_ptr);
+ }
+
+ memnew_placement(r_weak_ref, Ref<RefCounted>(wref));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_str(const godot_array *p_what, godot_string *r_ret) {
+ String &str = *memnew_placement(r_ret, String);
+ const Array &what = *reinterpret_cast<const Array *>(p_what);
+
+ for (int i = 0; i < what.size(); i++) {
+ String os = what[i].operator String();
+
+ if (i == 0) {
+ str = os;
+ } else {
+ str += os;
+ }
+ }
+}
+
+GD_PINVOKE_EXPORT void godotsharp_print(const godot_string *p_what) {
+ print_line(*reinterpret_cast<const String *>(p_what));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_print_rich(const godot_string *p_what) {
+ print_line_rich(*reinterpret_cast<const String *>(p_what));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_printerr(const godot_string *p_what) {
+ print_error(*reinterpret_cast<const String *>(p_what));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_printt(const godot_string *p_what) {
+ print_line(*reinterpret_cast<const String *>(p_what));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_prints(const godot_string *p_what) {
+ print_line(*reinterpret_cast<const String *>(p_what));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_printraw(const godot_string *p_what) {
+ OS::get_singleton()->print("%s", reinterpret_cast<const String *>(p_what)->utf8().get_data());
+}
+
+GD_PINVOKE_EXPORT void godotsharp_pusherror(const godot_string *p_str) {
+ ERR_PRINT(*reinterpret_cast<const String *>(p_str));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_pushwarning(const godot_string *p_str) {
+ WARN_PRINT(*reinterpret_cast<const String *>(p_str));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_var2str(const godot_variant *p_var, godot_string *r_ret) {
+ const Variant &var = *reinterpret_cast<const Variant *>(p_var);
+ String &vars = *memnew_placement(r_ret, String);
+ VariantWriter::write_to_string(var, vars);
+}
+
+GD_PINVOKE_EXPORT void godotsharp_str2var(const godot_string *p_str, godot_variant *r_ret) {
+ Variant ret;
+
+ VariantParser::StreamString ss;
+ ss.s = *reinterpret_cast<const String *>(p_str);
+
+ String errs;
+ int line;
+ Error err = VariantParser::parse(&ss, ret, errs, line);
+ if (err != OK) {
+ String err_str = "Parse error at line " + itos(line) + ": " + errs + ".";
+ ERR_PRINT(err_str);
+ ret = err_str;
+ }
+ memnew_placement(r_ret, Variant(ret));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_var2bytes(const godot_variant *p_var, bool p_full_objects, godot_packed_array *r_bytes) {
+ const Variant &var = *reinterpret_cast<const Variant *>(p_var);
+ PackedByteArray &bytes = *memnew_placement(r_bytes, PackedByteArray);
+
+ int len;
+ Error err = encode_variant(var, nullptr, len, p_full_objects);
+ ERR_FAIL_COND_MSG(err != OK, "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
+
+ bytes.resize(len);
+ encode_variant(var, bytes.ptrw(), len, p_full_objects);
+}
+
+GD_PINVOKE_EXPORT void godotsharp_bytes2var(const godot_packed_array *p_bytes, bool p_allow_objects, godot_variant *r_ret) {
+ const PackedByteArray *bytes = reinterpret_cast<const PackedByteArray *>(p_bytes);
+ Variant ret;
+ Error err = decode_variant(ret, bytes->ptr(), bytes->size(), nullptr, p_allow_objects);
+ if (err != OK) {
+ ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
+ }
+ memnew_placement(r_ret, Variant(ret));
+}
+
+GD_PINVOKE_EXPORT int godotsharp_hash(const godot_variant *p_var) {
+ return reinterpret_cast<const Variant *>(p_var)->hash();
+}
+
+GD_PINVOKE_EXPORT void godotsharp_convert(const godot_variant *p_what, int32_t p_type, godot_variant *r_ret) {
+ const Variant *args[1] = { reinterpret_cast<const Variant *>(p_what) };
+ Callable::CallError ce;
+ Variant ret;
+ Variant::construct(Variant::Type(p_type), ret, args, 1, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ memnew_placement(r_ret, Variant);
+ ERR_FAIL_MSG("Unable to convert parameter from '" +
+ Variant::get_type_name(reinterpret_cast<const Variant *>(p_what)->get_type()) +
+ "' to '" + Variant::get_type_name(Variant::Type(p_type)) + "'.");
+ }
+ memnew_placement(r_ret, Variant(ret));
+}
+
+GD_PINVOKE_EXPORT Object *godotsharp_instance_from_id(uint64_t p_instance_id) {
+ return ObjectDB::get_instance(ObjectID(p_instance_id));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_object_to_string(Object *p_ptr, godot_string *r_str) {
+#ifdef DEBUG_ENABLED
+ // Cannot happen in C#; would get an ObjectDisposedException instead.
+ CRASH_COND(p_ptr == nullptr);
+#endif
+ // Can't call 'Object::to_string()' here, as that can end up calling 'ToString' again resulting in an endless circular loop.
+ memnew_placement(r_str,
+ String("[" + p_ptr->get_class() + ":" + itos(p_ptr->get_instance_id()) + "]"));
+}
+
#ifdef __cplusplus
}
#endif
// We need this to prevent the functions from being stripped.
-void *godotsharp_pinvoke_funcs[138] = {
+void *godotsharp_pinvoke_funcs[164] = {
(void *)godotsharp_method_bind_get_method,
(void *)godotsharp_get_class_constructor,
(void *)godotsharp_invoke_class_constructor,
@@ -982,5 +1166,31 @@ void *godotsharp_pinvoke_funcs[138] = {
(void *)godotsharp_node_path_get_name_count,
(void *)godotsharp_node_path_get_subname,
(void *)godotsharp_node_path_get_subname_count,
- (void *)godotsharp_node_path_is_absolute
+ (void *)godotsharp_node_path_is_absolute,
+ (void *)godotsharp_randomize,
+ (void *)godotsharp_randi,
+ (void *)godotsharp_randf,
+ (void *)godotsharp_randi_range,
+ (void *)godotsharp_randf_range,
+ (void *)godotsharp_randfn,
+ (void *)godotsharp_seed,
+ (void *)godotsharp_rand_from_seed,
+ (void *)godotsharp_weakref,
+ (void *)godotsharp_str,
+ (void *)godotsharp_print,
+ (void *)godotsharp_print_rich,
+ (void *)godotsharp_printerr,
+ (void *)godotsharp_printt,
+ (void *)godotsharp_prints,
+ (void *)godotsharp_printraw,
+ (void *)godotsharp_pusherror,
+ (void *)godotsharp_pushwarning,
+ (void *)godotsharp_var2str,
+ (void *)godotsharp_str2var,
+ (void *)godotsharp_var2bytes,
+ (void *)godotsharp_bytes2var,
+ (void *)godotsharp_hash,
+ (void *)godotsharp_convert,
+ (void *)godotsharp_instance_from_id,
+ (void *)godotsharp_object_to_string,
};