summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt26
-rw-r--r--include/godot_cpp/classes/wrapped.hpp19
-rw-r--r--include/godot_cpp/core/class_db.hpp1
-rw-r--r--test/CMakeLists.txt17
-rw-r--r--test/project/main.gd3
-rw-r--r--test/src/example.cpp6
-rw-r--r--test/src/example.h2
-rw-r--r--tools/godotcpp.py16
-rw-r--r--tools/windows.py2
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"]: