Feature #510 ยป 0003-delta-protocol-transmit-fields-bitvector-after-key-f.patch
common/generate_packets.py | ||
---|---|---|
pre_send_{self.packet_name}(pc, &packet_buf);
|
||
"""
|
||
delta_header = "\n" + prefix(" ", self.get_delta_send_header(before_return)) if self.delta else ""
|
||
init_field_addr = f"""\
|
||
#ifdef FREECIV_JSON_CONNECTION
|
||
... | ... | |
""" if self.fields else ""
|
||
put_key = "".join(
|
||
prefix(" ", field.get_put(False)) + "\n"
|
||
for field in self.key_fields
|
||
)
|
||
nondelta_body = "\n".join(
|
||
prefix(" ", field.get_put(False))
|
||
for field in self.fields
|
||
for field in self.other_fields
|
||
)
|
||
if self.delta:
|
||
declare_differ = f"""\
|
||
bool differ;
|
||
""" if self.differ_used else ""
|
||
if self.is_info == "no":
|
||
declare_different = ""
|
||
elif self.want_force:
|
||
declare_different = f"""\
|
||
int different = force_to_send;
|
||
"""
|
||
else:
|
||
declare_different = f"""\
|
||
int different = 0;
|
||
"""
|
||
delta_body = prefix(" ", self.get_delta_send_body(before_return))
|
||
delta_body = prefix(" ", self.get_delta_send_body())
|
||
body = f"""\
|
||
#ifdef FREECIV_DELTA_PROTOCOL
|
||
{self.name}_fields fields;
|
||
struct {self.packet_name} *old;
|
||
{declare_differ}\
|
||
{declare_different}\
|
||
struct genhash **hash = pc->phs.sent + {self.type};
|
||
{delta_body}\
|
||
#else /* FREECIV_DELTA_PROTOCOL */
|
||
{nondelta_body}\
|
||
#endif
|
||
#endif /* FREECIV_DELTA_PROTOCOL */
|
||
"""
|
||
else:
|
||
body = nondelta_body
|
||
... | ... | |
{log_key}\
|
||
{report}\
|
||
{pre_send}\
|
||
{delta_header}\
|
||
{init_field_addr}\
|
||
{put_key}\
|
||
{body}\
|
||
{post_send}\
|
||
... | ... | |
"""
|
||
def get_delta_send_body(self, before_return: str = "") -> str:
|
||
def get_delta_send_header(self, before_return: str = "") -> str:
|
||
"""Helper for get_send(). Generate the part of the send function
|
||
that computes and transmits the delta between the real packet and
|
||
the last cached packet."""
|
||
that determined which fields differ between the real packet and
|
||
the last cached packet, and possibly discards is-info packets."""
|
||
declare_differ = f"""\
|
||
bool differ;
|
||
""" if self.differ_used else ""
|
||
if self.is_info == "no":
|
||
declare_different = ""
|
||
elif self.want_force:
|
||
declare_different = f"""\
|
||
int different = force_to_send;
|
||
"""
|
||
else:
|
||
declare_different = f"""\
|
||
int different = 0;
|
||
"""
|
||
force_info = """\
|
||
different = 1; /* Force to send. */
|
||
""" if self.is_info != "no" else ""
|
||
... | ... | |
else:
|
||
discard_part = ""
|
||
put_key = "".join(
|
||
field.get_put(True) + "\n"
|
||
for field in self.key_fields
|
||
)
|
||
return f"""\
|
||
#ifdef FREECIV_DELTA_PROTOCOL
|
||
{self.name}_fields fields;
|
||
struct {self.packet_name} *old;
|
||
{declare_differ}\
|
||
{declare_different}\
|
||
struct genhash **hash = pc->phs.sent + {self.type};
|
||
if (nullptr == *hash) {{
|
||
*hash = genhash_new_full(hash_{self.name}, cmp_{self.name},
|
||
nullptr, nullptr, nullptr, destroy_{self.packet_name});
|
||
}}
|
||
BV_CLR_ALL(fields);
|
||
if (!genhash_lookup(*hash, real_packet, (void **) &old)) {{
|
||
old = fc_malloc(sizeof(*old));
|
||
/* temporary bitcopy just to insert correctly */
|
||
*old = *real_packet;
|
||
genhash_insert(*hash, old, old);
|
||
init_{self.packet_name}(old);
|
||
{force_info}\
|
||
}}
|
||
{cmp_part}\
|
||
{discard_part}\
|
||
#endif /* FREECIV_DELTA_PROTOCOL */
|
||
"""
|
||
def get_delta_send_body(self) -> str:
|
||
"""Helper for get_send(). Generate the part of the send function
|
||
that transmits the delta between the real packet and the last
|
||
cached packet.
|
||
put_other = "\n".join(
|
||
See also get_delta_send_header()"""
|
||
body = "\n".join(
|
||
field.get_put_wrapper(self, i, True)
|
||
for i, field in enumerate(self.other_fields)
|
||
)
|
||
... | ... | |
)
|
||
return f"""\
|
||
if (nullptr == *hash) {{
|
||
*hash = genhash_new_full(hash_{self.name}, cmp_{self.name},
|
||
nullptr, nullptr, nullptr, destroy_{self.packet_name});
|
||
}}
|
||
BV_CLR_ALL(fields);
|
||
if (!genhash_lookup(*hash, real_packet, (void **) &old)) {{
|
||
old = fc_malloc(sizeof(*old));
|
||
/* temporary bitcopy just to insert correctly */
|
||
*old = *real_packet;
|
||
genhash_insert(*hash, old, old);
|
||
init_{self.packet_name}(old);
|
||
{force_info}\
|
||
}}
|
||
{cmp_part}\
|
||
{discard_part}\
|
||
#ifdef FREECIV_JSON_CONNECTION
|
||
field_addr.name = "fields";
|
||
#endif /* FREECIV_JSON_CONNECTION */
|
||
... | ... | |
log_packet_detailed("fields bitvector error detected");
|
||
}}
|
||
{put_key}\
|
||
{put_other}\
|
||
{body}\
|
||
{copy_to_old}\
|
||
{reset_part}\
|
||
... | ... | |
def get_receive(self) -> str:
|
||
"""Generate the receive function for this packet variant"""
|
||
delta_header = f"""\
|
||
#ifdef FREECIV_DELTA_PROTOCOL
|
||
{self.name}_fields fields;
|
||
struct {self.packet_name} *old;
|
||
struct genhash **hash = pc->phs.received + {self.type};
|
||
#endif /* FREECIV_DELTA_PROTOCOL */
|
||
""" if self.delta else ""
|
||
init_field_addr = f"""\
|
||
#ifdef FREECIV_JSON_CONNECTION
|
||
... | ... | |
#endif /* FREECIV_JSON_CONNECTION */
|
||
""" if self.fields else ""
|
||
get_delta_bv = f"""\
|
||
#ifdef FREECIV_DELTA_PROTOCOL
|
||
#ifdef FREECIV_JSON_CONNECTION
|
||
field_addr.name = "fields";
|
||
#endif /* FREECIV_JSON_CONNECTION */
|
||
DIO_BV_GET(&din, &field_addr, fields);
|
||
#endif /* FREECIV_DELTA_PROTOCOL */
|
||
""" if self.delta else ""
|
||
get_key = "".join(
|
||
prefix(" ", field.get_get(True)) + "\n"
|
||
prefix(" ", field.get_get(False)) + "\n"
|
||
for field in self.key_fields
|
||
)
|
||
... | ... | |
{self.receive_prototype}
|
||
{{
|
||
#define FREE_PACKET_STRUCT(_packet) free_{self.packet_name}(_packet)
|
||
{delta_header}\
|
||
RECEIVE_PACKET_START({self.packet_name}, real_packet);
|
||
{init_field_addr}\
|
||
{get_delta_bv}\
|
||
{get_key}\
|
||
{log_key}\
|
||
{get_body}\
|
||
... | ... | |
def get_delta_receive_body(self) -> str:
|
||
"""Helper for get_receive(). Generate the part of the receive
|
||
function responsible for recreating the full packet from the
|
||
received delta and the last cached packet."""
|
||
received delta and the last cached packet.
|
||
Note: This code fragment declares variables. To comply with
|
||
CodingStyle, it should be enclosed in a block {} or #ifdef."""
|
||
log_no_old = f"""\
|
||
{self.log_macro}(" no old info");
|
||
""" if self.gen_log else ""
|
||
... | ... | |
)
|
||
return f"""\
|
||
{self.name}_fields fields;
|
||
struct {self.packet_name} *old;
|
||
struct genhash **hash = pc->phs.received + {self.type};
|
||
if (nullptr == *hash) {{
|
||
*hash = genhash_new_full(hash_{self.name}, cmp_{self.name},
|
||
nullptr, nullptr, nullptr, destroy_{self.packet_name});
|
||
... | ... | |
{log_no_old}\
|
||
}}
|
||
#ifdef FREECIV_JSON_CONNECTION
|
||
field_addr.name = "fields";
|
||
#endif /* FREECIV_JSON_CONNECTION */
|
||
DIO_BV_GET(&din, &field_addr, fields);
|
||
{body}\
|
||
if (nullptr == old) {{
|