mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 13:41:03 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			256 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			256 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/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("arvr/SCsub")
 | |
| SConscript("pluginscript/SCsub")
 | |
| 
 | |
| def _spaced(e):
 | |
|     return e if e[-1] == '*' else e + ' '
 | |
| 
 | |
| def _build_gdnative_api_struct_header(api):
 | |
|     ext_wrappers = ''
 | |
| 
 | |
|     for name in api['extensions']:
 | |
|         ext_wrappers += ' extern const godot_gdnative_ext_' + name + '_api_struct *_gdnative_wrapper_' + name + '_api_struct;'
 | |
| 
 | |
|     ext_init = 'for (int i = 0; i < _gdnative_wrapper_api_struct->num_extensions; i++) { '
 | |
|     ext_init += 'switch (_gdnative_wrapper_api_struct->extensions[i]->type) {'
 | |
| 
 | |
|     for name in api['extensions']:
 | |
|         ext_init += 'case GDNATIVE_EXT_' + api['extensions'][name]['type'] + ': '
 | |
|         ext_init += '_gdnative_wrapper_' + name + '_api_struct = (' + 'godot_gdnative_ext_' + name + '_api_struct *) _gdnative_wrapper_api_struct->extensions[i]; break;'
 | |
| 
 | |
|     ext_init += '}'
 | |
| 
 | |
|     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 <arvr/godot_arvr.h>',
 | |
|         '#include <nativescript/godot_nativescript.h>',
 | |
|         '#include <pluginscript/godot_pluginscript.h>',
 | |
|         '',
 | |
|         '#define GDNATIVE_API_INIT(options) do { extern const godot_gdnative_api_struct *_gdnative_wrapper_api_struct;' + ext_wrappers + ' _gdnative_wrapper_api_struct = options->api_struct; ' + ext_init + ' } while (0)',
 | |
|         '',
 | |
|         '#ifdef __cplusplus',
 | |
|         'extern "C" {',
 | |
|         '#endif',
 | |
|         '',
 | |
|         'typedef struct godot_gdnative_api_version {',
 | |
|         '\tunsigned int major;',
 | |
|         '\tunsigned int minor;',
 | |
|         '} godot_gdnative_api_version;',
 | |
|         '',
 | |
|         'typedef struct godot_gdnative_api_struct godot_gdnative_api_struct;',
 | |
|         '',
 | |
|         'struct godot_gdnative_api_struct {',
 | |
|         '\tunsigned int type;',
 | |
|         '\tgodot_gdnative_api_version version;',
 | |
|         '\tconst godot_gdnative_api_struct *next;',
 | |
|         '};',
 | |
|         '',
 | |
|         'enum GDNATIVE_API_TYPES {',
 | |
|         '\tGDNATIVE_' + api['core']['type'] + ','
 | |
|     ]
 | |
| 
 | |
|     for name in api['extensions']:
 | |
|         out += ['\tGDNATIVE_EXT_' + api['extensions'][name]['type'] + ',']
 | |
| 
 | |
|     out += ['};', '']
 | |
| 
 | |
|     for name in api['extensions']:
 | |
|         out += [
 | |
|             'typedef struct godot_gdnative_ext_' + name + '_api_struct {',
 | |
|             '\tunsigned int type;',
 | |
|             '\tgodot_gdnative_api_version version;',
 | |
|             '\tconst godot_gdnative_api_struct *next;'
 | |
|         ]
 | |
| 
 | |
|         for funcdef in api['extensions'][name]['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_ext_' + name + '_api_struct;', '']
 | |
| 
 | |
|     out += [
 | |
|         'typedef struct godot_gdnative_core_api_struct {',
 | |
|         '\tunsigned int type;',
 | |
|         '\tgodot_gdnative_api_version version;',
 | |
|         '\tconst godot_gdnative_api_struct *next;',
 | |
|         '\tunsigned int num_extensions;',
 | |
|         '\tconst godot_gdnative_api_struct **extensions;',
 | |
|     ]
 | |
| 
 | |
|     for funcdef in api['core']['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_core_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>',
 | |
|         ''
 | |
|     ]
 | |
| 
 | |
|     for name in api['extensions']:
 | |
|         out += [
 | |
|             'extern const godot_gdnative_ext_' + name + '_api_struct api_extension_' + name + '_struct = {',
 | |
|             '\tGDNATIVE_EXT_' + api['extensions'][name]['type'] + ',',
 | |
|             '\t{' + str(api['extensions'][name]['version']['major']) + ', ' + str(api['extensions'][name]['version']['minor']) + '},',
 | |
|             '\tNULL,'
 | |
|         ]
 | |
| 
 | |
|         for funcdef in api['extensions'][name]['api']:
 | |
|             out.append('\t%s,' % funcdef['name'])
 | |
| 
 | |
|         out += ['};\n']
 | |
| 
 | |
|     out += ['', 'const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {']
 | |
| 
 | |
|     for name in api['extensions']:
 | |
|         out += ['\t(godot_gdnative_api_struct *)&api_extension_' + name + '_struct,']
 | |
| 
 | |
|     out += ['};\n']
 | |
| 
 | |
|     out += [
 | |
|         'extern const godot_gdnative_core_api_struct api_struct = {',
 | |
|         '\tGDNATIVE_' + api['core']['type'] + ',',
 | |
|         '\t{' + str(api['core']['version']['major']) + ', ' + str(api['core']['version']['minor']) + '},',
 | |
|         '\tNULL,',
 | |
|         '\t' + str(len(api['extensions'])) + ',',
 | |
|         '\tgdnative_extensions_pointers,',
 | |
|     ]
 | |
| 
 | |
|     for funcdef in api['core']['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 <pluginscript/godot_pluginscript.h>',
 | |
|         '#include <arvr/godot_arvr.h>',
 | |
|         '',
 | |
|         '#include <gdnative_api_struct.gen.h>',
 | |
|         '',
 | |
|         '#ifdef __cplusplus',
 | |
|         'extern "C" {',
 | |
|         '#endif',
 | |
|         '',
 | |
|         'godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct = 0;',
 | |
|     ]
 | |
| 
 | |
|     for name in api['extensions']:
 | |
|         out.append('godot_gdnative_ext_' + name + '_api_struct *_gdnative_wrapper_' + name + '_api_struct;')
 | |
| 
 | |
|     out += ['']
 | |
| 
 | |
|     for funcdef in api['core']['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('')
 | |
| 
 | |
|     for name in api['extensions']:
 | |
|         for funcdef in api['extensions'][name]['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_' + name + '_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])
 | 
