diff options
-rw-r--r-- | CMakeLists.txt | 26 | ||||
-rw-r--r-- | include/godot_cpp/classes/wrapped.hpp | 19 | ||||
-rw-r--r-- | include/godot_cpp/core/class_db.hpp | 1 | ||||
-rw-r--r-- | test/CMakeLists.txt | 17 | ||||
-rw-r--r-- | test/project/main.gd | 3 | ||||
-rw-r--r-- | test/src/example.cpp | 6 | ||||
-rw-r--r-- | test/src/example.h | 2 | ||||
-rw-r--r-- | tools/godotcpp.py | 16 | ||||
-rw-r--r-- | tools/windows.py | 2 |
9 files changed, 85 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ee99aa..7fe8638 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,21 +72,22 @@ endif() # Input from user for GDExtension interface header and the API JSON file set(GODOT_GDEXTENSION_DIR "gdextension" CACHE STRING "") set(GODOT_CUSTOM_API_FILE "" CACHE STRING "") -set(FLOAT_PRECISION "single" CACHE STRING "") -if ("${FLOAT_PRECISION}" STREQUAL "double") - add_definitions(-DREAL_T_IS_DOUBLE) -endif() set(GODOT_GDEXTENSION_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json") if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override. set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}") endif() +set(FLOAT_PRECISION "single" CACHE STRING "") +if ("${FLOAT_PRECISION}" STREQUAL "double") + add_definitions(-DREAL_T_IS_DOUBLE) +endif() + set(GODOT_COMPILE_FLAGS ) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # using Visual Studio C++ - set(GODOT_COMPILE_FLAGS "/EHsc /utf-8") # /GF /MP + set(GODOT_COMPILE_FLAGS "/utf-8") # /GF /MP if(CMAKE_BUILD_TYPE MATCHES Debug) set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi @@ -107,6 +108,21 @@ else() # GCC/Clang endif(CMAKE_BUILD_TYPE MATCHES Debug) endif() +# Disable exception handling. Godot doesn't use exceptions anywhere, and this +# saves around 20% of binary size and very significant build time (GH-80513). +option(GODOT_DISABLE_EXCEPTIONS ON "Force disabling exception handling code") +if (GODOT_DISABLE_EXCEPTIONS) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D_HAS_EXCEPTIONS=0") + else() + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-exceptions") + endif() +else() + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /EHsc") + endif() +endif() + # Generate source from the bindings file find_package(Python3 3.4 REQUIRED) # pathlib should be present if(GENERATE_TEMPLATE_GET_NODE) diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp index 2bbffc0..af2ce4c 100644 --- a/include/godot_cpp/classes/wrapped.hpp +++ b/include/godot_cpp/classes/wrapped.hpp @@ -202,6 +202,8 @@ protected: } \ \ public: \ + typedef m_class self_type; \ + \ static void initialize_class() { \ static bool initialized = false; \ if (initialized) { \ @@ -395,6 +397,10 @@ protected: 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; \ } \ @@ -416,6 +422,8 @@ protected: } \ \ public: \ + typedef m_class self_type; \ + \ static void initialize_class() {} \ \ static ::godot::StringName &get_class_static() { \ @@ -427,6 +435,17 @@ public: 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); \ diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp index 17e093a..4196a76 100644 --- a/include/godot_cpp/core/class_db.hpp +++ b/include/godot_cpp/core/class_db.hpp @@ -170,6 +170,7 @@ public: template <class T, bool is_abstract> void ClassDB::_register_class(bool p_virtual, bool p_exposed) { + static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS."); instance_binding_callbacks[T::get_class_static()] = &T::_gde_binding_callbacks; // Register this class within our plugin diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0538c5d..4b25f41 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -36,7 +36,7 @@ set(GODOT_LINKER_FLAGS ) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # using Visual Studio C++ - set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /EHsc /WX") # /GF /MP + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /WX") # /GF /MP set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /DTYPED_METHOD_BIND") if(CMAKE_BUILD_TYPE MATCHES Debug) @@ -92,6 +92,21 @@ else() endif(CMAKE_BUILD_TYPE MATCHES Debug) endif() +# Disable exception handling. Godot doesn't use exceptions anywhere, and this +# saves around 20% of binary size and very significant build time (GH-80513). +option(GODOT_DISABLE_EXCEPTIONS ON "Force disabling exception handling code") +if (GODOT_DISABLE_EXCEPTIONS) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D_HAS_EXCEPTIONS=0") + else() + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-exceptions") + endif() +else() + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /EHsc") + endif() +endif() + # Get Sources file(GLOB_RECURSE SOURCES src/*.c**) file(GLOB_RECURSE HEADERS include/*.h**) diff --git a/test/project/main.gd b/test/project/main.gd index d5b8d94..62bd19d 100644 --- a/test/project/main.gd +++ b/test/project/main.gd @@ -83,6 +83,9 @@ func _ready(): var array: Array[int] = [1, 2, 3] assert_equal(example.test_tarray_arg(array), 6) + example.callable_bind() + assert_equal(custom_signal_emitted, ["bound", 11]) + # String += operator assert_equal(example.test_string_ops(), "ABCĎE") diff --git a/test/src/example.cpp b/test/src/example.cpp index c82bfba..dd58f37 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -178,6 +178,7 @@ void Example::_bind_methods() { ClassDB::bind_method(D_METHOD("return_last_rpc_arg"), &Example::return_last_rpc_arg); ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200)); + ClassDB::bind_method(D_METHOD("callable_bind"), &Example::callable_bind); ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static); ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2); @@ -533,6 +534,11 @@ int Example::return_last_rpc_arg() { return last_rpc_arg; } +void Example::callable_bind() { + Callable c = Callable(this, "emit_custom_signal").bind("bound", 11); + c.call(); +} + // Properties. void Example::set_custom_position(const Vector2 &pos) { custom_position = pos; diff --git a/test/src/example.h b/test/src/example.h index 929d8bb..200c970 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -159,6 +159,8 @@ public: void test_send_rpc(int p_value); int return_last_rpc_arg(); + void callable_bind(); + // Property. void set_custom_position(const Vector2 &pos); Vector2 get_custom_position() const; diff --git a/tools/godotcpp.py b/tools/godotcpp.py index 329fffc..8e7e1c6 100644 --- a/tools/godotcpp.py +++ b/tools/godotcpp.py @@ -183,6 +183,12 @@ def options(opts, env): ) ) + opts.Add( + BoolVariable( + "disable_exceptions", "Force disabling exception handling code", default=env.get("disable_exceptions", True) + ) + ) + # Add platform options for pl in platforms: tool = Tool(pl, toolpath=["tools"]) @@ -242,6 +248,16 @@ def generate(env): if env["use_hot_reload"]: env.Append(CPPDEFINES=["HOT_RELOAD_ENABLED"]) + # 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"]: + if env.get("is_msvc", False): + env.Append(CPPDEFINES=[("_HAS_EXCEPTIONS", 0)]) + else: + env.Append(CXXFLAGS=["-fno-exceptions"]) + 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): diff --git a/tools/windows.py b/tools/windows.py index e156aef..d5a729c 100644 --- a/tools/windows.py +++ b/tools/windows.py @@ -31,7 +31,7 @@ def generate(env): env.Tool("mslink") env.Append(CPPDEFINES=["TYPED_METHOD_BIND", "NOMINMAX"]) - env.Append(CCFLAGS=["/EHsc", "/utf-8"]) + env.Append(CCFLAGS=["/utf-8"]) env.Append(LINKFLAGS=["/WX"]) if env["use_clang_cl"]: |