def _inherit_into(obj, parent_class, game_objects): parent = game_objects[parent_class] for parm_type in ["attributes", "functions"]: for parm_key, parm_parms in parent[parm_type].items(): obj['inherited' + parm_type.capitalize()][parm_key] = copy_dict( parm_parms, {'inheritedFrom': parent_class}) for parent_parent_class in parent['parentClasses']: _inherit_into(obj, parent_parent_class, game_objects)
def build_all(prototype, inputs, output, do_merge=False, tagless=False): generated_files = [] game = prototype['game'] game_name = game['name'] game_objects = prototype['game_objects'] ai = prototype['ai'] if not inputs: inputs = default_input() if not output: output = "../" if do_merge else "./output" for input_directory in inputs: full_path = os.path.join(input_directory, templates_folder) for root, dirnames, filenames in os.walk(full_path): for filename in filenames: extensionless, extension = os.path.splitext(filename) if extension == '.noCreer': # noCreer files are not to be templated continue filepath = os.path.join(root, filename) dirs = list_dirs(filepath) output_path = "" for i, d in enumerate(dirs): if d == templates_folder: # slice it off if output: if i > 0: output_path = os.path.join( dirs[i - 1], *dirs[i + 1:]) else: output_path = os.path.join(*dirs[i + 1:]) else: output_dirs = list(dirs) output_dirs.pop(i) output_path = os.path.join(*output_dirs) break binary = is_binary( filepath ) # don't template binary files, assume they are needed to work (like images) if binary: print("binary file", output_path) else: print("templating", output_path) with open(filepath, "r") as read_file: lookup = TemplateLookup( directories=[os.path.dirname(filepath)]) filecontents_template = Template(read_file.read(), lookup=lookup) filepath_template = Template(output_path, lookup=lookup) base_parameters = { 'game': game, 'game_name': game_name, 'game_objs': game_objects, 'game_obj_names': sort_dict_keys(game_objects), 'ai': ai, 'uncapitalize': uncapitalize, 'camel_case_to_underscore': camel_case_to_underscore, # depreciated 'underscore': camel_case_to_underscore, 'hyphenate': camel_case_to_hyphenate, 'sort_dict_keys': sort_dict_keys, 'upcase_first': upcase_first, 'lowercase_first': lowercase_first, 'is_primitive_type': is_primitive_type, 'header': template_header, 'json': json, 'shared': {}, } parameters = [] if 'obj_key' in extensionless: # then we are templating for all the game + game objects parameters.append( copy_dict(base_parameters, { 'obj_key': "Game", 'obj': game, })) for obj_key, obj in game_objects.items(): parameters.append( copy_dict(base_parameters, { 'obj_key': obj_key, 'obj': obj })) else: parameters.append(base_parameters) for p in parameters: try: templated_path = filepath_template.render(**p) system_path = os.path.join( output, templated_path) if output else templated_path if binary: # copy the file, don't actually template it print(" -> copying", system_path) generated_files.append({ 'copy-from': filepath, 'copy-dest': system_path }) continue merge_data = {} if do_merge and os.path.isfile( system_path ): # then we need to have merge data in the existing file with the new one we would be creating with open(system_path) as f: content = f.readlines() merge_data = merge.generate_data(content) print(" -> generating", system_path) def this_merge(pre_comment, key, alt, optional=False, help=True): return merge.with_data( merge_data, pre_comment, key, alt, optional=optional, add_tags=(not tagless), help=help, ) p['merge'] = this_merge contents = filecontents_template.render(**p) endl = "\r\n" if "\r\n" in contents else "\n" generated_files.append({ 'contents': contents.rstrip() + endl, 'path': system_path, }) except: raise Exception( exceptions.text_error_template().render()) return generated_files
def build(datas): parent_keys = ['main'] parent_datas = [] parent_data_names = [] while len(parent_keys) > 0: parent_key = parent_keys.pop() parent_data = datas[parent_key] if parent_key != 'main': parent_data_names.append(parent_key) parent_datas.append(parent_data) # now look if that data had parent data to continue investigating if not '_parentDatas' in parent_data: parent_data['_parentDatas'] = [] for new_parent_key in parent_data['_parentDatas']: parent_keys.append(new_parent_key) parent_datas.append(datas['base']) # all games get the base data # merge all the prototypes inherited into one prototype prototype = {} for parent_data in reversed(parent_datas): extend(prototype, parent_data) # extend won't do this correctly. multiple data may pre-define parent classes and will get overwritten via extend. this appends each additional class name for proto_key, proto in prototype.items(): if proto_key[0] == "_": continue newServerParentClasses = [] if 'serverParentClasses' in proto: for parent_data in reversed(parent_datas): if proto_key in parent_data and 'serverParentClasses' in parent_data[ proto_key]: for parent_class_name in parent_data[proto_key][ 'serverParentClasses']: newServerParentClasses.append(parent_class_name) proto['serverParentClasses'] = newServerParentClasses game_objects = {} game = prototype['Game'] if not 'name' in game: raise Exception( "Error: no name given for the main game data. Name your Game!!!") default.game_obj(game, "Game") ai = prototype['AI'] del prototype['AI'] default.functions_for(ai, "AI") if len(game['serverParentClasses']) == 0: game['serverParentClasses'].append("BaseGame") for obj_key, obj in prototype.items(): if obj_key == "Game" or obj_key[0] == "_": continue if obj_key == "GameObject" and len(obj['serverParentClasses']) == 0: obj['serverParentClasses'] = ['BaseGameObject'] default.game_obj(obj, obj_key) if obj_key != "GameObject" and len(obj['parentClasses']) == 0: obj['parentClasses'].append("GameObject") game_objects[obj_key] = obj for obj_key, obj in (copy_dict(game_objects, {'Game': game}).items()): obj['inheritedAttributes'] = {} obj['inheritedFunctions'] = {} for parent_class in obj['parentClasses']: _inherit_into(obj, parent_class, game_objects) # now all the prototypes should be built, so sort the attribute/function keys for proto_key, proto in prototype.items(): if proto_key[0] == '_': continue proto['function_names'] = sort_dict_keys(proto['functions']) proto['attribute_names'] = sort_dict_keys(proto['attributes']) proto['inheritedFunction_names'] = sort_dict_keys( proto['inheritedFunctions']) proto['inheritedAttribute_names'] = sort_dict_keys( proto['inheritedAttributes']) ai['function_names'] = sort_dict_keys(ai['functions']) creer.validate.validate(prototype) proto = {'game_objects': game_objects, 'game': game, 'ai': ai} min_game_data = _proto_clean(proto) as_string = json.dumps(min_game_data, sort_keys=True) as_bytes = bytes(as_string, 'utf8') sha = hashlib.sha256() sha.update(as_bytes) proto['parent_data_names'] = parent_data_names proto['game_version'] = sha.hexdigest() return proto