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

pull/155/head
karroffel 2018-03-11 11:43:06 +01:00
parent e9517a7b3b
commit a4a9a16001
7 changed files with 55 additions and 26 deletions

3
.gitignore vendored
View File

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

View File

@ -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)

View File

@ -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(class_name + " *" + strip_name(c["name"]) + "::_new()")
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("{")
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) + "]);")

View File

@ -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:

View File

@ -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:

View File

@ -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() {

View File

@ -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)