Skip to content

Commit c6639af

Browse files
author
Vano
committed
resource loader/saver, deinit funcs
1 parent 3778b93 commit c6639af

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

cppscript.py

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def GlobRecursive(path, pattern, **kwargs):
4444
return found
4545

4646

47-
KEYWORDS = ['GPROPERTY', 'GMETHOD', 'GGROUP', 'GSUBGROUP', 'GBITFIELD', 'GSIGNAL', 'GRPC', 'GVARARG', 'GIGNORE', 'GBIND_METHODS_APPEND', 'GBIND_METHODS_PREPEND']
47+
KEYWORDS = ['GPROPERTY', 'GMETHOD', 'GGROUP', 'GSUBGROUP', 'GBITFIELD', 'GSIGNAL', 'GRPC', 'GVARARG', 'GIGNORE', 'GBIND_METHODS_APPEND', 'GBIND_METHODS_PREPEND', 'GRESOURCE_LOADER', 'GRESOURCE_SAVER']
4848
INIT_LEVELS = ['GINIT_LEVEL_CORE', 'GINIT_LEVEL_SERVERS', 'GINIT_LEVEL_SCENE', 'GINIT_LEVEL_EDITOR']
4949

5050
DONOTEDIT_MSG = "/*-- GENERATED FILE - DO NOT EDIT --*/\n\n"
@@ -488,10 +488,16 @@ def process_macros(item, macros, properties, is_ignored=False):
488488
is_ignored = True
489489

490490
case 'GBIND_METHODS_APPEND':
491-
class_defs['bind_methods_append'] += get_macro_body(filecontent, macro)
491+
class_defs['bind_methods_append'] += '\n' + get_macro_body(filecontent, macro) + '\n'
492492

493493
case 'GBIND_METHODS_PREPEND':
494-
class_defs['bind_methods_prepend'] += get_macro_body(filecontent, macro)
494+
class_defs['bind_methods_prepend'] += '\n' + get_macro_body(filecontent, macro) + '\n'
495+
496+
case 'GRESOURCE_LOADER':
497+
class_defs['is_resource_loader'] = True
498+
499+
case 'GRESOURCE_SAVER':
500+
class_defs['is_resource_saver'] = True
495501

496502

497503
return not is_ignored
@@ -541,7 +547,7 @@ def apply_macros(item, macros):
541547

542548
leftover = collapse_list(class_macros, lambda x: x.kind != CursorKind.MACRO_INSTANTIATION, apply_macros)
543549
for macro in leftover:
544-
if macro.spelling not in ['GSIGNAL', 'GGROUP', 'GSUBGROUP', 'GBIND_METHODS_APPEND', 'GBIND_METHODS_PREPEND'] + INIT_LEVELS:
550+
if macro.spelling not in ['GSIGNAL', 'GGROUP', 'GSUBGROUP', 'GBIND_METHODS_APPEND', 'GBIND_METHODS_PREPEND', 'GRESOURCE_LOADER', 'GRESOURCE_SAVER'] + INIT_LEVELS:
545551
raise CppScriptException('{}:{}:{}: error: macro without target member'
546552
.format(filename, macro.location.line, macro.location.column))
547553
process_macros(None, leftover, None)
@@ -561,6 +567,7 @@ def parse_and_write_header(index, filename, filecontent, env):
561567

562568
def write_header(file, defs, env):
563569
header_defs = []
570+
global_variables = []
564571
for class_name_full, content in defs.items():
565572
class_name = content['class_name']
566573
Hmethod, Hstatic_method, Hvirtual_method, Hvaragr_method, Hprop, Hsignal, Henum, Hbitfield, Hconst = '', '', '', '', '', '', '', '', ''
@@ -645,6 +652,13 @@ def write_header(file, defs, env):
645652
for const in content['constants']:
646653
Hconst += f'\tBIND_CONSTANT({const});\n'
647654

655+
if 'is_resource_loader' in content:
656+
variable_name = content["class_name"] + '_loader'
657+
global_variables.append(f'Ref<{class_name_full}> {variable_name};')
658+
elif 'is_resource_saver' in content:
659+
variable_name = content["class_name"] + '_saver'
660+
global_variables.append(f'Ref<{class_name_full}> {variable_name};')
661+
648662
header_rpc_config = 'void {}::_rpc_config() {{{}}}\n'.format(
649663
class_name_full, '\n' + header_rpc_config if header_rpc_config != '' else '')
650664
header_bind_methods = '\n\n'.join(i for i in [Hmethod, Hvirtual_method, Hstatic_method, Hvaragr_method, Hprop, Hsignal, Henum, Hbitfield, Hconst] if i != '')
@@ -660,7 +674,10 @@ def write_header(file, defs, env):
660674
gen_filename = filename_to_gen_filename(file, env)
661675
content = ''
662676
if len(defs) != 0:
663-
header_include = '#include <cppscript_bindings.h>\n\n#include "{}"\n\nusing namespace godot;\n\n'.format(os.path.relpath(file, os.path.dirname(gen_filename)).replace('\\', '/'))
677+
header_include = '#include <cppscript_bindings.h>\n\n#include "{}"\n\nusing namespace godot;\n\n{}' \
678+
.format(
679+
os.path.relpath(file, os.path.dirname(gen_filename)).replace('\\', '/'),
680+
('\n'.join(global_variables) + '\n\n' if global_variables != [] else ''))
664681
content = DONOTEDIT_MSG + header_include + '\n'.join(header_defs)
665682

