Nativescript 1.1
implemented instance binding data usage This commit changes the way C++ wrapper classes work. Previously, wrapper classes were merely wrapper *interfaces*. They used the `this` pointer to store the actual foreign Godot Object. With the NativeScript 1.1 extension it is now possible to have low-overhead language binding data attached to Objects. The C++ bindings use that feature to implement *proper* wrappers and enable regular C++ inheritance usage that way. Some things might still be buggy and untested, but the C++ SimpleDemo works with those changes. new and free change, custom free will crash engine, be wary fix exporting of non-object types fix free() crash with custom resources added type tags and safe object casting fix global type registration order fix cast_to changed build system to be more self contained updated .gitignore use typeid() for type tags now fix indentation in bindings generator remove accidentally added files fix gitignore Fixed up registering tool and updated godot_headers Fix crash when calling String::split/split_floats Was casting to the wrong object type. Also adds parse_ints function to String with the same logic Better warning/error macros Change gitignore so we get our gen folders New documentation based on nativescript 1.1 Fixed GODOT_SUBCLASS macro Preventing crash when function returned null ptr Adds needed include <typeinfo> Solves this issue #168 due to not having the include of typeinfo Fix compile error of 'WARN_PRINT' and 'ERR_PRINT'. cannot pass non-trivial object of type 'godot::String' to variadic function; expected type from format string was 'char *' [-Wnon-pod-varargs] update vector3::distance_to Remove godot_api.json as its now in the godot_headers submodule (api.json)pull/194/head
parent
13f4f0e8f8
commit
200bf226bf
|
@ -1,8 +1,3 @@
|
||||||
# Generated bindings
|
|
||||||
src/*.cpp
|
|
||||||
src/*.hpp
|
|
||||||
include/*.hpp
|
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
logs/*
|
logs/*
|
||||||
|
|
||||||
|
@ -16,3 +11,8 @@ logs/*
|
||||||
*.pdb
|
*.pdb
|
||||||
*.lib
|
*.lib
|
||||||
bin
|
bin
|
||||||
|
*.config
|
||||||
|
*.creator
|
||||||
|
*.creator.user
|
||||||
|
*.files
|
||||||
|
*.includes
|
||||||
|
|
191
README.md
191
README.md
|
@ -1,123 +1,180 @@
|
||||||
# godot-cpp
|
# godot-cpp
|
||||||
C++ bindings for the Godot script API
|
C++ bindings for the Godot script API
|
||||||
|
|
||||||
# Creating a GDNative library (Linux)
|
Note that the master branch in this repository is for use with Godot build from its latest master.
|
||||||
Create a directory named `SimpleLibrary` with subdirectories `lib, src`
|
If you need to support older versions of Godot use the relevant branch for that version in this repository.
|
||||||
|
|
||||||
|
The instructions below feature the new NativeScript 1.1 class structure and will only work for modules created for Godot 3.1 and later.
|
||||||
|
|
||||||
|
- [**Getting Started**](#getting-started)
|
||||||
|
- [**Creating a simple class**](#creating-a-simple-class)
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
| **Build latest version of Godot** | [**GitHub**](https://github.com/godotengine/godot) | [**Docs**](https://godot.readthedocs.io/en/latest/development/compiling/index.html) |
|
||||||
|
| --- | --- | --- |
|
||||||
|
|
||||||
|
### Setting up a new project
|
||||||
|
|
||||||
|
We recommend using git for managing your project and the instructions below assume so. Alternatively you can download the source code directly from GitHub in which case you need to download both [godot-cpp](https://github.com/GodotNativeTools/godot-cpp) and [godot_headers](https://github.com/GodotNativeTools/godot_headers).
|
||||||
|
|
||||||
Getting latest `godot-cpp` and `godot_headers`
|
|
||||||
```
|
```
|
||||||
$ git clone https://github.com/GodotNativeTools/godot-cpp
|
$ mkdir SimpleLibrary
|
||||||
$ git clone https://github.com/GodotNativeTools/godot_headers
|
$ cd SimpleLibrary
|
||||||
```
|
$ mkdir bin
|
||||||
right now our directory structure should look like this:
|
$ mkdir src
|
||||||
```
|
$ git clone --recursive https://github.com/GodotNativeTools/godot-cpp
|
||||||
godot-cpp
|
|
||||||
godot_headers
|
|
||||||
SimpleLibrary
|
|
||||||
├── lib/
|
|
||||||
└── src/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Now to generate cpp bindings
|
Note that if you wish to use a specific branch, add the -b option to the clone command:
|
||||||
|
```
|
||||||
|
$ git clone --recursive https://github.com/GodotNativeTools/godot-cpp -b 3.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Right now our directory structure should look like this:
|
||||||
|
```
|
||||||
|
SimpleLibrary/
|
||||||
|
├─godot-cpp/
|
||||||
|
| └─godot_headers/
|
||||||
|
├─bin/
|
||||||
|
└─src/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Updating the api.json
|
||||||
|
Our api.json file contains meta data of all the classes that are part of the Godot core and are needed to generate the C++ binding classes for use in GDNative modules.
|
||||||
|
|
||||||
|
A file is supplied in our repository for your convinience but if you are running a custom build of Godot and need access to classes that have recent changes a new api.json file must be generated. You do this by starting your Godot executable with the following parameters:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ godot --gdnative-generate-json-api api.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Now copy the api.json file into your folder structure so its easy to access.
|
||||||
|
|
||||||
|
### Compiling the cpp bindings library
|
||||||
|
The final step is to compile our cpp bindings library:
|
||||||
```
|
```
|
||||||
$ cd godot-cpp
|
$ cd godot-cpp
|
||||||
$ scons godotbinpath="../godot_fork/bin/godot_binary" p=linux
|
$ scons platform=<your platform> generate_bindings=yes
|
||||||
$ cd ..
|
$ cd ..
|
||||||
```
|
```
|
||||||
resulting libraries will be placed under `bin/` and the generated headers will be placed under `include/*`
|
|
||||||
|
|
||||||
**Note:**
|
> Replace `<your platform>` with either `windows`, `linux` or `osx`.
|
||||||
> `generate_bindings=yes` is used to force regenerating C++ bindings (`godot_api.json` - Godot API)
|
|
||||||
|
|
||||||
> Include `use_llvm=yes` for using clang++
|
> Include `use_llvm=yes` for using clang++
|
||||||
|
|
||||||
> You may need to specify `headers=../godot_headers` if you have compilation issues related to missing include files
|
> Include `target=runtime` to build a runtime build (windows only at the moment)
|
||||||
|
|
||||||
And our directory structure will be
|
> The resulting library will be created in `godot-cpp/bin/`, take note of its name as it will be different depending on platform.
|
||||||
```
|
|
||||||
godot-cpp
|
|
||||||
└── bin/libgodot-cpp.a
|
|
||||||
godot_headers
|
|
||||||
SimpleLibrary
|
|
||||||
├── lib/
|
|
||||||
└── src/
|
|
||||||
```
|
|
||||||
|
|
||||||
# Creating simple class
|
> If you want to use an alternative api.json file add `use_custom_api_file=yes custom_api_file=../api.json`, be sure to specify the correct location of where you placed your file.
|
||||||
|
|
||||||
|
## Creating a simple class
|
||||||
|
|
||||||
Create `init.cpp` under `SimpleLibrary/src/` and add the following code
|
Create `init.cpp` under `SimpleLibrary/src/` and add the following code
|
||||||
```cpp
|
```cpp
|
||||||
#include <core/Godot.hpp>
|
#include <Godot.hpp>
|
||||||
#include <Reference.hpp>
|
#include <Reference.hpp>
|
||||||
|
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
|
|
||||||
class SimpleClass : public GodotScript<Reference> {
|
class SimpleClass : public Reference {
|
||||||
GODOT_CLASS(SimpleClass);
|
GODOT_CLASS(SimpleClass, Reference);
|
||||||
public:
|
public:
|
||||||
SimpleClass() { }
|
SimpleClass() { }
|
||||||
|
|
||||||
void test_void_method() {
|
/* _init must exist as it is called by Godot */
|
||||||
Godot::print("This is test");
|
void _init() { }
|
||||||
}
|
|
||||||
|
|
||||||
Variant method(Variant arg) {
|
void test_void_method() {
|
||||||
Variant ret;
|
Godot::print("This is test");
|
||||||
ret = arg;
|
}
|
||||||
|
|
||||||
return ret;
|
Variant method(Variant arg) {
|
||||||
}
|
Variant ret;
|
||||||
|
ret = arg;
|
||||||
|
|
||||||
static void _register_methods() {
|
return ret;
|
||||||
register_method("method", &SimpleClass::method);
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* How to register exports like gdscript
|
|
||||||
* export var _name = "SimpleClass"
|
|
||||||
**/
|
|
||||||
register_property((char *)"base/name", &SimpleClass::_name, String("SimpleClass"));
|
|
||||||
|
|
||||||
/** For registering signal **/
|
static void _register_methods() {
|
||||||
// register_signal<SimpleClass>("signal_name");
|
register_method("method", &SimpleClass::method);
|
||||||
// register_signal<SimpleClass>("signal_name", "string_argument", GODOT_VARIANT_TYPE_STRING)
|
|
||||||
}
|
/**
|
||||||
|
* How to register exports like gdscript
|
||||||
String _name;
|
* export var _name = "SimpleClass"
|
||||||
|
**/
|
||||||
|
register_property<SimpleClass, String>("base/name", &SimpleClass::_name, String("SimpleClass"));
|
||||||
|
|
||||||
|
/* or alternatively with getter and setter methods */
|
||||||
|
register_property<SimpleClass, int>("base/value", &SimpleClass::set_value, &SimpleClass::get_value, 0);
|
||||||
|
|
||||||
|
/** For registering signal **/
|
||||||
|
// register_signal<SimpleClass>("signal_name");
|
||||||
|
// register_signal<SimpleClass>("signal_name", "string_argument", GODOT_VARIANT_TYPE_STRING)
|
||||||
|
}
|
||||||
|
|
||||||
|
String _name;
|
||||||
|
int _value;
|
||||||
|
|
||||||
|
void set_value(int p_value) {
|
||||||
|
_value = p_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_value() const {
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** GDNative Initialize **/
|
/** GDNative Initialize **/
|
||||||
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o)
|
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
|
||||||
{
|
|
||||||
godot::Godot::gdnative_init(o);
|
godot::Godot::gdnative_init(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** GDNative Terminate **/
|
/** GDNative Terminate **/
|
||||||
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o)
|
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
|
||||||
{
|
|
||||||
godot::Godot::gdnative_terminate(o);
|
godot::Godot::gdnative_terminate(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** NativeScript Initialize **/
|
/** NativeScript Initialize **/
|
||||||
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle)
|
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
|
||||||
{
|
|
||||||
godot::Godot::nativescript_init(handle);
|
godot::Godot::nativescript_init(handle);
|
||||||
|
|
||||||
godot::register_class<SimpleClass>();
|
godot::register_class<SimpleClass>();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# Compiling
|
### Compiling
|
||||||
|
|
||||||
|
*Linux*
|
||||||
```
|
```
|
||||||
$ cd SimpleLibrary
|
$ cd SimpleLibrary
|
||||||
$ clang -fPIC -o src/init.os -c src/init.cpp -g -O3 -std=c++14 -I../godot-cpp/include -Igodot_headers
|
$ clang -fPIC -o src/init.os -c src/init.cpp -g -O3 -std=c++14 -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Igodot-cpp/godot_headers
|
||||||
$ clang -o lib/libtest.so -shared src/init.os -L../godot-cpp/lib -lgodot-cpp
|
$ clang -o bin/libtest.so -shared src/init.os -Lgodot-cpp/bin -l<name of the godot-cpp>
|
||||||
```
|
```
|
||||||
This creates the file `libtest.so` in your `SimpleLibrary/lib` directory. For windows you need to find out what compiler flags need to be used.
|
> This creates the file `libtest.so` in your `SimpleLibrary/bin` directory.
|
||||||
|
|
||||||
# Creating `.gdns` file
|
> You will need to replace `<name of the godot-cpp>` with the file that was created in [**Compiling the cpp bindings library**](#compiling-the-cpp-bindings-library)
|
||||||
|
|
||||||
|
*Windows*
|
||||||
|
```
|
||||||
|
$ cd SimpleLibrary
|
||||||
|
$ cl /Fosrc/init.obj /c src/init.cpp /nologo -EHsc -DNDEBUG /MDd /Igodot-cpp\include /Igodot-cpp\include\core /Igodot-cpp\include\gen /Igodot-cpp\godot_headers
|
||||||
|
$ link /nologo /dll /out:bin\libtest.dll /implib:bin\libsimple.lib src\init.obj godot-cpp\bin\<name of the godot-cpp>
|
||||||
|
```
|
||||||
|
> This creates the file `libtest.dll` in your `SimpleLibrary/bin` directory.
|
||||||
|
|
||||||
|
> You will need to replace `<name of the godot-cpp>` with the file that was created in [**Compiling the cpp bindings library**](#compiling-the-cpp-bindings-library)
|
||||||
|
|
||||||
|
> Finally replace `/MDd` with `/MD` if you're generated a runtime build.
|
||||||
|
|
||||||
|
*macOS*
|
||||||
|
For OSX you need to find out what compiler flags need to be used.
|
||||||
|
|
||||||
|
### Creating `.gdnlib` and `.gdns` files
|
||||||
follow [godot_header/README.md](https://github.com/GodotNativeTools/godot_headers/blob/master/README.md#how-do-i-use-native-scripts-from-the-editor) to create the `.gdns`
|
follow [godot_header/README.md](https://github.com/GodotNativeTools/godot_headers/blob/master/README.md#how-do-i-use-native-scripts-from-the-editor) to create the `.gdns`
|
||||||
|
|
||||||
# Implementing with gdscript
|
### Implementing with gdscript
|
||||||
```gdscript
|
```gdscript
|
||||||
var simpleclass = load("res://simpleclass.gdns").new();
|
var simpleclass = load("res://simpleclass.gdns").new();
|
||||||
simpleclass.method("Test argument");
|
simpleclass.method("Test argument");
|
||||||
|
|
11
SConstruct
11
SConstruct
|
@ -96,7 +96,10 @@ elif env['platform'] == 'windows':
|
||||||
env.Append(LINKFLAGS=['--static', '-Wl,--no-undefined', '-static-libgcc', '-static-libstdc++'])
|
env.Append(LINKFLAGS=['--static', '-Wl,--no-undefined', '-static-libgcc', '-static-libstdc++'])
|
||||||
|
|
||||||
|
|
||||||
env.Append(CPPPATH=['.', env['headers_dir'], 'include', 'include/core'])
|
env.Append(CPPPATH=['.', env['headers_dir'], 'include', 'include/gen', 'include/core'])
|
||||||
|
|
||||||
|
# Generate bindings?
|
||||||
|
json_api_file = ''
|
||||||
|
|
||||||
# Generate bindings?
|
# Generate bindings?
|
||||||
json_api_file = ''
|
json_api_file = ''
|
||||||
|
@ -104,7 +107,7 @@ json_api_file = ''
|
||||||
if ARGUMENTS.get('use_custom_api_file', 'no') == 'yes':
|
if ARGUMENTS.get('use_custom_api_file', 'no') == 'yes':
|
||||||
json_api_file = ARGUMENTS.get('custom_api_file', '')
|
json_api_file = ARGUMENTS.get('custom_api_file', '')
|
||||||
else:
|
else:
|
||||||
json_api_file = os.path.join(os.getcwd(), 'godot_api.json')
|
json_api_file = os.path.join(os.getcwd(), 'godot_headers', 'api.json')
|
||||||
|
|
||||||
if ARGUMENTS.get('generate_bindings', 'no') == 'yes':
|
if ARGUMENTS.get('generate_bindings', 'no') == 'yes':
|
||||||
# Actually create the bindings here
|
# Actually create the bindings here
|
||||||
|
@ -113,9 +116,11 @@ if ARGUMENTS.get('generate_bindings', 'no') == 'yes':
|
||||||
|
|
||||||
binding_generator.generate_bindings(json_api_file)
|
binding_generator.generate_bindings(json_api_file)
|
||||||
|
|
||||||
|
|
||||||
|
# source to compile
|
||||||
sources = []
|
sources = []
|
||||||
add_sources(sources, 'src/core', 'cpp')
|
add_sources(sources, 'src/core', 'cpp')
|
||||||
add_sources(sources, 'src', 'cpp')
|
add_sources(sources, 'src/gen', 'cpp')
|
||||||
|
|
||||||
library = env.StaticLibrary(
|
library = env.StaticLibrary(
|
||||||
target='bin/' + 'libgodot-cpp.{}.{}.{}'.format(env['platform'], env['target'], env['bits']), source=sources
|
target='bin/' + 'libgodot-cpp.{}.{}.{}'.format(env['platform'], env['target'], env['bits']), source=sources
|
||||||
|
|
|
@ -21,19 +21,22 @@ def generate_bindings(path):
|
||||||
|
|
||||||
impl = generate_class_implementation(icalls, used_classes, c)
|
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)
|
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)
|
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_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))
|
icall_source_file.write(generate_icall_implementation(icalls))
|
||||||
|
|
||||||
|
register_types_file = open("src/gen/__register_types.cpp", "w+")
|
||||||
|
register_types_file.write(generate_type_registry(classes))
|
||||||
|
|
||||||
|
|
||||||
def is_reference_type(t):
|
def is_reference_type(t):
|
||||||
for c in classes:
|
for c in classes:
|
||||||
|
@ -79,6 +82,8 @@ def generate_class_header(used_classes, c):
|
||||||
# so don't include it here because it's not needed
|
# so don't include it here because it's not needed
|
||||||
if class_name != "Object" and class_name != "Reference":
|
if class_name != "Object" and class_name != "Reference":
|
||||||
source.append("#include <core/Ref.hpp>")
|
source.append("#include <core/Ref.hpp>")
|
||||||
|
else:
|
||||||
|
source.append("#include <core/TagDB.hpp>")
|
||||||
|
|
||||||
|
|
||||||
included = []
|
included = []
|
||||||
|
@ -100,7 +105,6 @@ def generate_class_header(used_classes, c):
|
||||||
if c["base_class"] != "":
|
if c["base_class"] != "":
|
||||||
source.append("#include \"" + strip_name(c["base_class"]) + ".hpp\"")
|
source.append("#include \"" + strip_name(c["base_class"]) + ".hpp\"")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
source.append("namespace godot {")
|
source.append("namespace godot {")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
@ -118,15 +122,40 @@ def generate_class_header(used_classes, c):
|
||||||
vararg_templates = ""
|
vararg_templates = ""
|
||||||
|
|
||||||
# generate the class definition here
|
# generate the class definition here
|
||||||
source.append("class " + class_name + ("" if c["base_class"] == "" else (" : public " + strip_name(c["base_class"])) ) + " {")
|
source.append("class " + class_name + (" : public _Wrapped" if c["base_class"] == "" else (" : public " + strip_name(c["base_class"])) ) + " {")
|
||||||
|
|
||||||
|
if c["base_class"] == "":
|
||||||
|
source.append("public: enum { ___CLASS_IS_SCRIPT = 0, };")
|
||||||
|
source.append("private:")
|
||||||
|
source.append("")
|
||||||
|
|
||||||
|
if c["singleton"]:
|
||||||
|
source.append("\tstatic " + class_name + " *_singleton;")
|
||||||
|
source.append("")
|
||||||
|
source.append("\t" + class_name + "();")
|
||||||
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
source.append("public:")
|
source.append("public:")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
# ___get_class_name
|
|
||||||
source.append("\tstatic inline char *___get_class_name() { return (char *) \"" + strip_name(c["name"]) + "\"; }")
|
|
||||||
|
|
||||||
source.append("\tstatic inline Object *___get_from_variant(Variant a) { return (Object *) a; }")
|
if c["singleton"]:
|
||||||
|
source.append("\tstatic inline " + class_name + " *get_singleton()")
|
||||||
|
source.append("\t{")
|
||||||
|
source.append("\t\tif (!" + class_name + "::_singleton) {")
|
||||||
|
source.append("\t\t\t" + class_name + "::_singleton = new " + class_name + ";")
|
||||||
|
source.append("\t\t}")
|
||||||
|
source.append("\t\treturn " + class_name + "::_singleton;")
|
||||||
|
source.append("\t}")
|
||||||
|
source.append("")
|
||||||
|
|
||||||
|
# godot::api->godot_global_get_singleton((char *) \"" + strip_name(c["name"]) + "\");"
|
||||||
|
|
||||||
|
# ___get_class_name
|
||||||
|
source.append("\tstatic inline const char *___get_class_name() { return (const char *) \"" + strip_name(c["name"]) + "\"; }")
|
||||||
|
|
||||||
|
source.append("\tstatic inline Object *___get_from_variant(Variant a) { godot_object *o = (godot_object*) a; return (Object *) godot::nativescript_1_1_api->godot_nativescript_get_instance_binding_data(godot::_RegisterState::language_index, o); }")
|
||||||
|
|
||||||
enum_values = []
|
enum_values = []
|
||||||
|
|
||||||
|
@ -146,17 +175,26 @@ def generate_class_header(used_classes, c):
|
||||||
|
|
||||||
|
|
||||||
if c["instanciable"]:
|
if c["instanciable"]:
|
||||||
source.append("\tstatic void *operator new(size_t);")
|
source.append("")
|
||||||
|
source.append("")
|
||||||
source.append("\tstatic void operator delete(void *);")
|
source.append("\tstatic " + class_name + " *_new();")
|
||||||
|
|
||||||
source.append("\n\t// methods")
|
source.append("\n\t// methods")
|
||||||
|
|
||||||
|
|
||||||
|
if class_name == "Object":
|
||||||
|
source.append("#ifndef GODOT_CPP_NO_OBJECT_CAST")
|
||||||
|
source.append("\ttemplate<class T>")
|
||||||
|
source.append("\tstatic T *cast_to(const Object *obj);")
|
||||||
|
source.append("#endif")
|
||||||
|
source.append("")
|
||||||
|
|
||||||
for method in c["methods"]:
|
for method in c["methods"]:
|
||||||
|
|
||||||
method_signature = ""
|
method_signature = ""
|
||||||
|
|
||||||
method_signature += "static " if c["singleton"] else ""
|
# TODO decide what to do about virtual methods
|
||||||
|
# method_signature += "virtual " if method["is_virtual"] else ""
|
||||||
method_signature += make_gdnative_type(method["return_type"])
|
method_signature += make_gdnative_type(method["return_type"])
|
||||||
method_name = escape_cpp(method["name"])
|
method_name = escape_cpp(method["name"])
|
||||||
method_signature += method_name + "("
|
method_signature += method_name + "("
|
||||||
|
@ -224,7 +262,7 @@ def generate_class_header(used_classes, c):
|
||||||
vararg_templates += "\ttemplate <class... Args> " + method_signature + "Args... args){\n\t\treturn " + method_name + "(" + method_arguments + "Array::make(args...));\n\t}\n"""
|
vararg_templates += "\ttemplate <class... Args> " + method_signature + "Args... args){\n\t\treturn " + method_name + "(" + method_arguments + "Array::make(args...));\n\t}\n"""
|
||||||
method_signature += "const Array& __var_args = Array()"
|
method_signature += "const Array& __var_args = Array()"
|
||||||
|
|
||||||
method_signature += ")" + (" const" if method["is_const"] and not c["singleton"] else "")
|
method_signature += ")" + (" const" if method["is_const"] else "")
|
||||||
|
|
||||||
|
|
||||||
source.append("\t" + method_signature + ";")
|
source.append("\t" + method_signature + ";")
|
||||||
|
@ -234,11 +272,10 @@ def generate_class_header(used_classes, c):
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
source.append("#endif")
|
source.append("#endif")
|
||||||
|
|
||||||
|
|
||||||
|
@ -279,23 +316,20 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||||
source.append("namespace godot {")
|
source.append("namespace godot {")
|
||||||
|
|
||||||
|
|
||||||
core_object_name = ("___static_object_" + strip_name(c["name"])) if c["singleton"] else "this"
|
core_object_name = "this"
|
||||||
|
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
if c["singleton"]:
|
if c["singleton"]:
|
||||||
source.append("static godot_object *" + core_object_name + ";")
|
source.append("" + class_name + " *" + class_name + "::_singleton = NULL;")
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
# FIXME Test if inlining has a huge impact on binary size
|
# FIXME Test if inlining has a huge impact on binary size
|
||||||
source.append("static inline void ___singleton_init()")
|
source.append(class_name + "::" + class_name + "() {")
|
||||||
source.append("{")
|
source.append("\t_owner = godot::api->godot_global_get_singleton((char *) \"" + strip_name(c["name"]) + "\");")
|
||||||
source.append("\tif (" + core_object_name + " == nullptr) {")
|
|
||||||
source.append("\t\t" + core_object_name + " = godot::api->godot_global_get_singleton((char *) \"" + strip_name(c["name"]) + "\");")
|
|
||||||
source.append("\t}")
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
@ -304,18 +338,14 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||||
|
|
||||||
|
|
||||||
if c["instanciable"]:
|
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("{")
|
||||||
source.append("\treturn godot::api->godot_get_class_constructor((char *)\"" + c["name"] + "\")();")
|
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("}")
|
|
||||||
|
|
||||||
source.append("void " + strip_name(c["name"]) + "::operator delete(void *ptr)")
|
|
||||||
source.append("{")
|
|
||||||
source.append("\tgodot::api->godot_object_destroy((godot_object *)ptr);")
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
|
|
||||||
for method in c["methods"]:
|
for method in c["methods"]:
|
||||||
method_signature = ""
|
method_signature = ""
|
||||||
|
|
||||||
|
|
||||||
method_signature += make_gdnative_type(method["return_type"])
|
method_signature += make_gdnative_type(method["return_type"])
|
||||||
method_signature += strip_name(c["name"]) + "::" + escape_cpp(method["name"]) + "("
|
method_signature += strip_name(c["name"]) + "::" + escape_cpp(method["name"]) + "("
|
||||||
|
@ -332,20 +362,23 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||||
method_signature += ", "
|
method_signature += ", "
|
||||||
method_signature += "const Array& __var_args"
|
method_signature += "const Array& __var_args"
|
||||||
|
|
||||||
method_signature += ")" + (" const" if method["is_const"] and not c["singleton"] else "")
|
method_signature += ")" + (" const" if method["is_const"] else "")
|
||||||
|
|
||||||
source.append(method_signature + " {")
|
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) {")
|
||||||
if c["singleton"]:
|
source.append("\t\tmb = godot::api->godot_method_bind_get_method(\"" + c["name"] +"\", \"" + method["name"] + "\");")
|
||||||
source.append("\t___singleton_init();")
|
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 = ""
|
return_statement = ""
|
||||||
|
|
||||||
|
@ -408,10 +441,17 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("\tVariant __result;")
|
source.append("\tVariant __result;")
|
||||||
source.append("\t*(godot_variant *) &__result = godot::api->godot_method_bind_call(mb, (godot_object *) " + core_object_name + ", (const godot_variant **) __args, " + size + ", nullptr);")
|
source.append("\t*(godot_variant *) &__result = godot::api->godot_method_bind_call(mb, ((const Object *) " + core_object_name + ")->_owner, (const godot_variant **) __args, " + size + ", nullptr);")
|
||||||
|
|
||||||
source.append("")
|
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"]):
|
for i, argument in enumerate(method["arguments"]):
|
||||||
source.append("\tgodot::api->godot_variant_destroy((godot_variant *) &__given_args[" + str(i) + "]);")
|
source.append("\tgodot::api->godot_variant_destroy((godot_variant *) &__given_args[" + str(i) + "]);")
|
||||||
|
@ -424,7 +464,7 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||||
if is_reference_type(method["return_type"]):
|
if is_reference_type(method["return_type"]):
|
||||||
cast += "Ref<" + strip_name(method["return_type"]) + ">::__internal_constructor(__result);"
|
cast += "Ref<" + strip_name(method["return_type"]) + ">::__internal_constructor(__result);"
|
||||||
else:
|
else:
|
||||||
cast += "(" + strip_name(method["return_type"]) + " *) (Object *) __result;"
|
cast += "(" + strip_name(method["return_type"]) + " *) " + strip_name(method["return_type"] + "::___get_from_variant(") + "__result);"
|
||||||
else:
|
else:
|
||||||
cast += "__result;"
|
cast += "__result;"
|
||||||
source.append("\treturn " + cast)
|
source.append("\treturn " + cast)
|
||||||
|
@ -445,7 +485,7 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||||
|
|
||||||
icall_name = get_icall_name(icall_sig)
|
icall_name = get_icall_name(icall_sig)
|
||||||
|
|
||||||
return_statement += icall_name + "(mb, (godot_object *) " + core_object_name
|
return_statement += icall_name + "(mb, (const Object *) " + core_object_name
|
||||||
|
|
||||||
for arg in method["arguments"]:
|
for arg in method["arguments"]:
|
||||||
return_statement += ", " + escape_cpp(arg["name"]) + (".ptr()" if is_reference_type(arg["type"]) else "")
|
return_statement += ", " + escape_cpp(arg["name"]) + (".ptr()" if is_reference_type(arg["type"]) else "")
|
||||||
|
@ -494,7 +534,7 @@ def generate_icall_header(icalls):
|
||||||
|
|
||||||
method_signature = ""
|
method_signature = ""
|
||||||
|
|
||||||
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, godot_object *inst"
|
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, const Object *inst"
|
||||||
|
|
||||||
for arg in args:
|
for arg in args:
|
||||||
method_signature += ", const "
|
method_signature += ", const "
|
||||||
|
@ -547,7 +587,7 @@ def generate_icall_implementation(icalls):
|
||||||
|
|
||||||
method_signature = ""
|
method_signature = ""
|
||||||
|
|
||||||
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, godot_object *inst"
|
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, const Object *inst"
|
||||||
|
|
||||||
for i, arg in enumerate(args):
|
for i, arg in enumerate(args):
|
||||||
method_signature += ", const "
|
method_signature += ", const "
|
||||||
|
@ -568,7 +608,7 @@ def generate_icall_implementation(icalls):
|
||||||
source.append(method_signature + " {")
|
source.append(method_signature + " {")
|
||||||
|
|
||||||
if ret_type != "void":
|
if ret_type != "void":
|
||||||
source.append("\t" + return_type(ret_type) + "ret;")
|
source.append("\t" + ("godot_object *" if is_class_type(ret_type) else return_type(ret_type)) + "ret;")
|
||||||
if is_class_type(ret_type):
|
if is_class_type(ret_type):
|
||||||
source.append("\tret = nullptr;")
|
source.append("\tret = nullptr;")
|
||||||
|
|
||||||
|
@ -581,7 +621,7 @@ def generate_icall_implementation(icalls):
|
||||||
if is_primitive(arg) or is_core_type(arg):
|
if is_primitive(arg) or is_core_type(arg):
|
||||||
wrapped_argument += "(void *) &arg" + str(i)
|
wrapped_argument += "(void *) &arg" + str(i)
|
||||||
else:
|
else:
|
||||||
wrapped_argument += "(void *) arg" + str(i)
|
wrapped_argument += "(void *) arg" + str(i) + "->_owner"
|
||||||
|
|
||||||
wrapped_argument += ","
|
wrapped_argument += ","
|
||||||
source.append(wrapped_argument)
|
source.append(wrapped_argument)
|
||||||
|
@ -589,10 +629,17 @@ def generate_icall_implementation(icalls):
|
||||||
source.append("\t};")
|
source.append("\t};")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("\tgodot::api->godot_method_bind_ptrcall(mb, inst, args, " + ("nullptr" if ret_type == "void" else "&ret") + ");")
|
source.append("\tgodot::api->godot_method_bind_ptrcall(mb, inst->_owner, args, " + ("nullptr" if ret_type == "void" else "&ret") + ");")
|
||||||
|
|
||||||
if ret_type != "void":
|
if ret_type != "void":
|
||||||
source.append("\treturn ret;")
|
if is_class_type(ret_type):
|
||||||
|
source.append("\tif (ret) {")
|
||||||
|
source.append("\t\treturn (Object *) godot::nativescript_1_1_api->godot_nativescript_get_instance_binding_data(godot::_RegisterState::language_index, ret);")
|
||||||
|
source.append("\t}")
|
||||||
|
source.append("")
|
||||||
|
source.append("\treturn (Object *) ret;")
|
||||||
|
else:
|
||||||
|
source.append("\treturn ret;")
|
||||||
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
|
|
||||||
|
@ -604,8 +651,44 @@ def generate_icall_implementation(icalls):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def generate_type_registry(classes):
|
||||||
|
source = []
|
||||||
|
|
||||||
|
source.append("#include \"TagDB.hpp\"")
|
||||||
|
source.append("#include <typeinfo>")
|
||||||
|
source.append("\n")
|
||||||
|
|
||||||
|
for c in classes:
|
||||||
|
source.append("#include <" + strip_name(c["name"]) + ".hpp>")
|
||||||
|
|
||||||
|
source.append("")
|
||||||
|
source.append("")
|
||||||
|
|
||||||
|
source.append("namespace godot {")
|
||||||
|
|
||||||
|
source.append("void ___register_types()")
|
||||||
|
source.append("{")
|
||||||
|
|
||||||
|
for c in classes:
|
||||||
|
class_name = strip_name(c["name"])
|
||||||
|
base_class_name = strip_name(c["base_class"])
|
||||||
|
|
||||||
|
class_type_hash = "typeid(" + class_name + ").hash_code()"
|
||||||
|
|
||||||
|
base_class_type_hash = "typeid(" + base_class_name + ").hash_code()"
|
||||||
|
|
||||||
|
if base_class_name == "":
|
||||||
|
base_class_type_hash = "0"
|
||||||
|
|
||||||
|
source.append("\tgodot::_TagDB::register_global_type(\"" + class_name + "\", " + class_type_hash + ", " + base_class_type_hash + ");")
|
||||||
|
|
||||||
|
source.append("}")
|
||||||
|
|
||||||
|
source.append("")
|
||||||
|
source.append("}")
|
||||||
|
|
||||||
|
|
||||||
|
return "\n".join(source)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -664,6 +747,8 @@ def get_used_classes(c):
|
||||||
|
|
||||||
|
|
||||||
def strip_name(name):
|
def strip_name(name):
|
||||||
|
if len(name) == 0:
|
||||||
|
return name
|
||||||
if name[0] == '_':
|
if name[0] == '_':
|
||||||
return name[1:]
|
return name[1:]
|
||||||
return name
|
return name
|
||||||
|
|
140717
godot_api.json
140717
godot_api.json
File diff suppressed because it is too large
Load Diff
|
@ -1 +1 @@
|
||||||
Subproject commit 2d221de20c7ddc297b8bb14f0dbd55c053eb3024
|
Subproject commit a51d905c5a34a441c1d4701b57c9de6548efbea3
|
|
@ -21,5 +21,7 @@
|
||||||
#include "Vector2.hpp"
|
#include "Vector2.hpp"
|
||||||
#include "Vector3.hpp"
|
#include "Vector3.hpp"
|
||||||
|
|
||||||
|
#include "Wrapped.hpp"
|
||||||
|
|
||||||
|
|
||||||
#endif // CORETYPES_H
|
#endif // CORETYPES_H
|
||||||
|
|
|
@ -107,32 +107,45 @@ typedef float real_t;
|
||||||
#define _PLANE_EQ_DOT_EPSILON 0.999
|
#define _PLANE_EQ_DOT_EPSILON 0.999
|
||||||
#define _PLANE_EQ_D_EPSILON 0.0001
|
#define _PLANE_EQ_D_EPSILON 0.0001
|
||||||
|
|
||||||
|
// ERR/WARN macros
|
||||||
#ifndef ERR_FAIL_COND_V
|
#ifndef WARN_PRINT
|
||||||
#define ERR_FAIL_COND_V(cond, ret) do { if (cond) { return ret; } } while(0)
|
#define WARN_PRINT(msg) fprintf(stdout, "ERROR: %s\n", msg); fflush(stdout)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef WARN_PRINTS
|
||||||
|
#define WARN_PRINTS(msg) WARN_PRINT((msg).utf8().get_data())
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_PRINT
|
||||||
|
#define ERR_PRINT(x) fprintf(stderr, "ERROR: %s\n", x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_PRINTS
|
||||||
|
#define ERR_PRINTS(msg) ERR_PRINT((msg).utf8().get_data())
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL
|
||||||
|
#define ERR_FAIL() ERR_PRINT("Failed")
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_FAIL_V
|
#ifndef ERR_FAIL_V
|
||||||
#define ERR_FAIL_V(a) return a
|
#define ERR_FAIL_V(a) { ERR_FAIL(); return a; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL_COND
|
||||||
|
#define ERR_FAIL_COND(a) do { if (a) { ERR_PRINT(#a); return; } } while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL_COND_V
|
||||||
|
#define ERR_FAIL_COND_V(cond, ret) do { if (cond) { ERR_PRINT(#cond); return ret; } } while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_FAIL_INDEX
|
#ifndef ERR_FAIL_INDEX
|
||||||
#define ERR_FAIL_INDEX(a, b)
|
#define ERR_FAIL_INDEX(a, b) do { if (a < 0 || a >= b) { ERR_FAIL(); return; } } while(0)
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ERR_PRINT
|
|
||||||
#define ERR_PRINT(msg) fprintf(stderr, "ERROR: %S\n", (msg).unicode_str())
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_FAIL_INDEX_V
|
#ifndef ERR_FAIL_INDEX_V
|
||||||
#define ERR_FAIL_INDEX_V(a, b, c)
|
#define ERR_FAIL_INDEX_V(a, b, c) do { if (a < 0 || a >= b) { ERR_FAIL(); return c; } } while(0)
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ERR_FAIL_COND
|
|
||||||
#define ERR_FAIL_COND(a) do { if (a) { fprintf(stderr, #a); return; } } while(0)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,60 +6,52 @@
|
||||||
|
|
||||||
#include <gdnative_api_struct.gen.h>
|
#include <gdnative_api_struct.gen.h>
|
||||||
#include <nativescript/godot_nativescript.h>
|
#include <nativescript/godot_nativescript.h>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
#include "CoreTypes.hpp"
|
#include "CoreTypes.hpp"
|
||||||
#include "Variant.hpp"
|
#include "Variant.hpp"
|
||||||
#include "Ref.hpp"
|
#include "Ref.hpp"
|
||||||
|
#include "TagDB.hpp"
|
||||||
|
|
||||||
#include "Object.hpp"
|
#include "Object.hpp"
|
||||||
|
|
||||||
#include "GodotGlobal.hpp"
|
#include "GodotGlobal.hpp"
|
||||||
|
|
||||||
|
#include <NativeScript.hpp>
|
||||||
|
#include <GDNativeLibrary.hpp>
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T *as(Object *obj)
|
T *as(const Object *obj)
|
||||||
{
|
{
|
||||||
return (T *) godot::nativescript_api->godot_nativescript_get_userdata(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
#define GODOT_CLASS(Name, Base) \
|
||||||
class GodotScript {
|
|
||||||
public:
|
|
||||||
T *owner;
|
|
||||||
|
|
||||||
// GodotScript() {}
|
|
||||||
|
|
||||||
void _init() {}
|
|
||||||
static const char *___get_base_type_name()
|
|
||||||
{
|
|
||||||
return T::___get_class_name();
|
|
||||||
}
|
|
||||||
|
|
||||||
static GodotScript<T> *___get_from_variant(Variant a)
|
|
||||||
{
|
|
||||||
return as<GodotScript<T> >((Object *) a);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _register_methods() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define GODOT_CLASS(Name) \
|
|
||||||
public: inline static const char *___get_type_name() { return static_cast<const char *>(#Name); } \
|
public: inline static const char *___get_type_name() { return static_cast<const char *>(#Name); } \
|
||||||
|
enum { ___CLASS_IS_SCRIPT = 1, }; \
|
||||||
|
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_()); 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:
|
private:
|
||||||
|
|
||||||
#define GODOT_SUBCLASS(Name, Base) \
|
#define GODOT_SUBCLASS(Name, Base) \
|
||||||
public: inline static const char *___get_type_name() { return static_cast<const char *>(#Name); } \
|
public: inline static const char *___get_type_name() { return static_cast<const char *>(#Name); } \
|
||||||
inline static const char *___get_base_type_name() { return static_cast<const char *>(#Base); } \
|
enum { ___CLASS_IS_SCRIPT = 1, }; \
|
||||||
|
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_()); return instance; } \
|
||||||
|
inline static const char *___get_base_type_name() { return #Base; } \
|
||||||
|
inline static Object *___get_from_variant(godot::Variant a) { return (godot::Object *) godot::as<Name>(godot::Object::___get_from_variant(a)); } \
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct _ArgCast {
|
struct _ArgCast {
|
||||||
static T _arg_cast(Variant a)
|
static T _arg_cast(Variant a)
|
||||||
|
@ -94,7 +86,8 @@ template<class T>
|
||||||
void *_godot_class_instance_func(godot_object *p, void *method_data)
|
void *_godot_class_instance_func(godot_object *p, void *method_data)
|
||||||
{
|
{
|
||||||
T *d = new T();
|
T *d = new T();
|
||||||
*(godot_object **) &d->owner = p;
|
d->_owner = p;
|
||||||
|
d->_type_tag = typeid(T).hash_code();
|
||||||
d->_init();
|
d->_init();
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
@ -116,8 +109,10 @@ void register_class()
|
||||||
godot_instance_destroy_func destroy = {};
|
godot_instance_destroy_func destroy = {};
|
||||||
destroy.destroy_func = _godot_class_destroy_func<T>;
|
destroy.destroy_func = _godot_class_destroy_func<T>;
|
||||||
|
|
||||||
|
_TagDB::register_type(typeid(T).hash_code(), typeid(T).hash_code());
|
||||||
|
|
||||||
godot::nativescript_api->godot_nativescript_register_class(godot::_RegisterState::nativescript_handle, T::___get_type_name(), T::___get_base_type_name(), create, destroy);
|
godot::nativescript_api->godot_nativescript_register_class(godot::_RegisterState::nativescript_handle, T::___get_type_name(), T::___get_base_type_name(), create, destroy);
|
||||||
|
godot::nativescript_1_1_api->godot_nativescript_set_type_tag(godot::_RegisterState::nativescript_handle, T::___get_type_name(), (const void *) typeid(T).hash_code());
|
||||||
T::_register_methods();
|
T::_register_methods();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +125,10 @@ void register_tool_class()
|
||||||
godot_instance_destroy_func destroy = {};
|
godot_instance_destroy_func destroy = {};
|
||||||
destroy.destroy_func = _godot_class_destroy_func<T>;
|
destroy.destroy_func = _godot_class_destroy_func<T>;
|
||||||
|
|
||||||
|
_TagDB::register_type(typeid(T).hash_code(), typeid(T).hash_code());
|
||||||
|
|
||||||
godot::nativescript_api->godot_nativescript_register_tool_class(godot::_RegisterState::nativescript_handle, T::___get_type_name(), T::___get_base_type_name(), create, destroy);
|
godot::nativescript_api->godot_nativescript_register_tool_class(godot::_RegisterState::nativescript_handle, T::___get_type_name(), T::___get_base_type_name(), create, destroy);
|
||||||
|
godot::nativescript_1_1_api->godot_nativescript_set_type_tag(godot::_RegisterState::nativescript_handle, T::___get_type_name(), (const void *) typeid(T).hash_code());
|
||||||
T::_register_methods();
|
T::_register_methods();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +366,7 @@ void register_property(const char *name, P (T::*var), P default_value, godot_met
|
||||||
usage = (godot_property_usage_flags) ((int) usage | GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE);
|
usage = (godot_property_usage_flags) ((int) usage | GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE);
|
||||||
|
|
||||||
if (def_val.get_type() == Variant::OBJECT) {
|
if (def_val.get_type() == Variant::OBJECT) {
|
||||||
Object *o = def_val;
|
Object *o = get_wrapper<Object>(def_val.operator godot_object*());
|
||||||
if (o && o->is_class("Resource")) {
|
if (o && o->is_class("Resource")) {
|
||||||
hint = (godot_property_hint) ((int) hint | GODOT_PROPERTY_HINT_RESOURCE_TYPE);
|
hint = (godot_property_hint) ((int) hint | GODOT_PROPERTY_HINT_RESOURCE_TYPE);
|
||||||
hint_string = o->get_class();
|
hint_string = o->get_class();
|
||||||
|
@ -490,6 +487,35 @@ void register_signal(String name, Args... varargs)
|
||||||
register_signal<T>(name, Dictionary::make(varargs...));
|
register_signal<T>(name, Dictionary::make(varargs...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GODOT_CPP_NO_OBJECT_CAST
|
||||||
|
template<class T>
|
||||||
|
T *Object::cast_to(const Object *obj)
|
||||||
|
{
|
||||||
|
size_t have_tag = (size_t) godot::nativescript_1_1_api->godot_nativescript_get_type_tag(obj->_owner);
|
||||||
|
|
||||||
|
if (have_tag) {
|
||||||
|
if (!godot::_TagDB::is_type_known((size_t) have_tag)) {
|
||||||
|
have_tag = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!have_tag) {
|
||||||
|
have_tag = obj->_type_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (godot::_TagDB::is_type_compatible(typeid(T).hash_code(), have_tag)) {
|
||||||
|
return (T::___CLASS_IS_SCRIPT) ? godot::as<T>(obj) : (T *) obj;
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GODOT_H
|
#endif // GODOT_H
|
||||||
|
|
|
@ -5,11 +5,13 @@
|
||||||
#include "String.hpp"
|
#include "String.hpp"
|
||||||
#include "Array.hpp"
|
#include "Array.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
extern "C" const godot_gdnative_core_api_struct *api;
|
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_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 {
|
class Godot {
|
||||||
|
|
||||||
|
@ -21,6 +23,7 @@ public:
|
||||||
static void gdnative_init(godot_gdnative_init_options *o);
|
static void gdnative_init(godot_gdnative_init_options *o);
|
||||||
static void gdnative_terminate(godot_gdnative_terminate_options *o);
|
static void gdnative_terminate(godot_gdnative_terminate_options *o);
|
||||||
static void nativescript_init(void *handle);
|
static void nativescript_init(void *handle);
|
||||||
|
static void nativescript_terminate(void *handle);
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
static void print(const String& fmt, Args... values) {
|
static void print(const String& fmt, Args... values) {
|
||||||
|
@ -32,6 +35,7 @@ public:
|
||||||
|
|
||||||
struct _RegisterState {
|
struct _RegisterState {
|
||||||
static void *nativescript_handle;
|
static void *nativescript_handle;
|
||||||
|
static int language_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "Variant.hpp"
|
#include "Variant.hpp"
|
||||||
#include "GodotGlobal.hpp"
|
#include "GodotGlobal.hpp"
|
||||||
#include "../Reference.hpp"
|
#include "Reference.hpp"
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ public:
|
||||||
void operator=(const Variant &p_variant) {
|
void operator=(const Variant &p_variant) {
|
||||||
|
|
||||||
// TODO We need a safe cast
|
// TODO We need a safe cast
|
||||||
Reference *refb = (Reference *) (Object *) p_variant;
|
Reference *refb = (Reference *) T::___get_from_variant(p_variant);
|
||||||
if (!refb) {
|
if (!refb) {
|
||||||
unref();
|
unref();
|
||||||
return;
|
return;
|
||||||
|
@ -156,7 +156,7 @@ public:
|
||||||
|
|
||||||
reference = nullptr;
|
reference = nullptr;
|
||||||
// TODO We need a safe cast
|
// TODO We need a safe cast
|
||||||
Reference *refb = (Reference *) (Object *) p_variant;
|
Reference *refb = (Reference *) T::___get_from_variant(p_variant);
|
||||||
if (!refb) {
|
if (!refb) {
|
||||||
unref();
|
unref();
|
||||||
return;
|
return;
|
||||||
|
@ -180,14 +180,14 @@ public:
|
||||||
if (reference && reference->unreference()) {
|
if (reference && reference->unreference()) {
|
||||||
|
|
||||||
//memdelete(reference);
|
//memdelete(reference);
|
||||||
delete reference;
|
reference->free();
|
||||||
}
|
}
|
||||||
reference = nullptr;
|
reference = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void instance() {
|
void instance() {
|
||||||
//ref(memnew(T));
|
//ref(memnew(T));
|
||||||
ref(new T);
|
ref(T::_new());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref() {
|
Ref() {
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace godot {
|
||||||
class NodePath;
|
class NodePath;
|
||||||
class Variant;
|
class Variant;
|
||||||
class PoolByteArray;
|
class PoolByteArray;
|
||||||
|
class PoolIntArray;
|
||||||
class PoolRealArray;
|
class PoolRealArray;
|
||||||
class PoolStringArray;
|
class PoolStringArray;
|
||||||
class String;
|
class String;
|
||||||
|
@ -120,6 +121,7 @@ public:
|
||||||
String sha256_text() const;
|
String sha256_text() const;
|
||||||
float similarity(String text) const;
|
float similarity(String text) const;
|
||||||
PoolStringArray split(String divisor, bool allow_empty = true) const;
|
PoolStringArray split(String divisor, bool allow_empty = true) const;
|
||||||
|
PoolIntArray split_ints(String divisor, bool allow_empty = true) const;
|
||||||
PoolRealArray split_floats(String divisor, bool allow_empty = true) const;
|
PoolRealArray split_floats(String divisor, bool allow_empty = true) const;
|
||||||
String strip_edges(bool left = true, bool right = true) const;
|
String strip_edges(bool left = true, bool right = true) const;
|
||||||
String substr(int from, int len) const;
|
String substr(int from, int len) const;
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef TAGDB_HPP
|
||||||
|
#define TAGDB_HPP
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
|
||||||
|
namespace _TagDB {
|
||||||
|
|
||||||
|
void register_type(size_t type_tag, size_t base_type_tag);
|
||||||
|
bool is_type_known(size_t type_tag);
|
||||||
|
void register_global_type(const char *name, size_t type_tag, size_t base_type_tag);
|
||||||
|
bool is_type_compatible(size_t type_tag, size_t base_type_tag);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TAGDB_HPP
|
|
@ -225,7 +225,7 @@ public:
|
||||||
|
|
||||||
operator NodePath() const;
|
operator NodePath() const;
|
||||||
operator RID() const;
|
operator RID() const;
|
||||||
operator Object*() const;
|
operator godot_object*() const;
|
||||||
|
|
||||||
operator Dictionary() const;
|
operator Dictionary() const;
|
||||||
operator Array() const;
|
operator Array() const;
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef WRAPPED_HPP
|
||||||
|
#define WRAPPED_HPP
|
||||||
|
|
||||||
|
#include <gdnative/gdnative.h>
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
|
||||||
|
class _Wrapped {
|
||||||
|
public:
|
||||||
|
godot_object *_owner;
|
||||||
|
size_t _type_tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WRAPPED_HPP
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
|
@ -269,7 +269,7 @@ Color Color::html(const String& p_color)
|
||||||
} else if (color.length()==6) {
|
} else if (color.length()==6) {
|
||||||
alpha=false;
|
alpha=false;
|
||||||
} else {
|
} else {
|
||||||
ERR_PRINT(String("Invalid Color Code: ") + p_color);
|
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||||
ERR_FAIL_V(Color());
|
ERR_FAIL_V(Color());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ Color Color::html(const String& p_color)
|
||||||
if (alpha) {
|
if (alpha) {
|
||||||
a=_parse_col(color,0);
|
a=_parse_col(color,0);
|
||||||
if (a<0) {
|
if (a<0) {
|
||||||
ERR_PRINT("Invalid Color Code: "+p_color);
|
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||||
ERR_FAIL_V(Color());
|
ERR_FAIL_V(Color());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,17 +286,17 @@ Color Color::html(const String& p_color)
|
||||||
|
|
||||||
int r=_parse_col(color,from+0);
|
int r=_parse_col(color,from+0);
|
||||||
if (r<0) {
|
if (r<0) {
|
||||||
ERR_PRINT("Invalid Color Code: "+p_color);
|
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||||
ERR_FAIL_V(Color());
|
ERR_FAIL_V(Color());
|
||||||
}
|
}
|
||||||
int g=_parse_col(color,from+2);
|
int g=_parse_col(color,from+2);
|
||||||
if (g<0) {
|
if (g<0) {
|
||||||
ERR_PRINT("Invalid Color Code: "+p_color);
|
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||||
ERR_FAIL_V(Color());
|
ERR_FAIL_V(Color());
|
||||||
}
|
}
|
||||||
int b=_parse_col(color,from+4);
|
int b=_parse_col(color,from+4);
|
||||||
if (b<0) {
|
if (b<0) {
|
||||||
ERR_PRINT("Invalid Color Code: "+p_color);
|
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||||
ERR_FAIL_V(Color());
|
ERR_FAIL_V(Color());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,35 @@
|
||||||
|
|
||||||
#include "String.hpp"
|
#include "String.hpp"
|
||||||
|
|
||||||
|
#include "Wrapped.hpp"
|
||||||
|
|
||||||
|
static GDCALLINGCONV void *wrapper_create(void *data, const void *type_tag, godot_object *instance)
|
||||||
|
{
|
||||||
|
godot::_Wrapped *wrapper_memory = (godot::_Wrapped *) godot::api->godot_alloc(sizeof(godot::_Wrapped));
|
||||||
|
|
||||||
|
if (!wrapper_memory)
|
||||||
|
return NULL;
|
||||||
|
wrapper_memory->_owner = instance;
|
||||||
|
wrapper_memory->_type_tag = (size_t) type_tag;
|
||||||
|
|
||||||
|
return (void *) wrapper_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GDCALLINGCONV void wrapper_destroy(void *data, void *wrapper)
|
||||||
|
{
|
||||||
|
if (wrapper)
|
||||||
|
godot::api->godot_free(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
void *_RegisterState::nativescript_handle;
|
void *_RegisterState::nativescript_handle;
|
||||||
|
int _RegisterState::language_index;
|
||||||
const godot_gdnative_core_api_struct *api = nullptr;
|
const godot_gdnative_core_api_struct *api = nullptr;
|
||||||
const godot_gdnative_ext_nativescript_api_struct *nativescript_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)
|
void Godot::print(const String& message)
|
||||||
{
|
{
|
||||||
|
@ -47,19 +71,33 @@ void Godot::print_error(const String& description, const String& function, const
|
||||||
if (c_file != nullptr) godot::api->godot_free(c_file);
|
if (c_file != nullptr) godot::api->godot_free(c_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ___register_types();
|
||||||
|
|
||||||
void Godot::gdnative_init(godot_gdnative_init_options *options)
|
void Godot::gdnative_init(godot_gdnative_init_options *options)
|
||||||
{
|
{
|
||||||
godot::api = options->api_struct;
|
godot::api = options->api_struct;
|
||||||
|
godot::gdnlib = options->gd_native_library;
|
||||||
|
|
||||||
// now find our extensions
|
// now find our extensions
|
||||||
for (int i = 0; i < godot::api->num_extensions; i++) {
|
for (int i = 0; i < godot::api->num_extensions; i++) {
|
||||||
switch (godot::api->extensions[i]->type) {
|
switch (godot::api->extensions[i]->type) {
|
||||||
case GDNATIVE_EXT_NATIVESCRIPT: {
|
case GDNATIVE_EXT_NATIVESCRIPT: {
|
||||||
godot::nativescript_api = (godot_gdnative_ext_nativescript_api_struct *)godot::api->extensions[i];
|
godot::nativescript_api = (const godot_gdnative_ext_nativescript_api_struct *)godot::api->extensions[i];
|
||||||
}; break;
|
|
||||||
|
const godot_gdnative_api_struct *extension = godot::nativescript_api->next;
|
||||||
|
|
||||||
|
while (extension) {
|
||||||
|
if (extension->version.major == 1 && extension->version.minor == 1) {
|
||||||
|
godot::nativescript_1_1_api = (const godot_gdnative_ext_nativescript_1_1_api_struct *) extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension = extension->next;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
default: break;
|
default: break;
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Godot::gdnative_terminate(godot_gdnative_terminate_options *options)
|
void Godot::gdnative_terminate(godot_gdnative_terminate_options *options)
|
||||||
|
@ -70,6 +108,19 @@ void Godot::gdnative_terminate(godot_gdnative_terminate_options *options)
|
||||||
void Godot::nativescript_init(void *handle)
|
void Godot::nativescript_init(void *handle)
|
||||||
{
|
{
|
||||||
godot::_RegisterState::nativescript_handle = 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);
|
||||||
|
|
||||||
|
___register_types();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
void Godot::nativescript_terminate(void *handle)
|
||||||
|
{
|
||||||
|
godot::nativescript_1_1_api->godot_nativescript_unregister_instance_binding_data_functions(godot::_RegisterState::language_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -219,7 +219,7 @@ bool String::begins_with_char_array(const char *p_char_array) const {
|
||||||
PoolStringArray String::bigrams() const {
|
PoolStringArray String::bigrams() const {
|
||||||
godot_array arr = godot::api->godot_string_bigrams(&_godot_string);
|
godot_array arr = godot::api->godot_string_bigrams(&_godot_string);
|
||||||
|
|
||||||
return *(PoolStringArray *)&arr;
|
return *(Array *)&arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
String String::c_escape() const {
|
String String::c_escape() const {
|
||||||
|
@ -479,13 +479,19 @@ float String::similarity(String text) const {
|
||||||
PoolStringArray String::split(String divisor, bool allow_empty) const {
|
PoolStringArray String::split(String divisor, bool allow_empty) const {
|
||||||
godot_array arr = godot::api->godot_string_split(&_godot_string, &divisor._godot_string);
|
godot_array arr = godot::api->godot_string_split(&_godot_string, &divisor._godot_string);
|
||||||
|
|
||||||
return *(PoolStringArray *)&arr;
|
return *(Array *)&arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolIntArray String::split_ints(String divisor, bool allow_empty) const {
|
||||||
|
godot_array arr = godot::api->godot_string_split_floats(&_godot_string, &divisor._godot_string);
|
||||||
|
|
||||||
|
return *(Array *)&arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolRealArray String::split_floats(String divisor, bool allow_empty) const {
|
PoolRealArray String::split_floats(String divisor, bool allow_empty) const {
|
||||||
godot_array arr = godot::api->godot_string_split_floats(&_godot_string, &divisor._godot_string);
|
godot_array arr = godot::api->godot_string_split_floats(&_godot_string, &divisor._godot_string);
|
||||||
|
|
||||||
return *(PoolRealArray *)&arr;
|
return *(Array *)&arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
String String::strip_edges(bool left, bool right) const {
|
String String::strip_edges(bool left, bool right) const {
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "TagDB.hpp"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <GodotGlobal.hpp>
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
|
||||||
|
namespace _TagDB {
|
||||||
|
|
||||||
|
std::unordered_map<size_t, size_t> parent_to;
|
||||||
|
|
||||||
|
void register_type(size_t type_tag, size_t base_type_tag)
|
||||||
|
{
|
||||||
|
if (type_tag == base_type_tag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parent_to[type_tag] = base_type_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_type_known(size_t type_tag)
|
||||||
|
{
|
||||||
|
return parent_to.find(type_tag) != parent_to.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_global_type(const char *name, size_t type_tag, size_t base_type_tag)
|
||||||
|
{
|
||||||
|
|
||||||
|
godot::nativescript_1_1_api->godot_nativescript_set_global_type_tag(godot::_RegisterState::language_index, name, (const void *) type_tag);
|
||||||
|
|
||||||
|
register_type(type_tag, base_type_tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_type_compatible(size_t ask_tag, size_t have_tag)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (have_tag == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
size_t tag = have_tag;
|
||||||
|
|
||||||
|
while (tag != 0) {
|
||||||
|
if (tag == ask_tag)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
tag = parent_to[tag];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Defs.hpp"
|
#include "Defs.hpp"
|
||||||
#include "CoreTypes.hpp"
|
#include "CoreTypes.hpp"
|
||||||
#include "GodotGlobal.hpp"
|
#include "GodotGlobal.hpp"
|
||||||
|
#include "Object.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ Variant::Variant(const RID& p_rid)
|
||||||
|
|
||||||
Variant::Variant(const Object* p_object)
|
Variant::Variant(const Object* p_object)
|
||||||
{
|
{
|
||||||
godot::api->godot_variant_new_object(&_godot_variant, (godot_object *) p_object);
|
godot::api->godot_variant_new_object(&_godot_variant, p_object->_owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::Variant(const Dictionary& p_dictionary)
|
Variant::Variant(const Dictionary& p_dictionary)
|
||||||
|
@ -363,9 +364,8 @@ Variant::operator PoolColorArray() const
|
||||||
godot_pool_color_array s = godot::api->godot_variant_as_pool_color_array(&_godot_variant);
|
godot_pool_color_array s = godot::api->godot_variant_as_pool_color_array(&_godot_variant);
|
||||||
return *(PoolColorArray *) &s;
|
return *(PoolColorArray *) &s;
|
||||||
}
|
}
|
||||||
Variant::operator Object*() const {
|
Variant::operator godot_object*() const {
|
||||||
godot_object *o = godot::api->godot_variant_as_object(&_godot_variant);
|
return godot::api->godot_variant_as_object(&_godot_variant);
|
||||||
return (Object *) o;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::Type Variant::get_type() const
|
Variant::Type Variant::get_type() const
|
||||||
|
|
|
@ -229,12 +229,12 @@ real_t Vector3::length_squared() const
|
||||||
|
|
||||||
real_t Vector3::distance_squared_to(const Vector3& b) const
|
real_t Vector3::distance_squared_to(const Vector3& b) const
|
||||||
{
|
{
|
||||||
return (b-*this).length();
|
return (b-*this).length_squared();
|
||||||
}
|
}
|
||||||
|
|
||||||
real_t Vector3::distance_to(const Vector3& b) const
|
real_t Vector3::distance_to(const Vector3& b) const
|
||||||
{
|
{
|
||||||
return (b-*this).length_squared();
|
return (b-*this).length();
|
||||||
}
|
}
|
||||||
|
|
||||||
real_t Vector3::dot(const Vector3& b) const
|
real_t Vector3::dot(const Vector3& b) const
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
Loading…
Reference in New Issue