From c4da1c4fada726449f7476adc1f1bbbdca19ee63 Mon Sep 17 00:00:00 2001 From: DankParrot Date: Tue, 18 Aug 2020 19:45:15 -0700 Subject: [PATCH] Implement alternative enum syntax https://trello.com/c/8SWTk9jt/29-alternative-enum-syntax --- src/protocol/generate_protocol.py | 50 +++++++++++++++++++++++-------- src/protocol/protocol.hjson | 5 ++-- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/protocol/generate_protocol.py b/src/protocol/generate_protocol.py index 5cbc339..913782d 100644 --- a/src/protocol/generate_protocol.py +++ b/src/protocol/generate_protocol.py @@ -58,7 +58,9 @@ def get_type_info(types, typename, aliases={}): alias = tp['alias'] tp = get_type_info(types, tp['alias']).copy() tp['alias'] = alias - if tp['generic'] == True: + generic = 'generic' in tp and tp['generic'] == True + # primitive types are always generic + if generic or not 'method' in tp: tp['type'] = name if alias_name: @@ -105,15 +107,6 @@ def get_type_size(types, typename, aliases={}): return int(size) -def print_enum(name, dict, primitive = 'int32_t'): - add_text('enum class {} : {}', name, primitive) - add_text('{{') - indent() - for key, value in dict.items(): - add_text('{} = {},', key, value) - unindent() - add_text('}};') - def get_rw_func(types, typename, read, aliases={}): method = 'Read' if read else 'Write' @@ -133,8 +126,30 @@ def get_rw_func(types, typename, read, aliases={}): #print('{} -> {}'.format(typename, method)) return method + +def get_enum_type(dict, fallback = 'int32'): + return dict['.type'] if '.type' in dict else fallback + +def print_enum(name, dict, types={}, fallback = None): + primType = get_enum_type(dict, fallback) + + if primType == None: + # if we have nothing to resolve with and no fallback then use int32_t + primitive = 'int32_t' + else: + primitive = resolve_type(types, primType) -def print_messages(list, types): + add_text('enum class {} : {}', name, primitive) + add_text('{{') + indent() + for key, value in dict.items(): + if key.startswith('.'): + continue # ignore metadata + add_text('{} = {},', key, value) + unindent() + add_text('}};') + +def print_messages(list, globalTypes): global text for state, direction_list in list.items(): add_text('namespace {}', state.capitalize()) @@ -143,6 +158,9 @@ def print_messages(list, types): for direction, messages in direction_list.items(): serverbound = direction == 'serverbound' for message_name, message in messages.items(): + + # global and local types + types = globalTypes.copy() # add any local aliases aliases = {} @@ -150,6 +168,12 @@ def print_messages(list, types): for alias in message['aliases']: aliases[alias] = message['aliases'][alias] + # add enums to local types + if 'enums' in message: + for enum in message['enums']: + if not enum in aliases: + types[enum] = {'alias': get_enum_type(message['enums'][enum])} + global varint_max_size size = varint_max_size # Packet Length size += varint_max_size # Packet Id @@ -170,9 +194,9 @@ def print_messages(list, types): if enum in aliases: # lookup enum primitive type from aliases prim = resolve_type(types, aliases[enum]) - print_enum(enum, message['enums'][enum], prim) + print_enum(enum, message['enums'][enum], types, prim) else: - print_enum(enum, message['enums'][enum]) + print_enum(enum, message['enums'][enum], types) newline() if serverbound: add_text('{}(PacketReader& reader)', struct_name) diff --git a/src/protocol/protocol.hjson b/src/protocol/protocol.hjson index 41ea841..7d21b8b 100644 --- a/src/protocol/protocol.hjson +++ b/src/protocol/protocol.hjson @@ -257,6 +257,8 @@ id: 0x36 enums: { RelativeFlags: { + .type: byte + X: 1, Y: 2, Z: 4, @@ -264,9 +266,6 @@ X_ROT: 16, } } - aliases: { - RelativeFlags: byte - } vars: { x: double y: double