From ac630353cf57b3a62127b9133ce12231aeac2bee Mon Sep 17 00:00:00 2001 From: Karroffel Date: Mon, 19 Jun 2017 02:03:59 +0200 Subject: [PATCH] [experimental] constructors and Ref --- binding_generator.py | 14 ++++ include/core/Ref.hpp | 163 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 include/core/Ref.hpp diff --git a/binding_generator.py b/binding_generator.py index 0fc8045b..e3d6c9bb 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -89,7 +89,12 @@ def generate_class_header(used_classes, c): for name in c["constants"]: source.append("\tconst static int " + name + " = " + str(c["constants"][name]) + ";") + + if c["instanciable"]: + source.append("\tstatic void *operator new(size_t);") + + source.append("\tstatic void operator delete(void *);") source.append("") source.append("\n\t// methods") @@ -233,7 +238,16 @@ def generate_class_implementation(icalls, used_classes, c): + if c["instanciable"]: + source.append("void *" + strip_name(c["name"]) + "::operator new(size_t)") + source.append("{") + source.append("\treturn godot_get_class_constructor(\"" + c["name"] + "\")();") + source.append("}") + source.append("void " + strip_name(c["name"]) + "::operator delete(void *ptr)") + source.append("{") + source.append("\tgodot_object_destroy((godot_object *)ptr);") + source.append("}") for method in c["methods"]: method_signature = "" diff --git a/include/core/Ref.hpp b/include/core/Ref.hpp new file mode 100644 index 00000000..192ba585 --- /dev/null +++ b/include/core/Ref.hpp @@ -0,0 +1,163 @@ +#ifndef REF_H +#define REF_H + +#if defined(_WIN32) +# ifdef _GD_CPP_CORE_API_IMPL +# define GD_CPP_CORE_API __declspec(dllexport) +# else +# define GD_CPP_CORE_API __declspec(dllimport) +# endif +#else +# define GD_CPP_CORE_API +#endif + +#include "Variant.hpp" + +namespace godot { + +template +class Ref { + T *reference; + + void ref(const Ref &from) + { + if (from.reference == reference) return; + + unref(); + + reference = from.reference; + if (reference) reference->reference(); + } + + void ref_pointer(T *r) + { + if (!r) return; + + if (r->init_ref()) reference = r; + } + + +public: + inline bool operator==(const Ref &r) const + { + return reference == r.reference; + } + + inline bool operator!=(const Ref &r) const + { + return reference != r.reference; + } + + inline T *operator->() + { + return reference; + } + + inline T *operator*() + { + return reference; + } + + inline T *ptr() + { + return reference; + } + + inline const T *operator->() const + { + return reference; + } + + inline const T *operator*() const + { + return reference; + } + + inline const T *ptr() const + { + return reference; + } + + + + void operator=(const Ref &from) + { + ref(from); + } + + void operator=(const Variant &variant) + { + T *r = variant; + if (!r) { + unref(); + return; + } + + Ref re; + re.reference = r; + ref(re); + re.reference = nullptr; + } + + operator Variant() const + { + ref(); + return Variant((Object *) this); + } + + + Ref(const Ref &from) + { + reference = nullptr; + ref(from); + } + + Ref(T *r) + { + if (r) + ref_pointer(r); + else + reference = nullptr; + } + + Ref(const Variant &variant) + { + reference = nullptr; + T *r = variant; + if (!r) { + unref(); + return; + } + + Ref re; + re.reference = r; + ref(re); + re.reference = nullptr; + } + + + inline bool is_valid() const { return reference != nullptr; } + inline bool is_null() const { return reference == nullptr; } + + void unref() + { + if (reference && reference->unreference()) { + godot_object_destroy((godot_object *) reference); + } + reference = nullptr; + } + + Ref() + { + reference = nullptr; + } + + ~Ref() + { + unref(); + } +}; + +} + +#endif