diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | include/godot_cpp/classes/wrapped.hpp | 198 | ||||
-rw-r--r-- | include/godot_cpp/core/memory.hpp | 23 | ||||
-rw-r--r-- | src/core/memory.cpp | 11 | ||||
-rw-r--r-- | test/SConstruct | 11 | ||||
-rwxr-xr-x | test/generate_xcframework.sh | 7 | ||||
-rw-r--r-- | test/project/bin/libgdexample.macos.template_debug.framework/Resources/Info.plist (renamed from test/project/bin/libgdexample.osx.template_debug.framework/Resources/Info.plist) | 0 | ||||
-rw-r--r-- | test/project/bin/libgdexample.macos.template_release.framework/Resources/Info.plist (renamed from test/project/bin/libgdexample.osx.template_release.framework/Resources/Info.plist) | 0 | ||||
-rw-r--r-- | test/project/example.gdextension | 16 | ||||
-rw-r--r-- | test/project/project.godot | 1 | ||||
-rw-r--r-- | tools/godotcpp.py | 22 |
11 files changed, 170 insertions, 123 deletions
@@ -191,3 +191,7 @@ godot.creator.* # compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html) compile_commands.json + +# Python development +.venv +venv diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp index af2ce4c..f8f921b 100644 --- a/include/godot_cpp/classes/wrapped.hpp +++ b/include/godot_cpp/classes/wrapped.hpp @@ -365,105 +365,109 @@ public: _gde_binding_create_callback, \ _gde_binding_free_callback, \ _gde_binding_reference_callback, \ - }; + }; \ + \ +private: // Don't use this for your classes, use GDCLASS() instead. -#define GDEXTENSION_CLASS_ALIAS(m_class, m_alias_for, m_inherits) \ -private: \ - inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \ - void operator=(const m_class &p_rval) {} \ - \ -protected: \ - virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \ - return &_gde_binding_callbacks; \ - } \ - \ - m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \ - m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \ - \ - static void (*_get_bind_methods())() { \ - return nullptr; \ - } \ - \ - static void (Wrapped::*_get_notification())(int) { \ - return nullptr; \ - } \ - \ - static bool (Wrapped::*_get_set())(const ::godot::StringName &p_name, const Variant &p_property) { \ - return nullptr; \ - } \ - \ - static bool (Wrapped::*_get_get())(const ::godot::StringName &p_name, Variant &r_ret) const { \ - return nullptr; \ - } \ - \ - static inline bool has_get_property_list() { \ - return false; \ - } \ - \ - static void (Wrapped::*_get_get_property_list())(List<PropertyInfo> * p_list) const { \ - return nullptr; \ - } \ - \ - static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \ - return nullptr; \ - } \ - \ - static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) const { \ - return nullptr; \ - } \ - \ - static void (Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \ - return nullptr; \ - } \ - \ - static String (Wrapped::*_get_to_string())() const { \ - return nullptr; \ - } \ - \ -public: \ - typedef m_class self_type; \ - \ - static void initialize_class() {} \ - \ - static ::godot::StringName &get_class_static() { \ - static ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \ - return string_name; \ - } \ - \ - static ::godot::StringName &get_parent_class_static() { \ - return m_inherits::get_class_static(); \ - } \ - \ - static GDExtensionObjectPtr create(void *data) { \ - return nullptr; \ - } \ - \ - static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) { \ - return nullptr; \ - } \ - \ - static void free(void *data, GDExtensionClassInstancePtr ptr) { \ - } \ - \ - static void *_gde_binding_create_callback(void *p_token, void *p_instance) { \ - /* Do not call memnew here, we don't want the post-initializer to be called */ \ - return new ("") m_class((GodotObject *)p_instance); \ - } \ - static void _gde_binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \ - /* Explicitly call the deconstructor to ensure proper lifecycle for non-trivial members */ \ - reinterpret_cast<m_class *>(p_binding)->~m_class(); \ - Memory::free_static(reinterpret_cast<m_class *>(p_binding)); \ - } \ - static GDExtensionBool _gde_binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \ - return true; \ - } \ - static constexpr GDExtensionInstanceBindingCallbacks _gde_binding_callbacks = { \ - _gde_binding_create_callback, \ - _gde_binding_free_callback, \ - _gde_binding_reference_callback, \ - }; \ - m_class() : m_class(#m_alias_for) {} +#define GDEXTENSION_CLASS_ALIAS(m_class, m_alias_for, m_inherits) /******************************************************************************************************************/ \ +private: \ + inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \ + void operator=(const m_class &p_rval) {} \ + \ +protected: \ + virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \ + return &_gde_binding_callbacks; \ + } \ + \ + m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \ + m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \ + \ + static void (*_get_bind_methods())() { \ + return nullptr; \ + } \ + \ + static void (Wrapped::*_get_notification())(int) { \ + return nullptr; \ + } \ + \ + static bool (Wrapped::*_get_set())(const ::godot::StringName &p_name, const Variant &p_property) { \ + return nullptr; \ + } \ + \ + static bool (Wrapped::*_get_get())(const ::godot::StringName &p_name, Variant &r_ret) const { \ + return nullptr; \ + } \ + \ + static inline bool has_get_property_list() { \ + return false; \ + } \ + \ + static void (Wrapped::*_get_get_property_list())(List<PropertyInfo> * p_list) const { \ + return nullptr; \ + } \ + \ + static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \ + return nullptr; \ + } \ + \ + static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) const { \ + return nullptr; \ + } \ + \ + static void (Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \ + return nullptr; \ + } \ + \ + static String (Wrapped::*_get_to_string())() const { \ + return nullptr; \ + } \ + \ +public: \ + typedef m_class self_type; \ + \ + static void initialize_class() {} \ + \ + static ::godot::StringName &get_class_static() { \ + static ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \ + return string_name; \ + } \ + \ + static ::godot::StringName &get_parent_class_static() { \ + return m_inherits::get_class_static(); \ + } \ + \ + static GDExtensionObjectPtr create(void *data) { \ + return nullptr; \ + } \ + \ + static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) { \ + return nullptr; \ + } \ + \ + static void free(void *data, GDExtensionClassInstancePtr ptr) { \ + } \ + \ + static void *_gde_binding_create_callback(void *p_token, void *p_instance) { \ + /* Do not call memnew here, we don't want the post-initializer to be called */ \ + return new ("", "") m_class((GodotObject *)p_instance); \ + } \ + static void _gde_binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \ + /* Explicitly call the deconstructor to ensure proper lifecycle for non-trivial members */ \ + reinterpret_cast<m_class *>(p_binding)->~m_class(); \ + Memory::free_static(reinterpret_cast<m_class *>(p_binding)); \ + } \ + static GDExtensionBool _gde_binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \ + return true; \ + } \ + static constexpr GDExtensionInstanceBindingCallbacks _gde_binding_callbacks = { \ + _gde_binding_create_callback, \ + _gde_binding_free_callback, \ + _gde_binding_reference_callback, \ + }; \ + m_class() : m_class(#m_alias_for) {} \ + \ +private: // Don't use this for your classes, use GDCLASS() instead. #define GDEXTENSION_CLASS(m_class, m_inherits) GDEXTENSION_CLASS_ALIAS(m_class, m_class, m_inherits) diff --git a/include/godot_cpp/core/memory.hpp b/include/godot_cpp/core/memory.hpp index 548f330..97a2b13 100644 --- a/include/godot_cpp/core/memory.hpp +++ b/include/godot_cpp/core/memory.hpp @@ -44,20 +44,21 @@ #define PAD_ALIGN 16 //must always be greater than this at much #endif -void *operator new(size_t p_size, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool -void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool -void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory +// p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS. +void *operator new(size_t p_size, const char *p_dummy, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool +void *operator new(size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool +void *operator new(size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory -_ALWAYS_INLINE_ void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description) { +_ALWAYS_INLINE_ void *operator new(size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description) { return p_pointer; } #ifdef _MSC_VER // When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291). // The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete. -void operator delete(void *p_mem, const char *p_description); -void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)); -void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description); +void operator delete(void *p_mem, const char *p_dummy, const char *p_description); +void operator delete(void *p_mem, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)); +void operator delete(void *p_mem, const char *p_dummy, void *p_pointer, size_t check, const char *p_description); #endif namespace godot { @@ -85,10 +86,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) { #define memrealloc(m_mem, m_size) ::godot::Memory::realloc_static(m_mem, m_size) #define memfree(m_mem) ::godot::Memory::free_static(m_mem) -#define memnew(m_class) ::godot::_post_initialize(new ("") m_class) +#define memnew(m_class) ::godot::_post_initialize(new ("", "") m_class) -#define memnew_allocator(m_class, m_allocator) ::godot::_post_initialize(new (m_allocator::alloc) m_class) -#define memnew_placement(m_placement, m_class) ::godot::_post_initialize(new (m_placement, sizeof(m_class), "") m_class) +#define memnew_allocator(m_class, m_allocator) ::godot::_post_initialize(new ("", m_allocator::alloc) m_class) +#define memnew_placement(m_placement, m_class) ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class) // Generic comparator used in Map, List, etc. template <class T> @@ -154,7 +155,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") { /* call operator new */ for (size_t i = 0; i < p_elements; i++) { - new (&elems[i], sizeof(T), p_descr) T; + new ("", &elems[i], sizeof(T), p_descr) T; } } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 80e71ec..8118511 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -103,28 +103,29 @@ _GlobalNil _GlobalNilClass::_nil; } // namespace godot -void *operator new(size_t p_size, const char *p_description) { +// p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS. +void *operator new(size_t p_size, const char *p_dummy, const char *p_description) { return godot::Memory::alloc_static(p_size); } -void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) { +void *operator new(size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)) { return p_allocfunc(p_size); } using namespace godot; #ifdef _MSC_VER -void operator delete(void *p_mem, const char *p_description) { +void operator delete(void *p_mem, const char *p_dummy, const char *p_description) { ERR_PRINT("Call to placement delete should not happen."); CRASH_NOW(); } -void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) { +void operator delete(void *p_mem, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)) { ERR_PRINT("Call to placement delete should not happen."); CRASH_NOW(); } -void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) { +void operator delete(void *p_mem, const char *p_dummy, void *p_pointer, size_t check, const char *p_description) { ERR_PRINT("Call to placement delete should not happen."); CRASH_NOW(); } diff --git a/test/SConstruct b/test/SConstruct index 1732ecd..9c25917 100644 --- a/test/SConstruct +++ b/test/SConstruct @@ -23,6 +23,17 @@ if env["platform"] == "macos": ), source=sources, ) +elif env["platform"] == "ios": + if env["ios_simulator"]: + library = env.StaticLibrary( + "project/bin/libgdexample.{}.{}.simulator.a".format(env["platform"], env["target"]), + source=sources, + ) + else: + library = env.StaticLibrary( + "project/bin/libgdexample.{}.{}.a".format(env["platform"], env["target"]), + source=sources, + ) else: library = env.SharedLibrary( "project/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]), diff --git a/test/generate_xcframework.sh b/test/generate_xcframework.sh new file mode 100755 index 0000000..7adddff --- /dev/null +++ b/test/generate_xcframework.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +scons arch=universal ios_simulator=yes platform=ios target=$1 $2 +scons arch=arm64 ios_simulator=no platform=ios target=$1 $2 + +xcodebuild -create-xcframework -library ./project/bin/libgdexample.ios.$1.a -library ./project/bin/libgdexample.ios.$1.simulator.a -output ./project/bin/libgdexample.ios.$1.xcframework +xcodebuild -create-xcframework -library ../bin/libgodot-cpp.ios.$1.arm64.a -library ../bin/libgodot-cpp.ios.$1.universal.simulator.a -output ./project/bin/libgodot-cpp.ios.$1.xcframework diff --git a/test/project/bin/libgdexample.osx.template_debug.framework/Resources/Info.plist b/test/project/bin/libgdexample.macos.template_debug.framework/Resources/Info.plist index fbdbd20..fbdbd20 100644 --- a/test/project/bin/libgdexample.osx.template_debug.framework/Resources/Info.plist +++ b/test/project/bin/libgdexample.macos.template_debug.framework/Resources/Info.plist diff --git a/test/project/bin/libgdexample.osx.template_release.framework/Resources/Info.plist b/test/project/bin/libgdexample.macos.template_release.framework/Resources/Info.plist index b3bc3ca..b3bc3ca 100644 --- a/test/project/bin/libgdexample.osx.template_release.framework/Resources/Info.plist +++ b/test/project/bin/libgdexample.macos.template_release.framework/Resources/Info.plist diff --git a/test/project/example.gdextension b/test/project/example.gdextension index 30279e6..4f599ce 100644 --- a/test/project/example.gdextension +++ b/test/project/example.gdextension @@ -11,8 +11,14 @@ windows.debug.x86_32 = "res://bin/libgdexample.windows.template_debug.x86_32.dll windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll" windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll" windows.release.x86_64 = "res://bin/libgdexample.windows.template_release.x86_64.dll" +windows.debug.arm64 = "res://bin/libgdexample.windows.template_debug.arm64.dll" +windows.release.arm64 = "res://bin/libgdexample.windows.template_release.arm64.dll" +linux.debug.x86_32 = "res://bin/libgdexample.linux.template_debug.x86_32.so" +linux.release.x86_32 = "res://bin/libgdexample.linux.template_release.x86_32.so" linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so" linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so" +linux.debug.arm32 = "res://bin/libgdexample.linux.template_debug.arm32.so" +linux.release.arm32 = "res://bin/libgdexample.linux.template_release.arm32.so" linux.debug.arm64 = "res://bin/libgdexample.linux.template_debug.arm64.so" linux.release.arm64 = "res://bin/libgdexample.linux.template_release.arm64.so" linux.debug.rv64 = "res://bin/libgdexample.linux.template_debug.rv64.so" @@ -21,5 +27,15 @@ android.debug.x86_64 = "res://bin/libgdexample.android.template_debug.x86_64.so" android.release.x86_64 = "res://bin/libgdexample.android.template_release.x86_64.so" android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so" android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so" +ios.debug = "res://bin/libgdexample.ios.template_debug.xcframework" +ios.release = "res://bin/libgdexample.ios.template_release.xcframework" web.debug.wasm32 = "res://bin/libgdexample.web.template_debug.wasm32.wasm" web.release.wasm32 = "res://bin/libgdexample.web.template_release.wasm32.wasm" + +[dependencies] +ios.debug = { + "res://bin/libgodot-cpp.ios.template_debug.xcframework": "" +} +ios.release = { + "res://bin/libgodot-cpp.ios.template_release.xcframework": "" +} diff --git a/test/project/project.godot b/test/project/project.godot index 3ed679b..4f51c07 100644 --- a/test/project/project.godot +++ b/test/project/project.godot @@ -21,4 +21,5 @@ paths=["res://example.gdextension"] [rendering] +textures/vram_compression/import_etc2_astc=true environment/defaults/default_environment="res://default_env.tres" diff --git a/tools/godotcpp.py b/tools/godotcpp.py index 8e7e1c6..fcf4dd7 100644 --- a/tools/godotcpp.py +++ b/tools/godotcpp.py @@ -179,7 +179,7 @@ def options(opts, env): BoolVariable( key="use_hot_reload", help="Enable the extra accounting required to support hot reload.", - default=(env.get("target", "template_debug") != "template_release"), + default=env.get("use_hot_reload", None), ) ) @@ -245,9 +245,20 @@ def generate(env): print("Building for architecture " + env["arch"] + " on platform " + env["platform"]) + if env.get("use_hot_reload") is None: + env["use_hot_reload"] = env["target"] != "template_release" if env["use_hot_reload"]: env.Append(CPPDEFINES=["HOT_RELOAD_ENABLED"]) + tool = Tool(env["platform"], toolpath=["tools"]) + + if tool is None or not tool.exists(env): + raise ValueError("Required toolchain not found for platform " + env["platform"]) + + tool.generate(env) + target_tool = Tool("targets", toolpath=["tools"]) + target_tool.generate(env) + # Disable exception handling. Godot doesn't use exceptions anywhere, and this # saves around 20% of binary size and very significant build time. if env["disable_exceptions"]: @@ -258,15 +269,6 @@ def generate(env): elif env.get("is_msvc", False): env.Append(CXXFLAGS=["/EHsc"]) - tool = Tool(env["platform"], toolpath=["tools"]) - - if tool is None or not tool.exists(env): - raise ValueError("Required toolchain not found for platform " + env["platform"]) - - tool.generate(env) - target_tool = Tool("targets", toolpath=["tools"]) - target_tool.generate(env) - # Require C++17 if env.get("is_msvc", False): env.Append(CXXFLAGS=["/std:c++17"]) |