diff options
| author | George Marques <george@gmarqu.es> | 2021-08-18 11:03:52 -0300 |
|---|---|---|
| committer | Bastiaan Olij <mux213@gmail.com> | 2021-09-27 23:08:08 +1000 |
| commit | e4ed48976a962b67e9585cc2d20d11f115ef7949 (patch) | |
| tree | 7830ad6926b5cd14a91784b07c2eff5b77e3f533 /include/godot_cpp/classes | |
| parent | ee708668944430a7f1d69e8faf7b3f3160432dc2 (diff) | |
| download | redot-cpp-e4ed48976a962b67e9585cc2d20d11f115ef7949.tar.gz | |
Replace bindgins to work with extensions
Diffstat (limited to 'include/godot_cpp/classes')
| -rw-r--r-- | include/godot_cpp/classes/ref.hpp | 222 | ||||
| -rw-r--r-- | include/godot_cpp/classes/wrapped.hpp | 167 |
2 files changed, 389 insertions, 0 deletions
diff --git a/include/godot_cpp/classes/ref.hpp b/include/godot_cpp/classes/ref.hpp new file mode 100644 index 0000000..2140ef3 --- /dev/null +++ b/include/godot_cpp/classes/ref.hpp @@ -0,0 +1,222 @@ +/*************************************************************************/ +/* ref.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_REF_HPP +#define GODOT_CPP_REF_HPP + +#include <godot_cpp/core/defs.hpp> + +#include <godot_cpp/classes/object.hpp> +#include <godot_cpp/classes/ref_counted.hpp> +#include <godot_cpp/core/memory.hpp> +#include <godot_cpp/variant/variant.hpp> + +namespace godot { + +// Helper class for RefCounted objects, same as Godot one. + +class RefCounted; + +template <class T> +class Ref { + T *reference = nullptr; + + void ref(const Ref &p_from) { + if (p_from.reference == reference) { + return; + } + + unref(); + + reference = p_from.reference; + if (reference) { + reference->reference(); + } + } + + void ref_pointer(T *p_ref) { + ERR_FAIL_COND(!p_ref); + + if (p_ref->init_ref()) { + reference = p_ref; + } + } + +public: + _FORCE_INLINE_ bool operator==(const T *p_ptr) const { + return reference == p_ptr; + } + _FORCE_INLINE_ bool operator!=(const T *p_ptr) const { + return reference != p_ptr; + } + + _FORCE_INLINE_ bool operator<(const Ref<T> &p_r) const { + return reference < p_r.reference; + } + _FORCE_INLINE_ bool operator==(const Ref<T> &p_r) const { + return reference == p_r.reference; + } + _FORCE_INLINE_ bool operator!=(const Ref<T> &p_r) const { + return reference != p_r.reference; + } + + _FORCE_INLINE_ T *operator->() { + return reference; + } + + _FORCE_INLINE_ T *operator*() { + return reference; + } + + _FORCE_INLINE_ const T *operator->() const { + return reference; + } + + _FORCE_INLINE_ const T *ptr() const { + return reference; + } + _FORCE_INLINE_ T *ptr() { + return reference; + } + + _FORCE_INLINE_ const T *operator*() const { + return reference; + } + + operator Variant() const { + return Variant(reference); + } + + void operator=(const Ref &p_from) { + ref(p_from); + } + + template <class T_Other> + void operator=(const Ref<T_Other> &p_from) { + RefCounted *refb = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_from.ptr())); + if (!refb) { + unref(); + return; + } + Ref r; + r.reference = Object::cast_to<T>(refb); + ref(r); + r.reference = nullptr; + } + + void operator=(const Variant &p_variant) { + // FIXME + // Object *object = p_variant.get_validated_object(); + + // if (object == reference) { + // return; + // } + + // unref(); + + // if (!object) { + // return; + // } + + // T *r = Object::cast_to<T>(object); + // if (r && r->reference()) { + // reference = r; + // } + } + + template <class T_Other> + void reference_ptr(T_Other *p_ptr) { + if (reference == p_ptr) { + return; + } + unref(); + + T *r = Object::cast_to<T>(p_ptr); + if (r) { + ref_pointer(r); + } + } + + Ref(const Ref &p_from) { + ref(p_from); + } + + Ref(T *p_reference) { + if (p_reference) { + ref_pointer(p_reference); + } + } + + Ref(const Variant &p_variant) { + // FIXME + // Object *object = p_variant.get_validated_object(); + + // if (!object) { + // return; + // } + + // T *r = Object::cast_to<T>(object); + // if (r && r->reference()) { + // reference = r; + // } + } + + inline bool is_valid() const { return reference != nullptr; } + inline bool is_null() const { return reference == nullptr; } + + void unref() { + if (reference && reference->unreference()) { + memdelete(reference); + } + reference = nullptr; + } + + void instantiate() { + ref(memnew(T)); + } + + Ref() {} + + ~Ref() { + unref(); + } + + // Used exclusively in the bindings to recreate the Ref Godot encapsulates in return values, + // without adding to the refcount. + inline static Ref<T> ___internal_constructor(Object *obj) { + Ref<T> r; + r.reference = (T *)obj; + return r; + } +}; + +} // namespace godot + +#endif // ! GODOT_CPP_REF_HPP diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp new file mode 100644 index 0000000..770224a --- /dev/null +++ b/include/godot_cpp/classes/wrapped.hpp @@ -0,0 +1,167 @@ +/*************************************************************************/ +/* wrapped.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_WRAPPED_HPP +#define GODOT_CPP_WRAPPED_HPP + +#include <godot_cpp/core/memory.hpp> + +namespace godot { +namespace internal { +struct empty_constructor {}; +} // namespace internal + +typedef void GodotObject; + +// Base for all engine classes, to contain the pointer to the engine instance. +class Wrapped { + friend class GDExtensionBinding; + + // Private constructor, this should not be created directly by users. + Wrapped(GodotObject *p_owner) : + _owner(p_owner) {} + +protected: + Wrapped() = default; + Wrapped(internal::empty_constructor empty) {} + +public: + // Must be public but you should not touch this. + GodotObject *_owner = nullptr; +}; + +} // namespace godot + +#define GDCLASS(m_class, m_inherits) \ +private: \ + friend class ClassDB; \ + \ + using SelfType = m_class; \ + \ +protected: \ + static void (*_get_bind_methods())() { \ + return &m_class::_bind_methods; \ + } \ + \ + m_class(godot::GodotObject *owner) : m_inherits(godot::internal::empty_constructor()) { \ + _owner = owner; \ + } \ + \ + m_class(godot::internal::empty_constructor empty) : m_inherits(empty) {} \ + \ +public: \ + static void initialize_class() { \ + static bool initialized = false; \ + if (initialized) { \ + return; \ + } \ + m_inherits::initialize_class(); \ + if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \ + _bind_methods(); \ + } \ + initialized = true; \ + } \ + \ + static const char *get_class_static() { \ + return #m_class; \ + } \ + \ + static const char *get_parent_class_static() { \ + return #m_inherits; \ + } \ + \ + static GDExtensionClassInstancePtr create(void *data) { \ + return (GDExtensionClassInstancePtr)godot::Memory::alloc_static(sizeof(m_class)); \ + } \ + \ + static void free(void *data, GDExtensionClassInstancePtr ptr) { \ + godot::memdelete(reinterpret_cast<m_class *>(ptr)); \ + } \ + \ + static void set_object_instance(GDExtensionClassInstancePtr p_instance, GDNativeObjectPtr p_object_instance) { \ + memnew_placement((void *)p_instance, m_class((godot::GodotObject *)p_object_instance)); \ + } \ + \ + static void *___binding_create_callback(void *p_token, void *p_instance) { \ + return memnew(m_class((godot::GodotObject *)p_instance)); \ + } \ + static void ___binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \ + memdelete((m_class *)p_binding); \ + } \ + static GDNativeBool ___binding_reference_callback(void *p_token, void *p_instance, GDNativeBool p_reference) { \ + return true; \ + } \ + static constexpr GDNativeInstanceBindingCallbacks ___binding_callbacks = { \ + ___binding_create_callback, \ + ___binding_free_callback, \ + ___binding_reference_callback, \ + }; \ + \ +private: + +// Don't use this for your classes, use GDCLASS() instead. +#define GDNATIVE_CLASS(m_class, m_inherits) \ +protected: \ + static void (*_get_bind_methods())() { \ + return nullptr; \ + } \ + m_class(godot::internal::empty_constructor empty) : m_inherits(empty) {} \ + \ +public: \ + static void initialize_class() {} \ + \ + static const char *get_class_static() { \ + return #m_class; \ + } \ + \ + static const char *get_parent_class_static() { \ + return #m_inherits; \ + } \ + \ + static void *___binding_create_callback(void *p_token, void *p_instance) { \ + m_class *obj = memnew(m_class(godot::internal::empty_constructor())); \ + obj->_owner = (godot::GodotObject *)p_instance; \ + return obj; \ + } \ + static void ___binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \ + memdelete((m_class *)p_binding); \ + } \ + static GDNativeBool ___binding_reference_callback(void *p_token, void *p_instance, GDNativeBool p_reference) { \ + return true; \ + } \ + static constexpr GDNativeInstanceBindingCallbacks ___binding_callbacks = { \ + ___binding_create_callback, \ + ___binding_free_callback, \ + ___binding_reference_callback, \ + }; \ + \ +private: + +#endif // ! GODOT_CPP_WRAPPED_HPP |
