فهرست منبع

new and free change, custom free will crash engine, be wary

karroffel 7 سال پیش
والد
کامیت
a4a9a16001
7فایلهای تغییر یافته به همراه55 افزوده شده و 26 حذف شده
  1. 3 0
      .gitignore
  2. 2 2
      SConstruct
  3. 28 18
      binding_generator.py
  4. 9 0
      include/core/Godot.hpp
  5. 2 1
      include/core/GodotGlobal.hpp
  6. 5 5
      include/core/Ref.hpp
  7. 6 0
      src/core/GodotGlobal.cpp

+ 3 - 0
.gitignore

@@ -1,7 +1,10 @@
 # Generated bindings
 src/*.cpp
+src/gen
 src/*.hpp
 include/*.hpp
+include/gen
+*.json
 
 # Misc
 logs/*

+ 2 - 2
SConstruct

@@ -81,7 +81,7 @@ elif target_platform == 'osx':
     env.Append(LINKFLAGS = [ '-arch', 'x86_64', '-framework', 'Cocoa', '-Wl,-undefined,dynamic_lookup' ])
 
 
-env.Append(CPPPATH=['.', godot_headers, 'include', 'include/core'])
+env.Append(CPPPATH=['.', godot_headers, 'include', 'include/gen', 'include/core'])
 
 # Generate bindings?
 json_api_file = ''
@@ -100,7 +100,7 @@ if ARGUMENTS.get('generate_bindings', 'no') == 'yes':
 
 sources = []
 add_sources(sources, 'src/core', 'cpp')
-add_sources(sources, 'src', 'cpp')
+add_sources(sources, 'src/gen', 'cpp')
 
 
 library = env.StaticLibrary(target=result_path + '/' + result_name, source=sources)

+ 28 - 18
binding_generator.py

@@ -21,17 +21,17 @@ def generate_bindings(path):
         
         impl = generate_class_implementation(icalls, used_classes, c)
         
-        header_file = open("include/" + strip_name(c["name"]) + ".hpp", "w+")
+        header_file = open("include/gen/" + strip_name(c["name"]) + ".hpp", "w+")
         header_file.write(header)
         
-        source_file = open("src/" + strip_name(c["name"]) + ".cpp", "w+")
+        source_file = open("src/gen/" + strip_name(c["name"]) + ".cpp", "w+")
         source_file.write(impl)
     
     
-    icall_header_file = open("src/__icalls.hpp", "w+")
+    icall_header_file = open("src/gen/__icalls.hpp", "w+")
     icall_header_file.write(generate_icall_header(icalls))
     
-    icall_source_file = open("src/__icalls.cpp", "w+")
+    icall_source_file = open("src/gen/__icalls.cpp", "w+")
     icall_source_file.write(generate_icall_implementation(icalls))
 
 
@@ -177,9 +177,7 @@ def generate_class_header(used_classes, c):
     if c["instanciable"]:
         source.append("")
         source.append("")
-        source.append("\tstatic void *operator new(size_t);")
-        
-        source.append("\tstatic void operator delete(void *);")
+        source.append("\tstatic " + class_name + " *_new();")
     
     source.append("\n\t// methods")
     
@@ -333,18 +331,14 @@ 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::api->godot_get_class_constructor((char *)\"" + c["name"] + "\")();")
-        source.append("}")
-        
-        source.append("void " + strip_name(c["name"]) + "::operator delete(void *ptr)")
+        source.append(class_name + " *" + strip_name(c["name"]) + "::_new()")
         source.append("{")
-        source.append("\tgodot::api->godot_object_destroy(((Object *)ptr)->_owner);")
+        source.append("\treturn (" + class_name + " *) godot::nativescript_1_1_api->godot_nativescript_get_instance_binding_data(godot::_RegisterState::language_index, godot::api->godot_get_class_constructor((char *)\"" + c["name"] + "\")());")
         source.append("}")
     
     for method in c["methods"]:
         method_signature = ""
+
         
         method_signature += make_gdnative_type(method["return_type"])
         method_signature += strip_name(c["name"]) + "::" + escape_cpp(method["name"]) + "("
@@ -364,11 +358,20 @@ def generate_class_implementation(icalls, used_classes, c):
         method_signature += ")" + (" const" if method["is_const"] else "")
     
         source.append(method_signature + " {")
+
+
+        if method["name"] == "free":
+            # dirty hack because Object::free is marked virtual but doesn't actually exist...
+            source.append("\tgodot::api->godot_object_destroy(_owner);")
+            source.append("}")
+            source.append("")
+            continue
+        else:
         
-	source.append("\tstatic godot_method_bind *mb = nullptr;")
-	source.append("\tif (mb == nullptr) {")
-        source.append("\t\tmb = godot::api->godot_method_bind_get_method(\"" + c["name"] +"\", \"" + method["name"] + "\");")
-        source.append("\t}")
+            source.append("\tstatic godot_method_bind *mb = nullptr;")
+	    source.append("\tif (mb == nullptr) {")
+            source.append("\t\tmb = godot::api->godot_method_bind_get_method(\"" + c["name"] +"\", \"" + method["name"] + "\");")
+            source.append("\t}")
         
         return_statement = ""
         
@@ -435,6 +438,13 @@ def generate_class_implementation(icalls, used_classes, c):
             
             source.append("")
             
+            if is_class_type(method["return_type"]):
+                source.append("\tObject *obj = Object::___get_from_variant(__result);")
+                source.append("\tif (obj->has_method(\"reference\"))")
+                source.append("\t\tobj->callv(\"reference\", Array());")
+
+                source.append("")
+            
             
             for i, argument in enumerate(method["arguments"]):
                 source.append("\tgodot::api->godot_variant_destroy((godot_variant *) &__given_args[" + str(i) + "]);")

+ 9 - 0
include/core/Godot.hpp

@@ -16,6 +16,8 @@
 
 #include "GodotGlobal.hpp"
 
+#include <NativeScript.hpp>
+#include <GDNativeLibrary.hpp>
 
 namespace godot {
 
@@ -26,9 +28,16 @@ T *as(Object *obj)
 	return (T *) godot::nativescript_api->godot_nativescript_get_userdata(obj->_owner);
 }
 
+template<class T>
+T *get_wrapper(godot_object *obj)
+{
+	return (T *) godot::nativescript_1_1_api->godot_nativescript_get_instance_binding_data(godot::_RegisterState::language_index, obj);
+}
+
 
 #define GODOT_CLASS(Name, Base) \
 	public: inline static const char *___get_type_name() { return static_cast<const char *>(#Name); } \
+	inline static Name *_new() { godot::NativeScript *script = godot::NativeScript::_new(); script->set_library(godot::get_wrapper<godot::GDNativeLibrary>((godot_object *) godot::gdnlib)); script->set_class_name(#Name); Name *instance = godot::as<Name>(script->new_()); script->free(); return instance; } \
 	inline static const char *___get_base_type_name() { return Base::___get_class_name(); } \
 	inline static Object *___get_from_variant(godot::Variant a) { return (godot::Object *) godot::as<Name>(godot::Object::___get_from_variant(a)); } \
 	private:

+ 2 - 1
include/core/GodotGlobal.hpp

@@ -5,13 +5,14 @@
 #include "String.hpp"
 #include "Array.hpp"
 
-
 namespace godot {
 
 extern "C" const godot_gdnative_core_api_struct *api;
 extern "C" const godot_gdnative_ext_nativescript_api_struct *nativescript_api;
 extern "C" const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api;
 
+extern "C" const void *gdnlib;
+
 class Godot {
 
 public:

+ 5 - 5
include/core/Ref.hpp

@@ -3,7 +3,7 @@
 
 #include "Variant.hpp"
 #include "GodotGlobal.hpp"
-#include "../Reference.hpp"
+#include "Reference.hpp"
 
 namespace godot {
 
@@ -107,7 +107,7 @@ public:
 	void operator=(const Variant &p_variant) {
 
 		// TODO We need a safe cast
-		Reference *refb = (Reference *) (Object *) p_variant;
+		Reference *refb = (Reference *) Object::___get_from_variant(p_variant);
 		if (!refb) {
 			unref();
 			return;
@@ -156,7 +156,7 @@ public:
 
 		reference = nullptr;
 		// TODO We need a safe cast
-		Reference *refb = (Reference *) (Object *) p_variant;
+		Reference *refb = (Reference *) Object::___get_from_variant(p_variant);
 		if (!refb) {
 			unref();
 			return;
@@ -180,14 +180,14 @@ public:
 		if (reference && reference->unreference()) {
 
 			//memdelete(reference);
-			delete reference;
+			reference->free();
 		}
 		reference = nullptr;
 	}
 
 	void instance() {
 		//ref(memnew(T));
-		ref(new T);
+		ref(T::_new());
 	}
 
 	Ref() {

+ 6 - 0
src/core/GodotGlobal.cpp

@@ -30,6 +30,8 @@ const godot_gdnative_core_api_struct *api = nullptr;
 const godot_gdnative_ext_nativescript_api_struct *nativescript_api = nullptr;
 const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api = nullptr;
 
+const void *gdnlib = NULL;
+
 void Godot::print(const String& message)
 {
 	godot::api->godot_print((godot_string *) &message);
@@ -72,6 +74,7 @@ void Godot::print_error(const String& description, const String& function, const
 void Godot::gdnative_init(godot_gdnative_init_options *options)
 {
 	godot::api = options->api_struct;
+	godot::gdnlib = options->gd_native_library;
 
 	// now find our extensions
 	for (int i = 0; i < godot::api->num_extensions; i++) {
@@ -105,8 +108,11 @@ void Godot::nativescript_init(void *handle)
 	godot::_RegisterState::nativescript_handle = handle;
 
 	godot_instance_binding_functions binding_funcs = {};
+	binding_funcs.alloc_instance_binding_data = wrapper_create;
+	binding_funcs.free_instance_binding_data = wrapper_destroy;
 
 	godot::_RegisterState::language_index = godot::nativescript_1_1_api->godot_nativescript_register_instance_binding_data_functions(binding_funcs);
+
 }
 
 void Godot::nativescript_terminate(void *handle)