666683
os.makedirs(os.path.dirname(gen_filename), exist_ok=True)
@@ -673,12 +690,33 @@ def write_register_header(defs_all, env):
673690
scripts_header = DONOTEDIT_MSG
674691
classes_register_levels = {name[12:] : [] for name in INIT_LEVELS}
675692

693+
loaders_savers = []
694+
def make_register_str_pair(class_name_full, content):
695+
register_str = f"\tGDREGISTER_{content['type']}({class_name_full});\n"
696+
unregister_str = ''
697+
698+
if 'is_resource_loader' in content:
699+
variable_name = f'{content["class_name"]}_loader'
700+
701+
loaders_savers.append(f'extern Ref<{class_name_full}> {variable_name};')
702+
register_str += f'\t{variable_name}.instantiate();\n\tResourceLoader::get_singleton()->add_resource_format_loader({variable_name});\n'
703+
unregister_str += f'\tResourceLoader::get_singleton()->remove_resource_format_loader({variable_name});\n\t{variable_name}.unref();\n'
704+
elif 'is_resource_saver' in content:
705+
variable_name = f'{content["class_name"]}_saver'
706+
707+
loaders_savers.append(f'extern Ref<{class_name_full}> {variable_name};\n')
708+
register_str += f'\t{variable_name}.instantiate();\n\tResourceSaver::get_singleton()->add_resource_format_saver({variable_name});\n'
709+
unregister_str += f'\tResourceSaver::get_singleton()->remove_resource_format_saver({variable_name});\n\t{variable_name}.unref();\n'
710+
711+
return register_str, unregister_str
712+
676713
for file, filecontent in defs_all['files'].items():
677714
classes = filecontent['content']
678715
if len(classes) == 0:
679716
continue
680717

681718
scripts_header += '#include "{}"\n'.format(os.path.relpath(file, os.path.dirname(target)).replace('\\', '/'))
719+
682720
for class_name_full, content in classes.items():
683721
# Ensure parent classes are registered before children
684722
# by iterating throught pairs of (base_name, register_str)
@@ -688,11 +726,15 @@ def write_register_header(defs_all, env):
688726
base = base if dots == -1 else base[dots+1:]
689727
for i in range(len(classes_register)):
690728
if class_name == classes_register[i][0]:
691-
classes_register.insert(i, (base, f"\tGDREGISTER_{content['type']}({class_name_full});\n"))
729+
classes_register.insert(i, (base, make_register_str_pair(class_name_full, content)))
692730
break
693731
else:
694-
classes_register.append((base, f"\tGDREGISTER_{content['type']}({class_name_full});\n"))
732+
classes_register.append((base, make_register_str_pair(class_name_full, content)))
733+
695734

735+
if loaders_savers != []:
736+
scripts_header += '#include <godot_cpp/classes/resource_loader.hpp>\n'
737+
scripts_header += '#include <godot_cpp/classes/resource_saver.hpp>\n'
696738

697739
classes_register_str = ''
698740
if classes_register_levels['CORE'] != []:
@@ -703,12 +745,19 @@ def write_register_header(defs_all, env):
703745
minimal_register_level = 'MODULE_INITIALIZATION_LEVEL_SCENE'
704746

705747
scripts_header += '\nusing namespace godot;\n\n' + \
706-
f'static const ModuleInitializationLevel DEFAULT_INIT_LEVEL = {minimal_register_level};\n\n'
748+
f'static const ModuleInitializationLevel DEFAULT_INIT_LEVEL = {minimal_register_level};\n\n' + \
749+
('\n'.join(loaders_savers) + '\n\n' if loaders_savers != [] else '')
750+
707751
for level_name, defs in classes_register_levels.items():
708-
registers = ''.join(i for _, i in defs)
752+
registers = ''.join(i[0] for _, i in defs)
753+
unregisters = ''.join(i[1] for _, i in defs)
754+
709755
classes_register_str += '_FORCE_INLINE_ void _register_level_{}() {{{}}}\n\n'.format(
710756
level_name.lower(), '\n' + registers if registers != '' else '')
711757

758+
classes_register_str += '_FORCE_INLINE_ void _unregister_level_{}() {{{}}}\n\n'.format(
759+
level_name.lower(), '\n' + unregisters if unregisters != '' else '')
760+
712761
scripts_header += classes_register_str
713762

714763
new_hash = hashlib.md5(scripts_header.encode()).hexdigest()

src/cppscript_defs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,7 @@ void function(decltype(property) value) { \
5050
#define GINIT_LEVEL_EDITOR(...)
5151
#define GBIND_METHODS_APPEND(...)
5252
#define GBIND_METHODS_PREPEND(...)
53+
#define GRESOURCE_LOADER(...)
54+
#define GRESOURCE_SAVER(...)
5355

5456
#endif // CPPSCRIPT_HEADER

templates/register_types.cpp.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,19 @@ void initialize_@LIBRARY_NAME@_module(ModuleInitializationLevel p_level) {
3636
void uninitialize_@LIBRARY_NAME@_module(ModuleInitializationLevel p_level) {
3737
switch (p_level) {
3838
case MODULE_INITIALIZATION_LEVEL_CORE:
39+
_unregister_level_core();
3940
break;
4041
case MODULE_INITIALIZATION_LEVEL_SERVERS:
42+
_unregister_level_servers();
4143
break;
4244
case MODULE_INITIALIZATION_LEVEL_SCENE:
4345
// Non-cppscript classes, static/global variables
4446
// deinitialization here
4547

48+
_unregister_level_scene();
4649
break;
4750
case MODULE_INITIALIZATION_LEVEL_EDITOR:
51+
_unregister_level_editor();
4852
break;
4953
default:
5054
break;

0 commit comments

Comments
 (0)