diff --git a/src/protocol/generate_protocol.py b/src/protocol/generate_protocol.py index 5eb801f..0bb8fd1 100644 --- a/src/protocol/generate_protocol.py +++ b/src/protocol/generate_protocol.py @@ -68,7 +68,13 @@ def get_type_info(types, typename): return tp -def resolve_name(types, name, typename, decl=False): +def resolve_name(types, name, value, decl=False): + + if isinstance(value, dict): + return name + + typename = value + tp = get_type_info(types, typename) idx = name.find('(') @@ -90,7 +96,13 @@ def resolve_name(types, name, typename, decl=False): return name -def resolve_type(types, typename): +def resolve_type(types, value): + if isinstance(value, dict): + warn('WARNING: Attempted to call resolve_type on object type') + return "" + + typename = value + tp = get_type_info(types, typename) if 'type' in tp: return tp['type'] @@ -104,9 +116,17 @@ def is_type_array(types, typename): else: return extract_array_count(typename) != None -def get_type_size(types, typename): +def get_type_size(types, value): global varint_max_size + if isinstance(value, dict): + size = 0 + for k, v in value.items(): + size += get_type_size(types, v) + return size + + typename = value + tp = get_type_info(types, typename) if not 'size' in tp: @@ -153,8 +173,22 @@ def get_rw_func(types, typename, read): return method -def print_rw_logic(types, typename, name, read): - resolved_name = resolve_name(types, name, typename) +def print_rw_logic(types, value, name, read): + + resolved_name = resolve_name(types, name, value) + + if isinstance(value, dict): + add_text('{{') + indent() + for k, v in value.items(): + scoped_name = f'{resolved_name}.{resolve_name(types, k, v)}' + print_rw_logic(types, v, scoped_name, read) + unindent() + add_text('}}') + return + + typename = value + start = name.find('(') local_indent = 0 if start != -1: @@ -215,6 +249,22 @@ def print_rw_logic(types, typename, name, read): for i in range(local_indent): unindent() +def print_definition(types, name, value, serverbound): + resolved_name = resolve_name(types, name, value, decl=True) + if isinstance(value, dict): + add_text('struct {{') + indent() + for k, v in value.items(): + print_definition(types, k, v, serverbound) + unindent() + add_text('}} {};', resolved_name) + else: + resolved_type = resolve_type(types, value) + if not serverbound and resolved_type == 'std::string': + add_text('const {}& {};', resolved_type, resolved_name) + else: + add_text('{} {};', resolved_type, resolved_name) + def get_enum_type(dict, fallback = 'int32'): return dict['.type'] if '.type' in dict else fallback @@ -297,13 +347,8 @@ def print_messages(list, globalTypes): unindent() add_text('}}') - for name, typename in message['vars'].items(): - resolved_type = resolve_type(types, extract_array_type(typename)) - resolved_name = resolve_name(types, name, typename, decl=True) - if not serverbound and resolved_type == 'std::string': - add_text('const {}& {};', resolved_type, resolved_name) - else: - add_text('{} {};', resolved_type, resolved_name) + for name, value in message['vars'].items(): + print_definition(types, name, value, serverbound) unindent() add_text('}};')