diff --git a/src/godot/.gitignore b/src/godot/.gitignore index ff568d5..5e49886 100644 --- a/src/godot/.gitignore +++ b/src/godot/.gitignore @@ -1,3 +1,7 @@ .sconsign.dblite bin/ -*.os \ No newline at end of file +*.os +*.so +*.o +logs/ +storybook.h \ No newline at end of file diff --git a/src/godot/Makefile b/src/godot/Makefile new file mode 100644 index 0000000..9baaeef --- /dev/null +++ b/src/godot/Makefile @@ -0,0 +1,10 @@ +LDFLAGS := -Wl,--gc-sections -lpthread -ldl -rdynamic -shared +CFLAGS := -g -std=c11 -fPIC -Igodot-headers + +.PHONY: all +all: libstorybook.so +libstorybook.so: storybook.o ../rust-base/target/debug/libstorybook.a + $(CC) $(LDFLAGS) $^ -o $@ +storybook.o: storybook.h +storybook.h: + cbindgen -c ../rust-base/cbindgen.toml --crate storybook --lang c -o $@ ../rust-base diff --git a/src/godot/SConstruct b/src/godot/SConstruct deleted file mode 100644 index 8def9a2..0000000 --- a/src/godot/SConstruct +++ /dev/null @@ -1,109 +0,0 @@ -#!python -import os - -opts = Variables([], ARGUMENTS) - -# Gets the standard flags CC, CCX, etc. -env = DefaultEnvironment() - -# Define our options -opts.Add(EnumVariable('target', "Compilation target", 'debug', ['d', 'debug', 'r', 'release'])) -opts.Add(EnumVariable('platform', "Compilation platform", '', ['', 'windows', 'x11', 'linux', 'osx'])) -opts.Add(EnumVariable('p', "Compilation target, alias for 'platform'", '', ['', 'windows', 'x11', 'linux', 'osx'])) -opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'no')) -opts.Add(PathVariable('target_path', 'The path where the lib is installed.', 'bin/')) -opts.Add(PathVariable('target_name', 'The library name.', 'libgdstorybook', PathVariable.PathAccept)) - -# Local dependency paths, adapt them to your setup -godot_headers_path = "godot-cpp/godot-headers/" -cpp_bindings_path = "godot-cpp/" -cpp_library = "libgodot-cpp" - -# only support 64 at this time.. -bits = 64 - -# Updates the environment with the option variables. -opts.Update(env) - -# Process some arguments -if env['use_llvm']: - env['CC'] = 'clang' - env['CXX'] = 'clang++' - -if env['p'] != '': - env['platform'] = env['p'] - -if env['platform'] == '': - print("No valid target platform selected.") - quit(); - -# For the reference: -# - CCFLAGS are compilation flags shared between C and C++ -# - CFLAGS are for C-specific compilation flags -# - CXXFLAGS are for C++-specific compilation flags -# - CPPFLAGS are for pre-processor flags -# - CPPDEFINES are for pre-processor defines -# - LINKFLAGS are for linking flags - -# Check our platform specifics -if env['platform'] == "osx": - env['target_path'] += 'osx/' - cpp_library += '.osx' - env.Append(CCFLAGS=['-arch', 'x86_64']) - env.Append(CXXFLAGS=['-std=c++17']) - env.Append(LINKFLAGS=['-arch', 'x86_64']) - if env['target'] in ('debug', 'd'): - env.Append(CCFLAGS=['-g', '-O2']) - else: - env.Append(CCFLAGS=['-g', '-O3']) - -elif env['platform'] in ('x11', 'linux'): - env['target_path'] += 'x11/' - cpp_library += '.linux' - env.Append(CCFLAGS=['-fPIC']) - env.Append(CXXFLAGS=['-std=c++17']) - if env['target'] in ('debug', 'd'): - env.Append(CCFLAGS=['-g3', '-Og']) - else: - env.Append(CCFLAGS=['-g', '-O3']) - -elif env['platform'] == "windows": - env['target_path'] += 'win64/' - cpp_library += '.windows' - # This makes sure to keep the session environment variables on windows, - # that way you can run scons in a vs 2017 prompt and it will find all the required tools - env.Append(ENV=os.environ) - - env.Append(CPPDEFINES=['WIN32', '_WIN32', '_WINDOWS', '_CRT_SECURE_NO_WARNINGS']) - env.Append(CCFLAGS=['-W3', '-GR']) - env.Append(CXXFLAGS='/std:c++17') - if env['target'] in ('debug', 'd'): - env.Append(CPPDEFINES=['_DEBUG']) - env.Append(CCFLAGS=['-EHsc', '-MDd', '-ZI']) - env.Append(LINKFLAGS=['-DEBUG']) - else: - env.Append(CPPDEFINES=['NDEBUG']) - env.Append(CCFLAGS=['-O2', '-EHsc', '-MD']) - -if env['target'] in ('debug', 'd'): - cpp_library += '.debug' -else: - cpp_library += '.release' - -cpp_library += '.' + str(bits) - -# make sure our binding library is properly includes -env.Append(CPPPATH=['.', godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/', '../base/']) -env.Append(LIBPATH=[cpp_bindings_path + 'bin/', '../base']) -env.Append(LIBS=[cpp_library]) - -# tweak this if you want to use different folders, or more folders, to store your source code in. -env.Append(CPPPATH=['src/']) -sources = Glob('src/*.cpp') - -library = env.SharedLibrary(target=env['target_path'] + env['target_name'] , source=sources) - -Default(library) - -# Generates help for the -h scons option. -Help(opts.GenerateHelpText(env)) diff --git a/src/godot/src/gdlibrary.cpp b/src/godot/src/gdlibrary.cpp deleted file mode 100644 index de232b4..0000000 --- a/src/godot/src/gdlibrary.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Required for all godot modules -#include "storybook_godot.h" - -extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) { - godot::Godot::gdnative_init(o); -} - -extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) { - godot::Godot::gdnative_terminate(o); -} - -extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) { - godot::Godot::nativescript_init(handle); - - godot::register_class(); -} diff --git a/src/godot/src/storybook_godot.cpp b/src/godot/src/storybook_godot.cpp deleted file mode 100644 index 8ab3dbe..0000000 --- a/src/godot/src/storybook_godot.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "storybook_godot.h" - -using namespace godot; - -void Storybook::_register_methods() { - // TODO - // e.g. register_method("_process", &Story::_process); -} - -Storybook::Storybook(){} -Storybook::~Storybook(){} - - diff --git a/src/godot/src/storybook_godot.h b/src/godot/src/storybook_godot.h deleted file mode 100644 index 04b1b95..0000000 --- a/src/godot/src/storybook_godot.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef STORYBOOK_GODOT_H -#define STORYBOOK_GODOT_H - -#include - -#include -#include - -namespace godot { - class Storybook : public Node { - GODOT_CLASS(Storybook, Node) - private: - storybook::Storybook storybook; - public: - static void _register_methods(); - Storybook(); - ~Storybook(); - - void _init(); - }; -}; - -#endif /* STORYBOOK_GODOT_H */ diff --git a/src/godot/storybook.c b/src/godot/storybook.c new file mode 100644 index 0000000..ccac300 --- /dev/null +++ b/src/godot/storybook.c @@ -0,0 +1,127 @@ +#include + +#include + +#include "storybook.h" + +const godot_gdnative_core_api_struct *api = NULL; +const godot_gdnative_ext_nativescript_api_struct *nativescript_api = NULL; + +void *storybook_godot_constructor(godot_object *p_instance, void *p_method_data); +void storybook_godot_destructor(godot_object *p_instance, void *p_method_data, void *p_user_data); +godot_variant storybook_godot_parse(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args); +godot_variant storybook_godot_get_body(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args); +godot_variant storybook_godot_advance(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args); +godot_variant storybook_godot_get_footer(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args); + +void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *p_options) { + api = p_options->api_struct; + + for (int i = 0; i < api->num_extensions; i++) { + switch(api->extensions[i]->type) { + case GDNATIVE_EXT_NATIVESCRIPT: { + nativescript_api = (godot_gdnative_ext_nativescript_api_struct *)api->extensions[i]; + }; break; + default: break; + } + } +} + +void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *p_options) { + api = NULL; + nativescript_api = NULL; +} + +#define register_method(meth) \ + godot_instance_method meth = { NULL, NULL, NULL}; \ + meth.method = &storybook_godot_ ## meth; \ + nativescript_api->godot_nativescript_register_method(p_handle, "STORYBOOK", #meth, attributes, meth) + +void GDN_EXPORT godot_nativescript_init(void *p_handle) { + godot_instance_create_func create = { NULL, NULL, NULL }; + create.create_func = &storybook_godot_constructor; + + godot_instance_destroy_func destroy = { NULL, NULL, NULL }; + destroy.destroy_func = &storybook_godot_destructor; + + nativescript_api->godot_nativescript_register_class(p_handle, "STORYBOOK", "Reference", + create, destroy); + + godot_method_attributes attributes = { GODOT_METHOD_RPC_MODE_DISABLED }; + + register_method(parse); + register_method(get_body); + register_method(advance); + register_method(get_footer); +} + +typedef struct user_data_struct { + Book *book; +} user_data_struct; + +void *storybook_godot_constructor(godot_object *p_instance, void *p_method_data){ + user_data_struct *user_data = api->godot_alloc(sizeof(user_data_struct)); + return user_data; +} + +void storybook_godot_destructor(godot_object *p_instance, void *p_method_data, void *p_user_data) { + user_data_struct *user_data = (user_data_struct*) p_user_data; + storybook_free_book(user_data->book); + api->godot_free(user_data); +} + +godot_variant storybook_godot_parse(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args) { + godot_variant ret; + godot_string str = api->godot_variant_as_string(p_args[0]); + godot_char_string utf8 = api->godot_string_utf8(&str); + + user_data_struct *user_data = (user_data_struct*) p_user_data; + user_data->book = storybook_make_book(api->godot_char_string_get_data(&utf8)); + api->godot_char_string_destroy(&utf8); + + api->godot_variant_new_nil(&ret); + return ret; +} + + +godot_variant storybook_godot_get_body(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args) { + godot_variant ret; + godot_string str; + + user_data_struct *user_data = (user_data_struct*) p_user_data; + char *body = storybook_get_body(user_data->book); + api->godot_string_new(&str); + api->godot_string_parse_utf8(&str, body); + storybook_free_string(body); + + api->godot_variant_new_string(&ret, &str); + api->godot_string_destroy(&str); + + return ret; +} + +godot_variant storybook_godot_advance(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args) { + godot_variant ret; + + user_data_struct *user_data = (user_data_struct*) p_user_data; + + if (p_num_args == 0) { + storybook_advance_nooption(user_data->book); + } else { + uint64_t option = api->godot_variant_as_uint(p_args[0]); + storybook_advance_option(user_data->book, option); + } + + api->godot_variant_new_nil(&ret); + return ret; +} + +godot_variant storybook_godot_get_footer(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args) { + godot_variant ret; + + user_data_struct *user_data = (user_data_struct*) p_user_data; + footer ft = storybook_get_footer(user_data->book); + + api->godot_variant_new_int(&ret, ft); + return ret; +} diff --git a/src/rust-base/cbindgen.toml b/src/rust-base/cbindgen.toml index e139077..3870c1d 100644 --- a/src/rust-base/cbindgen.toml +++ b/src/rust-base/cbindgen.toml @@ -1,5 +1,4 @@ language = "C" -sys_includes = ["stdbool.h", "stdint.h"] include_guard = "STORYBOOK_H" [export.rename]