summaryrefslogtreecommitdiff
path: root/modules/gdnative/SCsub
blob: ba4163aab7138ebcff379c84651ef0aa3dd952d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python

Import('env')

gdn_env = env.Clone()

gdn_env.add_source_files(env.modules_sources, "gd_native_library_editor.cpp")
gdn_env.add_source_files(env.modules_sources, "gdnative.cpp")
gdn_env.add_source_files(env.modules_sources, "register_types.cpp")
gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp")
gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp")

gdn_env.Append(CPPPATH=['#modules/gdnative/include/'])

SConscript("nativearvr/SCsub")

def _spaced(e):
    return e if e[-1] == '*' else e + ' '

def _build_gdnative_api_struct_header(api):
    out = [
        '/* THIS FILE IS GENERATED DO NOT EDIT */',
        '#ifndef GODOT_GDNATIVE_API_STRUCT_H',
        '#define GODOT_GDNATIVE_API_STRUCT_H',
        '',
        '#include <gdnative/gdnative.h>',
        '#include <nativearvr/godot_nativearvr.h>',
        '#include <nativescript/godot_nativescript.h>',
        '',
        '#define GDNATIVE_API_INIT(options) do { extern const godot_gdnative_api_struct *_gdnative_wrapper_api_struct; _gdnative_wrapper_api_struct = options->api_struct; } while (0)',
        '',
        '#ifdef __cplusplus',
        'extern "C" {',
        '#endif',
        '',
        'typedef struct godot_gdnative_api_struct {',
        '\tvoid *next;',
        '\tconst char *version;',
    ]

    for funcdef in api['api']:
        args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
        out.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args))

    out += [
        '} godot_gdnative_api_struct;',
        '',
        '#ifdef __cplusplus',
        '}',
        '#endif',
        '',
        '#endif // GODOT_GDNATIVE_API_STRUCT_H',
        ''
    ]
    return '\n'.join(out)

def _build_gdnative_api_struct_source(api):
    out = [
        '/* THIS FILE IS GENERATED DO NOT EDIT */',
        '',
        '#include <gdnative_api_struct.gen.h>',
        '',
        'const char *_gdnative_api_version = "%s";' % api['version'],
        'extern const godot_gdnative_api_struct api_struct = {',
        '\tNULL,',
        '\t_gdnative_api_version,',
    ]

    for funcdef in api['api']:
        out.append('\t%s,' % funcdef['name'])
    out.append('};\n')

    return '\n'.join(out)

def build_gdnative_api_struct(target, source, env):
    import json
    from collections import OrderedDict

    with open(source[0].path, 'r') as fd:
        api = json.load(fd)

    header, source = target
    with open(header.path, 'w') as fd:
        fd.write(_build_gdnative_api_struct_header(api))
    with open(source.path, 'w') as fd:
        fd.write(_build_gdnative_api_struct_source(api))

_, gensource = gdn_env.Command(['include/gdnative_api_struct.gen.h', 'gdnative_api_struct.gen.cpp'],
                               'gdnative_api.json', build_gdnative_api_struct)
gdn_env.add_source_files(env.modules_sources, [gensource])

env.use_ptrcall = True


def _build_gdnative_wrapper_code(api):
    out = [
        '/* THIS FILE IS GENERATED DO NOT EDIT */',
        '',
        '#include <gdnative/gdnative.h>',
        '#include <nativescript/godot_nativescript.h>',
        '',
        '#include <gdnative_api_struct.gen.h>',
        '',
        'godot_gdnative_api_struct *_gdnative_wrapper_api_struct = 0;',
        '',
        '#ifdef __cplusplus',
        'extern "C" {',
        '#endif',
        ''
    ]

    for funcdef in api['api']:
        args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
        out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args))

        args = ', '.join(['%s' % n for t, n in funcdef['arguments']])

        return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t'
        return_line += '_gdnative_wrapper_api_struct->' + funcdef['name'] + '(' + args + ');'

        out.append(return_line)
        out.append('}')
        out.append('')

    out += [
        '#ifdef __cplusplus',
        '}',
        '#endif'
    ]

    return '\n'.join(out)


def build_gdnative_wrapper_code(target, source, env):
    import json
    with open(source[0].path, 'r') as fd:
        api = json.load(fd)

    wrapper_file = target[0]
    with open(wrapper_file.path, 'w') as fd:
        fd.write(_build_gdnative_wrapper_code(api))



if ARGUMENTS.get('gdnative_wrapper', False):
    #build wrapper code
    gensource, = gdn_env.Command('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', build_gdnative_wrapper_code)

    gd_wrapper_env = env.Clone()
    gd_wrapper_env.Append(CPPPATH=['#modules/gdnative/include/'])

    # I think this doesn't work on MSVC yet...
    gd_wrapper_env.Append(CCFLAGS=['-fPIC'])

    gd_wrapper_env.Library("#bin/gdnative_wrapper_code", [gensource])