@@ -90,16 +90,20 @@ def cpp_type(ty, prefix=True):
9090
9191 m = re .match (r'(.*)_Flags$' , ty )
9292 if m :
93- ty = m .expand (r'\1::Flags' )
94- if prefix :
95- ty = 'rpg::' + ty
96- return ty
93+ raise ValueError ("use flag_type for flags" )
9794
9895 if prefix :
9996 ty = 'rpg::' + ty
10097
10198 return ty
10299
100+ def flag_type (field , struct_name ):
101+ field_type = field .type
102+ # Backward compatibility: When Struct Name = Flag Name only emit "Flags"
103+ if struct_name == field .type [:- 6 ]:
104+ field_type = "Flags"
105+ return field_type
106+
103107def pod_default (field ):
104108 dfl = field .default
105109 ftype = field .type
@@ -133,9 +137,6 @@ def pod_default(field):
133137
134138 return " = " + str (dfl )
135139
136- def num_flags (flag ):
137- return len (flag )
138-
139140def flag_size (flag ):
140141 return (len (flag ) + 7 ) // 8
141142
@@ -149,6 +150,9 @@ def flag_set(field, bit):
149150
150151 return str (res ).lower ()
151152
153+ def flags_for (field ):
154+ return flags [field .type [:- 6 ]]
155+
152156def filter_structs_without_codes (structs ):
153157 for struct in structs :
154158 if all (f .code for f in sfields [struct .name ]):
@@ -392,11 +396,14 @@ def type_is_array_of_struct(ty):
392396def is_monotonic_from_0 (enum ):
393397 expected = 0
394398 for (val , idx ) in enum :
395- if int (idx ) != expected :
399+ if int (idx , 0 ) != expected :
396400 return False
397401 expected += 1
398402 return True
399403
404+ def is_scoped_enum (enum_name ):
405+ return enum_name == "Code"
406+
400407def openToRender (path ):
401408 subdir = os .path .dirname (path )
402409 if not os .path .exists (subdir ):
@@ -426,6 +433,8 @@ def generate():
426433 structs = sorted ([x .name for x in structs_flat ])
427434 ))
428435
436+ flag_fields = []
437+
429438 for filetype , structlist in structs .items ():
430439 for struct in structlist :
431440 filename = struct .name .lower ()
@@ -442,8 +451,8 @@ def generate():
442451 type = filetype
443452 ))
444453
445-
446- filepath = os .path .join (tmp_dir , 'lcf' , 'rpg' , '%s.h' % filename )
454+ struct_header = os . path . join ( 'lcf' , 'rpg' , '%s.h' % filename )
455+ filepath = os .path .join (tmp_dir , struct_header )
447456 with openToRender (filepath ) as f :
448457 f .write (rpg_header_tmpl .render (
449458 struct_name = struct .name ,
@@ -459,14 +468,33 @@ def generate():
459468 filename = filename
460469 ))
461470
462- if struct .name in flags :
463- filepath = os .path .join (tmp_dir , '%s_%s_flags.h' % (filetype , filename ))
471+ struct_flag_fields = [s for s in sfields [struct .name ] if s .type .endswith ("_Flags" )]
472+ for flag_field in struct_flag_fields :
473+ header_file = '%s_%s_%s.h' % (filetype , filename , flag_field .name )
474+ filepath = os .path .join (tmp_dir , header_file )
475+ field_name = flag_type (flag_field , struct .name )
476+ flag_fields .append (dict (struct_name = struct .name , struct_header = struct_header , field_name = field_name , flag_header = header_file ))
477+
464478 with openToRender (filepath ) as f :
465479 f .write (flags_tmpl .render (
466- struct_name = struct .name ,
467- type = filetype
480+ struct_name = flag_fields [- 1 ]["struct_name" ],
481+ type = filetype ,
482+ flag_name = flag_fields [- 1 ]["field_name" ],
483+ flag_item = flags [flag_field .type [:- 6 ]]
468484 ))
469485
486+ filepath = os .path .join (tmp_dir , 'fwd_flags_impl.h' )
487+ with openToRender (filepath ) as f :
488+ f .write (flags_fwd_tmpl .render (
489+ flags = flag_fields
490+ ))
491+
492+ filepath = os .path .join (tmp_dir , 'fwd_flags_instance.h' )
493+ with openToRender (filepath ) as f :
494+ f .write (flags_instance_tmpl .render (
495+ flags = flag_fields
496+ ))
497+
470498 for dirname , subdirlist , filelist in os .walk (tmp_dir , topdown = False ):
471499 subdir = os .path .relpath (dirname , tmp_dir )
472500
@@ -486,7 +514,7 @@ def main(argv):
486514 os .mkdir (dest_dir )
487515
488516 global structs , structs_flat , sfields , enums , flags , functions , constants , headers
489- global chunk_tmpl , lcf_struct_tmpl , rpg_header_tmpl , rpg_source_tmpl , flags_tmpl , enums_tmpl , fwd_tmpl , fwd_struct_tmpl
517+ global chunk_tmpl , lcf_struct_tmpl , rpg_header_tmpl , rpg_source_tmpl , flags_tmpl , flags_fwd_tmpl , flags_instance_tmpl , enums_tmpl , fwd_tmpl , fwd_struct_tmpl
490518
491519 structs , structs_flat = get_structs ('structs.csv' , 'structs_easyrpg.csv' )
492520 sfields = get_fields ('fields.csv' , 'fields_easyrpg.csv' )
@@ -499,15 +527,17 @@ def main(argv):
499527 # Setup Jinja
500528 env .filters ["lcf_type" ] = lcf_type
501529 env .filters ["cpp_type" ] = cpp_type
530+ env .filters ["flag_type" ] = flag_type
502531 env .filters ["pod_default" ] = pod_default
503532 env .filters ["struct_has_code" ] = filter_structs_without_codes
504533 env .filters ["field_is_used" ] = filter_unused_fields
505534 env .filters ["field_is_written" ] = filter_unwritten_fields
506535 env .filters ["field_is_not_size" ] = filter_size_fields
507- env .filters ["num_flags" ] = num_flags
508536 env .filters ["flag_size" ] = flag_size
509537 env .filters ["flag_set" ] = flag_set
538+ env .filters ["flags_for" ] = flags_for
510539 env .tests ['monotonic_from_0' ] = is_monotonic_from_0
540+ env .tests ['scoped_enum' ] = is_scoped_enum
511541 env .tests ['is_db_string' ] = type_is_db_string
512542 env .tests ['is_array' ] = type_is_array
513543 env .tests ['is_array_of_struct' ] = type_is_array_of_struct
@@ -529,6 +559,8 @@ def main(argv):
529559 rpg_header_tmpl = env .get_template ('rpg_header.tmpl' , globals = globals )
530560 rpg_source_tmpl = env .get_template ('rpg_source.tmpl' , globals = globals )
531561 flags_tmpl = env .get_template ('flag_reader.tmpl' , globals = globals )
562+ flags_fwd_tmpl = env .get_template ('flag_fwd.tmpl' , globals = globals )
563+ flags_instance_tmpl = env .get_template ('flag_instance.tmpl' , globals = globals )
532564 fwd_tmpl = env .get_template ('fwd.tmpl' , globals = globals )
533565 fwd_struct_tmpl = env .get_template ('fwd_struct.tmpl' , globals = globals )
534566
0 commit comments