mirror of
https://github.com/godotengine/godot-cpp.git
synced 2026-01-01 05:48:37 +03:00
Compare commits
6 Commits
nativescri
...
nativescri
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1729360e6e | ||
|
|
13f4f0e8f8 | ||
|
|
f52cc4c964 | ||
|
|
ffb087caed | ||
|
|
72d227dd1c | ||
|
|
46fe7ada03 |
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,3 +1,8 @@
|
||||
# Generated bindings
|
||||
src/*.cpp
|
||||
src/*.hpp
|
||||
include/*.hpp
|
||||
|
||||
# Misc
|
||||
logs/*
|
||||
|
||||
@@ -11,8 +16,3 @@ logs/*
|
||||
*.pdb
|
||||
*.lib
|
||||
bin
|
||||
*.config
|
||||
*.creator
|
||||
*.creator.user
|
||||
*.files
|
||||
*.includes
|
||||
|
||||
191
README.md
191
README.md
@@ -1,180 +1,123 @@
|
||||
# godot-cpp
|
||||
C++ bindings for the Godot script API
|
||||
|
||||
Note that the master branch in this repository is for use with Godot build from its latest master.
|
||||
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).
|
||||
# Creating a GDNative library (Linux)
|
||||
Create a directory named `SimpleLibrary` with subdirectories `lib, src`
|
||||
|
||||
Getting latest `godot-cpp` and `godot_headers`
|
||||
```
|
||||
$ mkdir SimpleLibrary
|
||||
$ cd SimpleLibrary
|
||||
$ mkdir bin
|
||||
$ mkdir src
|
||||
$ git clone --recursive https://github.com/GodotNativeTools/godot-cpp
|
||||
$ git clone https://github.com/GodotNativeTools/godot-cpp
|
||||
$ git clone https://github.com/GodotNativeTools/godot_headers
|
||||
```
|
||||
right now our directory structure should look like this:
|
||||
```
|
||||
godot-cpp
|
||||
godot_headers
|
||||
SimpleLibrary
|
||||
├── lib/
|
||||
└── src/
|
||||
```
|
||||
|
||||
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:
|
||||
Now to generate cpp bindings
|
||||
```
|
||||
$ cd godot-cpp
|
||||
$ scons platform=<your platform> generate_bindings=yes
|
||||
$ scons godotbinpath="../godot_fork/bin/godot_binary" p=linux
|
||||
$ cd ..
|
||||
```
|
||||
resulting libraries will be placed under `bin/` and the generated headers will be placed under `include/*`
|
||||
|
||||
> Replace `<your platform>` with either `windows`, `linux` or `osx`.
|
||||
**Note:**
|
||||
> `generate_bindings=yes` is used to force regenerating C++ bindings (`godot_api.json` - Godot API)
|
||||
|
||||
> Include `use_llvm=yes` for using clang++
|
||||
|
||||
> Include `target=runtime` to build a runtime build (windows only at the moment)
|
||||
> You may need to specify `headers=../godot_headers` if you have compilation issues related to missing include files
|
||||
|
||||
> The resulting library will be created in `godot-cpp/bin/`, take note of its name as it will be different depending on platform.
|
||||
And our directory structure will be
|
||||
```
|
||||
godot-cpp
|
||||
└── bin/libgodot-cpp.a
|
||||
godot_headers
|
||||
SimpleLibrary
|
||||
├── lib/
|
||||
└── src/
|
||||
```
|
||||
|
||||
> 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
|
||||
# Creating simple class
|
||||
|
||||
Create `init.cpp` under `SimpleLibrary/src/` and add the following code
|
||||
```cpp
|
||||
#include <Godot.hpp>
|
||||
#include <core/Godot.hpp>
|
||||
#include <Reference.hpp>
|
||||
|
||||
using namespace godot;
|
||||
|
||||
class SimpleClass : public Reference {
|
||||
GODOT_CLASS(SimpleClass, Reference);
|
||||
class SimpleClass : public GodotScript<Reference> {
|
||||
GODOT_CLASS(SimpleClass);
|
||||
public:
|
||||
SimpleClass() { }
|
||||
SimpleClass() { }
|
||||
|
||||
/* _init must exist as it is called by Godot */
|
||||
void _init() { }
|
||||
void test_void_method() {
|
||||
Godot::print("This is test");
|
||||
}
|
||||
|
||||
void test_void_method() {
|
||||
Godot::print("This is test");
|
||||
}
|
||||
Variant method(Variant arg) {
|
||||
Variant ret;
|
||||
ret = arg;
|
||||
|
||||
Variant method(Variant arg) {
|
||||
Variant ret;
|
||||
ret = arg;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
static void _register_methods() {
|
||||
register_method("method", &SimpleClass::method);
|
||||
|
||||
/**
|
||||
* How to register exports like gdscript
|
||||
* export var _name = "SimpleClass"
|
||||
**/
|
||||
register_property((char *)"base/name", &SimpleClass::_name, String("SimpleClass"));
|
||||
|
||||
static void _register_methods() {
|
||||
register_method("method", &SimpleClass::method);
|
||||
|
||||
/**
|
||||
* How to register exports like gdscript
|
||||
* 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;
|
||||
}
|
||||
/** For registering signal **/
|
||||
// register_signal<SimpleClass>("signal_name");
|
||||
// register_signal<SimpleClass>("signal_name", "string_argument", GODOT_VARIANT_TYPE_STRING)
|
||||
}
|
||||
|
||||
String _name;
|
||||
};
|
||||
|
||||
/** 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);
|
||||
}
|
||||
|
||||
/** 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);
|
||||
}
|
||||
|
||||
/** 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::register_class<SimpleClass>();
|
||||
}
|
||||
```
|
||||
|
||||
### Compiling
|
||||
|
||||
*Linux*
|
||||
# Compiling
|
||||
```
|
||||
$ cd SimpleLibrary
|
||||
$ 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 bin/libtest.so -shared src/init.os -Lgodot-cpp/bin -l<name of the godot-cpp>
|
||||
$ clang -fPIC -o src/init.os -c src/init.cpp -g -O3 -std=c++14 -I../godot-cpp/include -Igodot_headers
|
||||
$ clang -o lib/libtest.so -shared src/init.os -L../godot-cpp/lib -lgodot-cpp
|
||||
```
|
||||
> This creates the file `libtest.so` in your `SimpleLibrary/bin` directory.
|
||||
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.
|
||||
|
||||
> 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
|
||||
# Creating `.gdns` file
|
||||
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
|
||||
var simpleclass = load("res://simpleclass.gdns").new();
|
||||
simpleclass.method("Test argument");
|
||||
|
||||
161
SConstruct
161
SConstruct
@@ -8,87 +8,95 @@ def add_sources(sources, dir, extension):
|
||||
if f.endswith('.' + extension):
|
||||
sources.append(dir + '/' + f)
|
||||
|
||||
# Try to detect the host platform automatically
|
||||
# This is used if no `platform` argument is passed
|
||||
if sys.platform.startswith('linux'):
|
||||
host_platform = 'linux'
|
||||
elif sys.platform == 'darwin':
|
||||
host_platform = 'osx'
|
||||
elif sys.platform == 'win32':
|
||||
host_platform = 'windows'
|
||||
else:
|
||||
raise ValueError('Could not detect platform automatically, please specify with platform=<platform>')
|
||||
|
||||
opts = Variables([], ARGUMENTS)
|
||||
|
||||
opts.Add(EnumVariable('platform', 'Target platform', host_platform, ('linux', 'osx', 'windows')))
|
||||
opts.Add(EnumVariable('bits', 'Target platform bits', 'default', ('default', '32', '64')))
|
||||
opts.Add(BoolVariable('use_llvm', 'Use the LLVM compiler - only effective when targeting Linux', False))
|
||||
opts.Add(BoolVariable('use_mingw', 'Use the MinGW compiler - only effective on Windows', False))
|
||||
# Must be the same setting as used for cpp_bindings
|
||||
opts.Add(EnumVariable('target', 'Compilation target', 'debug', ('debug', 'release')))
|
||||
opts.Add(PathVariable('headers_dir', 'Path to the directory containing Godot headers', 'godot_headers'))
|
||||
|
||||
env = Environment()
|
||||
host_platform = platform.system()
|
||||
target_platform = ARGUMENTS.get('p', ARGUMENTS.get('platform', 'linux'))
|
||||
target_arch = ARGUMENTS.get('a', ARGUMENTS.get('arch', '64'))
|
||||
# default to debug build, must be same setting as used for cpp_bindings
|
||||
target = ARGUMENTS.get('target', 'debug')
|
||||
# Local dependency paths, adapt them to your setup
|
||||
godot_headers = ARGUMENTS.get('headers', 'godot_headers')
|
||||
result_path = 'bin'
|
||||
result_name = ARGUMENTS.get('n', ARGUMENTS.get('name', os.path.relpath('.', '..')))
|
||||
opts.Update(env)
|
||||
Help(opts.GenerateHelpText(env))
|
||||
|
||||
# This makes sure to keep the session environment variables on Windows
|
||||
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find all the required tools
|
||||
if env['platform'] == 'windows':
|
||||
if env['bits'] == '64':
|
||||
env = Environment(TARGET_ARCH='amd64')
|
||||
elif env['bits'] == '32':
|
||||
env = Environment(TARGET_ARCH='x86')
|
||||
opts.Update(env)
|
||||
|
||||
if target_platform == 'linux' or platform == "x11":
|
||||
result_name += '.linux.' + target_arch
|
||||
is64 = sys.maxsize > 2**32
|
||||
if env['bits'] == 'default':
|
||||
env['bits'] = '64' if is64 else '32'
|
||||
|
||||
env['CXX']='g++'
|
||||
if ARGUMENTS.get('use_llvm', 'no') == 'yes':
|
||||
if env['platform'] == 'linux':
|
||||
if env['use_llvm']:
|
||||
env['CXX'] = 'clang++'
|
||||
|
||||
env.Append(CCFLAGS = [ '-fPIC', '-g', '-Og', '-std=c++14', '-Wwrite-strings' ])
|
||||
env.Append(LINKFLAGS = [ '-Wl,-R,\'$$ORIGIN\'' ])
|
||||
env.Append(CCFLAGS=['-fPIC', '-g', '-std=c++14', '-Wwrite-strings'])
|
||||
env.Append(LINKFLAGS=["-Wl,-R,'$$ORIGIN'"])
|
||||
|
||||
if target == 'debug':
|
||||
env.Append(CCFLAGS = ['-Og'])
|
||||
if env['target'] == 'debug':
|
||||
env.Append(CCFLAGS=['-Og'])
|
||||
elif env['target'] == 'release':
|
||||
env.Append(CCFLAGS=['-O3'])
|
||||
|
||||
if env['bits'] == '64':
|
||||
env.Append(CCFLAGS=['-m64'])
|
||||
env.Append(LINKFLAGS=['-m64'])
|
||||
elif env['bits'] == '32':
|
||||
env.Append(CCFLAGS=['-m32'])
|
||||
env.Append(LINKFLAGS=['-m32'])
|
||||
|
||||
elif env['platform'] == 'osx':
|
||||
if env['bits'] == '32':
|
||||
raise ValueError('Only 64-bit builds are supported for the macOS target.')
|
||||
|
||||
env.Append(CCFLAGS=['-g', '-std=c++14', '-arch', 'x86_64'])
|
||||
env.Append(LINKFLAGS=['-arch', 'x86_64', '-framework', 'Cocoa', '-Wl,-undefined,dynamic_lookup'])
|
||||
|
||||
if env['target'] == 'debug':
|
||||
env.Append(CCFLAGS=['-Og'])
|
||||
elif env['target'] == 'release':
|
||||
env.Append(CCFLAGS=['-O3'])
|
||||
|
||||
elif env['platform'] == 'windows':
|
||||
if host_platform == 'windows' and not env['use_mingw']:
|
||||
# MSVC
|
||||
env.Append(LINKFLAGS=['/WX'])
|
||||
if env['target'] == 'debug':
|
||||
env.Append(CCFLAGS=['/EHsc', '/D_DEBUG', '/MDd'])
|
||||
elif env['target'] == 'release':
|
||||
env.Append(CCFLAGS=['/O2', '/EHsc', '/DNDEBUG', '/MD'])
|
||||
else:
|
||||
env.Append(CCFLAGS = ['-O3'])
|
||||
# MinGW
|
||||
if env['bits'] == '64':
|
||||
env['CXX'] = 'x86_64-w64-mingw32-g++'
|
||||
elif env['bits'] == '32':
|
||||
env['CXX'] = 'i686-w64-mingw32-g++'
|
||||
|
||||
if target_arch == '32':
|
||||
env.Append(CCFLAGS = [ '-m32' ])
|
||||
env.Append(LINKFLAGS = [ '-m32' ])
|
||||
elif target_arch == '64':
|
||||
env.Append(CCFLAGS = [ '-m64' ])
|
||||
env.Append(LINKFLAGS = [ '-m64' ])
|
||||
|
||||
elif target_platform == '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
|
||||
if (target_arch == '64'):
|
||||
env = Environment(ENV = os.environ, TARGET_ARCH='amd64')
|
||||
else:
|
||||
env = Environment(ENV = os.environ, TARGET_ARCH='x86')
|
||||
|
||||
result_name += '.windows.' + target_arch
|
||||
|
||||
if host_platform == 'Windows':
|
||||
result_name += '.lib'
|
||||
|
||||
env.Append(LINKFLAGS = [ '/WX' ])
|
||||
if target == 'debug':
|
||||
env.Append(CCFLAGS = ['/EHsc', '/D_DEBUG', '/MDd' ])
|
||||
else:
|
||||
env.Append(CCFLAGS = ['/O2', '/EHsc', '/DNDEBUG', '/MD' ])
|
||||
else:
|
||||
if target_arch == '32':
|
||||
env['CXX']='i686-w64-mingw32-g++'
|
||||
elif target_arch == '64':
|
||||
env['CXX']='x86_64-w64-mingw32-g++'
|
||||
|
||||
env.Append(CCFLAGS = [ '-g', '-O3', '-std=c++14', '-Wwrite-strings' ])
|
||||
env.Append(LINKFLAGS = [ '--static', '-Wl,--no-undefined', '-static-libgcc', '-static-libstdc++' ])
|
||||
|
||||
elif target_platform == 'osx':
|
||||
if ARGUMENTS.get('use_llvm', 'no') == 'yes':
|
||||
env['CXX'] = 'clang++'
|
||||
|
||||
# Only 64-bits is supported for OS X
|
||||
target_arch = '64'
|
||||
result_name += '.osx.' + target_arch
|
||||
|
||||
env.Append(CCFLAGS = [ '-g','-O3', '-std=c++14', '-arch', 'x86_64' ])
|
||||
env.Append(LINKFLAGS = [ '-arch', 'x86_64', '-framework', 'Cocoa', '-Wl,-undefined,dynamic_lookup' ])
|
||||
else:
|
||||
print("The only supported targets are 'osx', 'linux' and 'windows'.")
|
||||
sys.exit(255)
|
||||
env.Append(CCFLAGS=['-g', '-O3', '-std=c++14', '-Wwrite-strings'])
|
||||
env.Append(LINKFLAGS=['--static', '-Wl,--no-undefined', '-static-libgcc', '-static-libstdc++'])
|
||||
|
||||
|
||||
env.Append(CPPPATH=['.', godot_headers, 'include', 'include/gen', 'include/core'])
|
||||
|
||||
# Generate bindings?
|
||||
json_api_file = ''
|
||||
env.Append(CPPPATH=['.', env['headers_dir'], 'include', 'include/core'])
|
||||
|
||||
# Generate bindings?
|
||||
json_api_file = ''
|
||||
@@ -96,21 +104,20 @@ json_api_file = ''
|
||||
if ARGUMENTS.get('use_custom_api_file', 'no') == 'yes':
|
||||
json_api_file = ARGUMENTS.get('custom_api_file', '')
|
||||
else:
|
||||
json_api_file = os.path.join(os.getcwd(), 'godot_headers', 'api.json')
|
||||
json_api_file = os.path.join(os.getcwd(), 'godot_api.json')
|
||||
|
||||
if ARGUMENTS.get('generate_bindings', 'no') == 'yes':
|
||||
# actually create the bindings here
|
||||
|
||||
# Actually create the bindings here
|
||||
|
||||
import binding_generator
|
||||
|
||||
binding_generator.generate_bindings(json_api_file)
|
||||
|
||||
|
||||
# source to compile
|
||||
sources = []
|
||||
add_sources(sources, 'src/core', 'cpp')
|
||||
add_sources(sources, 'src/gen', 'cpp')
|
||||
add_sources(sources, 'src', 'cpp')
|
||||
|
||||
|
||||
library = env.StaticLibrary(target=result_path + '/' + result_name, source=sources)
|
||||
library = env.StaticLibrary(
|
||||
target='bin/' + 'libgodot-cpp.{}.{}.{}'.format(env['platform'], env['target'], env['bits']), source=sources
|
||||
)
|
||||
Default(library)
|
||||
|
||||
@@ -21,22 +21,19 @@ def generate_bindings(path):
|
||||
|
||||
impl = generate_class_implementation(icalls, used_classes, c)
|
||||
|
||||
header_file = open("include/gen/" + strip_name(c["name"]) + ".hpp", "w+")
|
||||
header_file = open("include/" + strip_name(c["name"]) + ".hpp", "w+")
|
||||
header_file.write(header)
|
||||
|
||||
source_file = open("src/gen/" + strip_name(c["name"]) + ".cpp", "w+")
|
||||
source_file = open("src/" + strip_name(c["name"]) + ".cpp", "w+")
|
||||
source_file.write(impl)
|
||||
|
||||
|
||||
icall_header_file = open("src/gen/__icalls.hpp", "w+")
|
||||
icall_header_file = open("src/__icalls.hpp", "w+")
|
||||
icall_header_file.write(generate_icall_header(icalls))
|
||||
|
||||
icall_source_file = open("src/gen/__icalls.cpp", "w+")
|
||||
icall_source_file = open("src/__icalls.cpp", "w+")
|
||||
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):
|
||||
for c in classes:
|
||||
@@ -82,8 +79,6 @@ def generate_class_header(used_classes, c):
|
||||
# so don't include it here because it's not needed
|
||||
if class_name != "Object" and class_name != "Reference":
|
||||
source.append("#include <core/Ref.hpp>")
|
||||
else:
|
||||
source.append("#include <core/TagDB.hpp>")
|
||||
|
||||
|
||||
included = []
|
||||
@@ -105,6 +100,7 @@ def generate_class_header(used_classes, c):
|
||||
if c["base_class"] != "":
|
||||
source.append("#include \"" + strip_name(c["base_class"]) + ".hpp\"")
|
||||
|
||||
|
||||
|
||||
source.append("namespace godot {")
|
||||
source.append("")
|
||||
@@ -122,40 +118,15 @@ def generate_class_header(used_classes, c):
|
||||
vararg_templates = ""
|
||||
|
||||
# generate the class definition here
|
||||
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("class " + class_name + ("" if c["base_class"] == "" else (" : public " + strip_name(c["base_class"])) ) + " {")
|
||||
|
||||
source.append("public:")
|
||||
source.append("")
|
||||
|
||||
|
||||
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 char *___get_class_name() { return (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); }")
|
||||
source.append("\tstatic inline Object *___get_from_variant(Variant a) { return (Object *) a; }")
|
||||
|
||||
enum_values = []
|
||||
|
||||
@@ -175,26 +146,17 @@ def generate_class_header(used_classes, c):
|
||||
|
||||
|
||||
if c["instanciable"]:
|
||||
source.append("")
|
||||
source.append("")
|
||||
source.append("\tstatic " + class_name + " *_new();")
|
||||
source.append("\tstatic void *operator new(size_t);")
|
||||
|
||||
source.append("\tstatic void operator delete(void *);")
|
||||
|
||||
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"]:
|
||||
|
||||
method_signature = ""
|
||||
|
||||
# TODO decide what to do about virtual methods
|
||||
# method_signature += "virtual " if method["is_virtual"] else ""
|
||||
method_signature += "static " if c["singleton"] else ""
|
||||
method_signature += make_gdnative_type(method["return_type"])
|
||||
method_name = escape_cpp(method["name"])
|
||||
method_signature += method_name + "("
|
||||
@@ -262,7 +224,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"""
|
||||
method_signature += "const Array& __var_args = Array()"
|
||||
|
||||
method_signature += ")" + (" const" if method["is_const"] else "")
|
||||
method_signature += ")" + (" const" if method["is_const"] and not c["singleton"] else "")
|
||||
|
||||
|
||||
source.append("\t" + method_signature + ";")
|
||||
@@ -272,10 +234,11 @@ def generate_class_header(used_classes, c):
|
||||
source.append("")
|
||||
|
||||
|
||||
|
||||
source.append("}")
|
||||
source.append("")
|
||||
|
||||
|
||||
|
||||
source.append("#endif")
|
||||
|
||||
|
||||
@@ -316,20 +279,23 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||
source.append("namespace godot {")
|
||||
|
||||
|
||||
core_object_name = "this"
|
||||
core_object_name = ("___static_object_" + strip_name(c["name"])) if c["singleton"] else "this"
|
||||
|
||||
|
||||
source.append("")
|
||||
source.append("")
|
||||
|
||||
|
||||
if c["singleton"]:
|
||||
source.append("" + class_name + " *" + class_name + "::_singleton = NULL;")
|
||||
source.append("static godot_object *" + core_object_name + ";")
|
||||
source.append("")
|
||||
source.append("")
|
||||
|
||||
# FIXME Test if inlining has a huge impact on binary size
|
||||
source.append(class_name + "::" + class_name + "() {")
|
||||
source.append("\t_owner = godot::api->godot_global_get_singleton((char *) \"" + strip_name(c["name"]) + "\");")
|
||||
source.append("static inline void ___singleton_init()")
|
||||
source.append("{")
|
||||
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("")
|
||||
@@ -338,14 +304,18 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||
|
||||
|
||||
if c["instanciable"]:
|
||||
source.append(class_name + " *" + strip_name(c["name"]) + "::_new()")
|
||||
source.append("void *" + strip_name(c["name"]) + "::operator new(size_t)")
|
||||
source.append("{")
|
||||
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("\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((godot_object *)ptr);")
|
||||
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"]) + "("
|
||||
@@ -362,23 +332,20 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||
method_signature += ", "
|
||||
method_signature += "const Array& __var_args"
|
||||
|
||||
method_signature += ")" + (" const" if method["is_const"] else "")
|
||||
method_signature += ")" + (" const" if method["is_const"] and not c["singleton"] 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}")
|
||||
|
||||
|
||||
if c["singleton"]:
|
||||
source.append("\t___singleton_init();")
|
||||
|
||||
|
||||
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 = ""
|
||||
|
||||
@@ -441,17 +408,10 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||
source.append("")
|
||||
|
||||
source.append("\tVariant __result;")
|
||||
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("\t*(godot_variant *) &__result = godot::api->godot_method_bind_call(mb, (godot_object *) " + core_object_name + ", (const godot_variant **) __args, " + size + ", nullptr);")
|
||||
|
||||
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) + "]);")
|
||||
@@ -464,7 +424,7 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||
if is_reference_type(method["return_type"]):
|
||||
cast += "Ref<" + strip_name(method["return_type"]) + ">::__internal_constructor(__result);"
|
||||
else:
|
||||
cast += "(" + strip_name(method["return_type"]) + " *) " + strip_name(method["return_type"] + "::___get_from_variant(") + "__result);"
|
||||
cast += "(" + strip_name(method["return_type"]) + " *) (Object *) __result;"
|
||||
else:
|
||||
cast += "__result;"
|
||||
source.append("\treturn " + cast)
|
||||
@@ -485,7 +445,7 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||
|
||||
icall_name = get_icall_name(icall_sig)
|
||||
|
||||
return_statement += icall_name + "(mb, (const Object *) " + core_object_name
|
||||
return_statement += icall_name + "(mb, (godot_object *) " + core_object_name
|
||||
|
||||
for arg in method["arguments"]:
|
||||
return_statement += ", " + escape_cpp(arg["name"]) + (".ptr()" if is_reference_type(arg["type"]) else "")
|
||||
@@ -534,7 +494,7 @@ def generate_icall_header(icalls):
|
||||
|
||||
method_signature = ""
|
||||
|
||||
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, const Object *inst"
|
||||
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, godot_object *inst"
|
||||
|
||||
for arg in args:
|
||||
method_signature += ", const "
|
||||
@@ -587,7 +547,7 @@ def generate_icall_implementation(icalls):
|
||||
|
||||
method_signature = ""
|
||||
|
||||
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, const Object *inst"
|
||||
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, godot_object *inst"
|
||||
|
||||
for i, arg in enumerate(args):
|
||||
method_signature += ", const "
|
||||
@@ -608,7 +568,7 @@ def generate_icall_implementation(icalls):
|
||||
source.append(method_signature + " {")
|
||||
|
||||
if ret_type != "void":
|
||||
source.append("\t" + ("godot_object *" if is_class_type(ret_type) else return_type(ret_type)) + "ret;")
|
||||
source.append("\t" + return_type(ret_type) + "ret;")
|
||||
if is_class_type(ret_type):
|
||||
source.append("\tret = nullptr;")
|
||||
|
||||
@@ -621,7 +581,7 @@ def generate_icall_implementation(icalls):
|
||||
if is_primitive(arg) or is_core_type(arg):
|
||||
wrapped_argument += "(void *) &arg" + str(i)
|
||||
else:
|
||||
wrapped_argument += "(void *) arg" + str(i) + "->_owner"
|
||||
wrapped_argument += "(void *) arg" + str(i)
|
||||
|
||||
wrapped_argument += ","
|
||||
source.append(wrapped_argument)
|
||||
@@ -629,17 +589,10 @@ def generate_icall_implementation(icalls):
|
||||
source.append("\t};")
|
||||
source.append("")
|
||||
|
||||
source.append("\tgodot::api->godot_method_bind_ptrcall(mb, inst->_owner, args, " + ("nullptr" if ret_type == "void" else "&ret") + ");")
|
||||
source.append("\tgodot::api->godot_method_bind_ptrcall(mb, inst, args, " + ("nullptr" if ret_type == "void" else "&ret") + ");")
|
||||
|
||||
if ret_type != "void":
|
||||
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("\treturn ret;")
|
||||
|
||||
source.append("}")
|
||||
|
||||
@@ -651,44 +604,8 @@ 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)
|
||||
|
||||
|
||||
|
||||
@@ -747,8 +664,6 @@ def get_used_classes(c):
|
||||
|
||||
|
||||
def strip_name(name):
|
||||
if len(name) == 0:
|
||||
return name
|
||||
if name[0] == '_':
|
||||
return name[1:]
|
||||
return name
|
||||
|
||||
Submodule godot_headers updated: 32aa216bab...2d221de20c
@@ -21,7 +21,5 @@
|
||||
#include "Vector2.hpp"
|
||||
#include "Vector3.hpp"
|
||||
|
||||
#include "Wrapped.hpp"
|
||||
|
||||
|
||||
#endif // CORETYPES_H
|
||||
|
||||
@@ -107,45 +107,32 @@ typedef float real_t;
|
||||
#define _PLANE_EQ_DOT_EPSILON 0.999
|
||||
#define _PLANE_EQ_D_EPSILON 0.0001
|
||||
|
||||
// ERR/WARN macros
|
||||
#ifndef WARN_PRINT
|
||||
#define WARN_PRINT(msg) fprintf(stdout, "ERROR: %s\n", msg); fflush(stdout)
|
||||
#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
|
||||
#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)
|
||||
#define ERR_FAIL_COND_V(cond, ret) do { if (cond) { return ret; } } while(0)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ERR_FAIL_V
|
||||
#define ERR_FAIL_V(a) return a
|
||||
#endif
|
||||
|
||||
#ifndef ERR_FAIL_INDEX
|
||||
#define ERR_FAIL_INDEX(a, b) do { if (a < 0 || a >= b) { ERR_FAIL(); return; } } while(0)
|
||||
#define ERR_FAIL_INDEX(a, b)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ERR_PRINT
|
||||
#define ERR_PRINT(msg) fprintf(stderr, "ERROR: %S\n", (msg).unicode_str())
|
||||
#endif
|
||||
|
||||
#ifndef ERR_FAIL_INDEX_V
|
||||
#define ERR_FAIL_INDEX_V(a, b, c) do { if (a < 0 || a >= b) { ERR_FAIL(); return c; } } while(0)
|
||||
#define ERR_FAIL_INDEX_V(a, b, c)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ERR_FAIL_COND
|
||||
#define ERR_FAIL_COND(a) do { if (a) { fprintf(stderr, #a); return; } } while(0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -6,52 +6,60 @@
|
||||
|
||||
#include <gdnative_api_struct.gen.h>
|
||||
#include <nativescript/godot_nativescript.h>
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
#include "CoreTypes.hpp"
|
||||
#include "Variant.hpp"
|
||||
#include "Ref.hpp"
|
||||
#include "TagDB.hpp"
|
||||
|
||||
#include "Object.hpp"
|
||||
|
||||
#include "GodotGlobal.hpp"
|
||||
|
||||
#include <NativeScript.hpp>
|
||||
#include <GDNativeLibrary.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
|
||||
template<class T>
|
||||
T *as(const Object *obj)
|
||||
T *as(Object *obj)
|
||||
{
|
||||
return (T *) godot::nativescript_api->godot_nativescript_get_userdata(obj->_owner);
|
||||
return (T *) godot::nativescript_api->godot_nativescript_get_userdata(obj);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
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, Base) \
|
||||
|
||||
#define GODOT_CLASS(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:
|
||||
|
||||
#define GODOT_SUBCLASS(Name, Base) \
|
||||
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; } \
|
||||
inline static Object *___get_from_variant(godot::Variant a) { return (godot::Object *) godot::as<Name>(godot::Object::___get_from_variant(a)); } \
|
||||
inline static const char *___get_base_type_name() { return static_cast<const char *>(#Base); } \
|
||||
private:
|
||||
|
||||
|
||||
template<class T>
|
||||
struct _ArgCast {
|
||||
static T _arg_cast(Variant a)
|
||||
@@ -86,8 +94,7 @@ template<class T>
|
||||
void *_godot_class_instance_func(godot_object *p, void *method_data)
|
||||
{
|
||||
T *d = new T();
|
||||
d->_owner = p;
|
||||
d->_type_tag = typeid(T).hash_code();
|
||||
*(godot_object **) &d->owner = p;
|
||||
d->_init();
|
||||
return d;
|
||||
}
|
||||
@@ -109,10 +116,8 @@ void register_class()
|
||||
godot_instance_destroy_func destroy = {};
|
||||
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_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();
|
||||
}
|
||||
|
||||
@@ -125,10 +130,8 @@ void register_tool_class()
|
||||
godot_instance_destroy_func destroy = {};
|
||||
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_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();
|
||||
}
|
||||
|
||||
@@ -366,7 +369,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);
|
||||
|
||||
if (def_val.get_type() == Variant::OBJECT) {
|
||||
Object *o = get_wrapper<Object>(def_val.operator godot_object*());
|
||||
Object *o = def_val;
|
||||
if (o && o->is_class("Resource")) {
|
||||
hint = (godot_property_hint) ((int) hint | GODOT_PROPERTY_HINT_RESOURCE_TYPE);
|
||||
hint_string = o->get_class();
|
||||
@@ -487,35 +490,6 @@ void register_signal(String name, Args... 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
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
#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 {
|
||||
|
||||
@@ -23,7 +21,6 @@ public:
|
||||
static void gdnative_init(godot_gdnative_init_options *o);
|
||||
static void gdnative_terminate(godot_gdnative_terminate_options *o);
|
||||
static void nativescript_init(void *handle);
|
||||
static void nativescript_terminate(void *handle);
|
||||
|
||||
template <class... Args>
|
||||
static void print(const String& fmt, Args... values) {
|
||||
@@ -35,7 +32,6 @@ public:
|
||||
|
||||
struct _RegisterState {
|
||||
static void *nativescript_handle;
|
||||
static int language_index;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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 *) T::___get_from_variant(p_variant);
|
||||
Reference *refb = (Reference *) (Object *) p_variant;
|
||||
if (!refb) {
|
||||
unref();
|
||||
return;
|
||||
@@ -156,7 +156,7 @@ public:
|
||||
|
||||
reference = nullptr;
|
||||
// TODO We need a safe cast
|
||||
Reference *refb = (Reference *) T::___get_from_variant(p_variant);
|
||||
Reference *refb = (Reference *) (Object *) p_variant;
|
||||
if (!refb) {
|
||||
unref();
|
||||
return;
|
||||
@@ -180,14 +180,14 @@ public:
|
||||
if (reference && reference->unreference()) {
|
||||
|
||||
//memdelete(reference);
|
||||
reference->free();
|
||||
delete reference;
|
||||
}
|
||||
reference = nullptr;
|
||||
}
|
||||
|
||||
void instance() {
|
||||
//ref(memnew(T));
|
||||
ref(T::_new());
|
||||
ref(new T);
|
||||
}
|
||||
|
||||
Ref() {
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace godot {
|
||||
class NodePath;
|
||||
class Variant;
|
||||
class PoolByteArray;
|
||||
class PoolIntArray;
|
||||
class PoolRealArray;
|
||||
class PoolStringArray;
|
||||
class String;
|
||||
@@ -121,7 +120,6 @@ public:
|
||||
String sha256_text() const;
|
||||
float similarity(String text) 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;
|
||||
String strip_edges(bool left = true, bool right = true) const;
|
||||
String substr(int from, int len) const;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#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 RID() const;
|
||||
operator godot_object*() const;
|
||||
operator Object*() const;
|
||||
|
||||
operator Dictionary() const;
|
||||
operator Array() const;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
class Basis;
|
||||
|
||||
struct Vector3 {
|
||||
|
||||
@@ -80,8 +79,6 @@ struct Vector3 {
|
||||
|
||||
Vector3 cubic_interpolate(const Vector3& b, const Vector3& pre_a, const Vector3& post_b, const real_t t) const;
|
||||
|
||||
Vector3 bounce(const Vector3& p_normal) const;
|
||||
|
||||
real_t length() const;
|
||||
|
||||
real_t length_squared() const;
|
||||
@@ -92,15 +89,11 @@ struct Vector3 {
|
||||
|
||||
real_t dot(const Vector3& b) const;
|
||||
|
||||
real_t angle_to(const Vector3& b) const;
|
||||
|
||||
Vector3 floor() const;
|
||||
|
||||
Vector3 inverse() const;
|
||||
|
||||
bool is_normalized() const;
|
||||
|
||||
Basis outer(const Vector3& b) const;
|
||||
|
||||
|
||||
int max_axis() const;
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#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
|
||||
2
include/gen/.gitignore
vendored
2
include/gen/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -269,7 +269,7 @@ Color Color::html(const String& p_color)
|
||||
} else if (color.length()==6) {
|
||||
alpha=false;
|
||||
} else {
|
||||
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||
ERR_PRINT(String("Invalid Color Code: ") + p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ Color Color::html(const String& p_color)
|
||||
if (alpha) {
|
||||
a=_parse_col(color,0);
|
||||
if (a<0) {
|
||||
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||
ERR_PRINT("Invalid Color Code: "+p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
}
|
||||
@@ -286,17 +286,17 @@ Color Color::html(const String& p_color)
|
||||
|
||||
int r=_parse_col(color,from+0);
|
||||
if (r<0) {
|
||||
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||
ERR_PRINT("Invalid Color Code: "+p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
int g=_parse_col(color,from+2);
|
||||
if (g<0) {
|
||||
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||
ERR_PRINT("Invalid Color Code: "+p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
int b=_parse_col(color,from+4);
|
||||
if (b<0) {
|
||||
ERR_PRINTS(String("Invalid Color Code: ") + p_color);
|
||||
ERR_PRINT("Invalid Color Code: "+p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
|
||||
|
||||
@@ -2,35 +2,11 @@
|
||||
|
||||
#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 {
|
||||
|
||||
void *_RegisterState::nativescript_handle;
|
||||
int _RegisterState::language_index;
|
||||
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)
|
||||
{
|
||||
@@ -71,33 +47,19 @@ void Godot::print_error(const String& description, const String& function, const
|
||||
if (c_file != nullptr) godot::api->godot_free(c_file);
|
||||
}
|
||||
|
||||
void ___register_types();
|
||||
|
||||
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++) {
|
||||
switch (godot::api->extensions[i]->type) {
|
||||
case GDNATIVE_EXT_NATIVESCRIPT: {
|
||||
godot::nativescript_api = (const godot_gdnative_ext_nativescript_api_struct *)godot::api->extensions[i];
|
||||
|
||||
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;
|
||||
case GDNATIVE_EXT_NATIVESCRIPT: {
|
||||
godot::nativescript_api = (godot_gdnative_ext_nativescript_api_struct *)godot::api->extensions[i];
|
||||
}; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
void Godot::gdnative_terminate(godot_gdnative_terminate_options *options)
|
||||
@@ -108,19 +70,6 @@ void Godot::gdnative_terminate(godot_gdnative_terminate_options *options)
|
||||
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);
|
||||
|
||||
___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 {
|
||||
godot_array arr = godot::api->godot_string_bigrams(&_godot_string);
|
||||
|
||||
return *(Array *)&arr;
|
||||
return *(PoolStringArray *)&arr;
|
||||
}
|
||||
|
||||
String String::c_escape() const {
|
||||
@@ -479,19 +479,13 @@ float String::similarity(String text) const {
|
||||
PoolStringArray String::split(String divisor, bool allow_empty) const {
|
||||
godot_array arr = godot::api->godot_string_split(&_godot_string, &divisor._godot_string);
|
||||
|
||||
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;
|
||||
return *(PoolStringArray *)&arr;
|
||||
}
|
||||
|
||||
PoolRealArray String::split_floats(String divisor, bool allow_empty) const {
|
||||
godot_array arr = godot::api->godot_string_split_floats(&_godot_string, &divisor._godot_string);
|
||||
|
||||
return *(Array *)&arr;
|
||||
return *(PoolRealArray *)&arr;
|
||||
}
|
||||
|
||||
String String::strip_edges(bool left, bool right) const {
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#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,7 +5,6 @@
|
||||
#include "Defs.hpp"
|
||||
#include "CoreTypes.hpp"
|
||||
#include "GodotGlobal.hpp"
|
||||
#include "Object.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -142,7 +141,7 @@ Variant::Variant(const RID& p_rid)
|
||||
|
||||
Variant::Variant(const Object* p_object)
|
||||
{
|
||||
godot::api->godot_variant_new_object(&_godot_variant, p_object->_owner);
|
||||
godot::api->godot_variant_new_object(&_godot_variant, (godot_object *) p_object);
|
||||
}
|
||||
|
||||
Variant::Variant(const Dictionary& p_dictionary)
|
||||
@@ -364,8 +363,9 @@ Variant::operator PoolColorArray() const
|
||||
godot_pool_color_array s = godot::api->godot_variant_as_pool_color_array(&_godot_variant);
|
||||
return *(PoolColorArray *) &s;
|
||||
}
|
||||
Variant::operator godot_object*() const {
|
||||
return godot::api->godot_variant_as_object(&_godot_variant);
|
||||
Variant::operator Object*() const {
|
||||
godot_object *o = godot::api->godot_variant_as_object(&_godot_variant);
|
||||
return (Object *) o;
|
||||
}
|
||||
|
||||
Variant::Type Variant::get_type() const
|
||||
|
||||
@@ -81,7 +81,7 @@ void Vector2::normalize()
|
||||
{
|
||||
real_t l = x*x + y*y;
|
||||
if (l != 0) {
|
||||
l = (l);
|
||||
l = sqrt(l);
|
||||
x /= l;
|
||||
y /= l;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
#include "String.hpp"
|
||||
|
||||
#include "Basis.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Basis.hpp"
|
||||
|
||||
namespace godot {
|
||||
|
||||
|
||||
@@ -209,11 +209,6 @@ Vector3 Vector3::cubic_interpolate(const Vector3& b, const Vector3& pre_a, const
|
||||
return out;
|
||||
}
|
||||
|
||||
Vector3 Vector3::bounce(const Vector3& p_normal) const
|
||||
{
|
||||
return -reflect(p_normal);
|
||||
}
|
||||
|
||||
real_t Vector3::length() const
|
||||
{
|
||||
real_t x2=x*x;
|
||||
@@ -234,12 +229,12 @@ real_t Vector3::length_squared() const
|
||||
|
||||
real_t Vector3::distance_squared_to(const Vector3& b) const
|
||||
{
|
||||
return (b-*this).length_squared();
|
||||
return (b-*this).length();
|
||||
}
|
||||
|
||||
real_t Vector3::distance_to(const Vector3& b) const
|
||||
{
|
||||
return (b-*this).length();
|
||||
return (b-*this).length_squared();
|
||||
}
|
||||
|
||||
real_t Vector3::dot(const Vector3& b) const
|
||||
@@ -247,11 +242,6 @@ real_t Vector3::dot(const Vector3& b) const
|
||||
return x*b.x + y*b.y + z*b.z;
|
||||
}
|
||||
|
||||
real_t Vector3::angle_to(const Vector3& b) const
|
||||
{
|
||||
return std::atan2(cross(b).length(), dot(b));
|
||||
}
|
||||
|
||||
Vector3 Vector3::floor() const
|
||||
{
|
||||
return Vector3(::floor(x), ::floor(y), ::floor(z));
|
||||
@@ -262,19 +252,7 @@ Vector3 Vector3::inverse() const
|
||||
return Vector3( 1.0/x, 1.0/y, 1.0/z );
|
||||
}
|
||||
|
||||
bool Vector3::is_normalized() const
|
||||
{
|
||||
return std::abs(length_squared() - 1.0) < 0.00001;
|
||||
}
|
||||
|
||||
Basis Vector3::outer(const Vector3& b) const
|
||||
{
|
||||
Vector3 row0(x * b.x, x * b.y, x * b.z);
|
||||
Vector3 row1(y * b.x, y * b.y, y * b.z);
|
||||
Vector3 row2(z * b.x, z * b.y, z * b.z);
|
||||
|
||||
return Basis(row0, row1, row2);
|
||||
}
|
||||
|
||||
|
||||
int Vector3::max_axis() const
|
||||
|
||||
2
src/gen/.gitignore
vendored
2
src/gen/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
Reference in New Issue
Block a user