def get_blueprint_info(path, transform_str): """ Returns information about the blueprint at path. If transform_str is given, blueprint will be transformed accordingly before returning. """ sheets = filereader.get_sheet_names(path) newphase, transforms, ztransforms = \ transformer.parse_transform_str(transform_str) result = '' for sheet in sheets: try: (layers, details) = filereader.parse_file(path, sheet[1]) # transform the blueprint if transforms is not None: logmsg('transform', 'Transforming with: %s' % transform_str) if newphase is not None: details['build_type'] = buildconfig.get_full_build_type_name(newphase) tran = Transformer(layers, details['start']) tran.transform(transforms) # do the x/y transformations details['start'] = tran.start layers = tran.layers logmsg('transform', 'Results of transform:') loglines('transform', lambda: FileLayer.str_layers(layers)) layers = FileLayers_to_GridLayers(layers) bp = Blueprint(sheet[0], layers, details) # perform any requested z-transforms if ztransforms is not None: layers = bp.repeat_ztransforms(ztransforms, bp.layers, Blueprint.repeater_layers) bp.layers = layers formatted = bp.get_info() # add this sheet's info to the result string result += '>>>> Sheet id %d\n' % sheet[1] result += formatted + '\n' except BlueprintError as ex: continue # ignore blank/missing sheets if result: return result else: raise BlueprintError("No valid blueprints found in '%s'." % path)
def expand_fixed_size_areas(self): """ Expand cell commands of the form 'd(20x20)' to their corresponding areas (in this example a 20x20 designation of d's) and mark those areas as plotted. """ label = self.label for y, row in enumerate(self.grid.rows): for x, cell in enumerate(row): # act on d(5x5) styles cells which haven't been plotted over m = re.match(r'(.+)\((\d+)x(\d+)\)', cell.command) if cell.plottable and m: command = m.group(1) width, height = (int(c) for c in m.group(2, 3)) area = Area((x, y), (x + width - 1, y + height - 1)) # ensure the grid is large enough to accept the expansion self.grid.expand_dimensions(x + width, y + height) # mark this area as plotted self.grid.set_area_cells(area, False, label, command) label = next_label(label) # set each corner's area variable for corner in area.corners: cornercell = self.grid.get_cell(*corner) cornercell.command = command cornercell.area = area self.label = label loglines('area', lambda: Grid.str_area_labels(self.grid)) return
def get_blueprint_info(path, transform_str): """ Returns information about the blueprint at path. If transform_str is given, blueprint will be transformed accordingly before returning. """ sheets = filereader.get_sheet_names(path) newphase, transforms, ztransforms = \ transformer.parse_transform_str(transform_str) result = '' for sheet in sheets: try: (layers, details) = filereader.parse_file(path, sheet[1]) # transform the blueprint if transforms is not None: logmsg('transform', 'Transforming with: %s' % transform_str) if newphase is not None: details[ 'build_type'] = buildconfig.get_full_build_type_name( newphase) tran = Transformer(layers, details['start']) tran.transform(transforms) # do the x/y transformations details['start'] = tran.start layers = tran.layers logmsg('transform', 'Results of transform:') loglines('transform', lambda: FileLayer.str_layers(layers)) layers = FileLayers_to_GridLayers(layers) bp = Blueprint(sheet[0], layers, details) # perform any requested z-transforms if ztransforms is not None: layers = bp.repeat_ztransforms(ztransforms, bp.layers, Blueprint.repeater_layers) bp.layers = layers formatted = bp.get_info() # add this sheet's info to the result string result += '>>>> Sheet id %d\n' % sheet[1] result += formatted + '\n' except BlueprintError as ex: continue # ignore blank/missing sheets if result: return result else: raise BlueprintError("No valid blueprints found in '%s'." % path)
def process_blueprint_command(command, startpos, transform_str, output_mode, output_title, visualize): """ Parses a QF one-line command and converts it to the desired output. """ layers, details = filereader.parse_command(command) logmsg('file', 'Parsed %s' % command) loglines('file', lambda: FileLayer.str_layers(layers)) return convert_blueprint(layers, details, startpos, transform_str, output_mode, output_title, visualize)
def transform(self, transforms): """Transforms start, layers using the given transforms.""" layers = self.layers start = self.start # loop through all single-layer transformations to all layers for i, layer in enumerate(layers): a = layer.rows # aka the memory bucket b = layer.rows # aka the current bucket logmsg('transform', 'Transformation buckets before layer %d:' % i) loglines('transform', lambda: self.str_buckets(a, b)) left = transforms for t in transforms: param, cmd = t left = left[1:] # remove this cmd from the remaining cmds if cmd == 'halign': self.halign = param elif cmd == 'valign': self.valign = param elif cmd == '!': # The ! command just updates A to match B a = b else: a, b = self.apply_transform(t, a, b) # do the transform # adjust start pos for 'n' and 'w' commands if cmd == 'n': start = add_points(start, (0, layers[0].height() * (param - 1))) elif cmd == 'w': start = add_points(start, (layers[0].width() * (param - 1), 0)) if cmd in ('halign', 'valign'): logmsg('transform', 'Set %s=%s' % (t[1], t[0])) else: logmsg('transform', 'Buckets after command %s%s:' % t) loglines('transform', lambda: self.str_buckets(a, b)) # we'll return the result in b layers[i].rows = b self.start, self.layers = start, layers return
def process_blueprint_file(path, sheetid, startpos, transform_str, output_mode, output_title, visualize): """ Parses a blueprint file and converts it to desired output. """ # parse sheetid if sheetid is None: sheetid = 0 elif not re.match('^\d+$', str(sheetid)): # TODO Fix this so it works sheetid = filereader.get_sheet_names(path)[1] # read in the blueprint layers, details = filereader.parse_file(path, sheetid) logmsg('file', 'Parsed %s' % path) loglines('file', lambda: FileLayer.str_layers(layers)) return convert_blueprint(layers, details, startpos, transform_str, output_mode, output_title, visualize)
def discover_areas(self): """ Repeatedly plot the largest contiguous areas possible until there are no more areas left to plot. """ testarea = Area((0, 0), (self.grid.width - 1, self.grid.height - 1)) while True: loglines('area', lambda: Grid.str_area_labels(self.grid)) logmsg('area', 'Marking largest plottable areas starting ' + \ 'with label %s' % self.label) self.label = self.mark_largest_plottable_areas(self.label) # if every single cell is non-plottable (already plotted).. if not self.grid.is_area_plottable(testarea, True): logmsg('area', 'All areas discovered:') loglines('area', lambda: Grid.str_area_labels(self.grid)) return raise AreaPlotterError("Unable to plot all areas for unknown reason")
def plan_route(grid, cursor): """ We assume the areas to be plotted are already loaded into grid. Starting from cursor, we locate the nearest area we can plot, and we plot it. Repeat until all areas are plotted. """ plots = [] grid.set_entire_grid_plottable(True) logmsg('router', 'Starting state:') loglines('router', lambda: Grid.str_area_labels(grid)) while (True): nearest_pos = get_nearest_plottable_area_from(grid, cursor) if nearest_pos is None: # no more areas left to plot break else: # record this plot start-coordinates in plots plots.append(nearest_pos) # mark the plot on the grid cell = grid.get_cell(*nearest_pos) area = cell.area grid.set_area_cells(area, False) logmsg('router', 'Plotting area starting at %s, area %s' % \ (nearest_pos, area)) loglines('router', lambda: Grid.str_plottable(grid)) # move cursor to the ending corner of the plotted area cursor = area.opposite_corner(nearest_pos) logmsg('router', 'Routed through all areas:') loglines('router', lambda: Grid.str_area_labels(grid)) logmsg('router', 'Route replay sequence: %s' % \ ''.join([grid.get_cell(*plot).label for plot in plots])) logmsg('router', 'Cursor position now: %s' % str(cursor)) return grid, plots, cursor
def convert_blueprint(layers, details, startpos, transform_str, output_mode, output_title, visualize): """ Transforms the provided layers if required by transform_str, then renders keystrokes/macros required to plot or visualize the blueprint specified by layers and details and pursuant to args. """ # apply aliases.txt to blueprint contents # TODO abstract this better alii = aliases.load_aliases( os.path.join(exetest.get_main_dir(), 'config/aliases.txt')) layers = aliases.apply_aliases(layers, alii) # transform the blueprint ztransforms = [] if transform_str: logmsg('transform', 'Transforming with: %s' % transform_str) newphase, transforms, ztransforms = \ transformer.parse_transform_str(transform_str) if newphase is not None: details['build_type'] = buildconfig.get_full_build_type_name( newphase) tran = Transformer(layers, details['start']) tran.transform(transforms) # do the x/y transformations details['start'] = tran.start layers = tran.layers logmsg('file', 'Results of transform:') loglines('file', lambda: FileLayer.str_layers(layers)) layers = FileLayers_to_GridLayers(layers) if not layers: # empty blueprint handling raise BlueprintError("Blueprint appears to be empty.") # override starting position if startpos command line option was given if startpos is not None: details['start'] = parse_startpos(startpos, layers[0].grid.width, layers[0].grid.height) # convert layers and other data to Blueprint bp = Blueprint('', layers, details) # get keys/macrocode to outline or plot the blueprint keys = [] if output_mode == 'csv': bp.analyze() # perform any awaiting z-transforms layers = bp.repeat_ztransforms(ztransforms, bp.layers, Blueprint.repeater_layers) bp.layers = layers output = str(bp) else: if visualize: keys = bp.trace_outline() else: bp.analyze() keys = bp.plot(ztransforms) output = keystroker.convert_keys(keys, output_mode, output_title) loglines('summary', lambda: str_summary(bp, keys)) return output
def convert_blueprint(layers, details, startpos, transform_str, output_mode, output_title, visualize): """ Transforms the provided layers if required by transform_str, then renders keystrokes/macros required to plot or visualize the blueprint specified by layers and details and pursuant to args. """ # apply aliases.txt to blueprint contents # TODO abstract this better alii = aliases.load_aliases( os.path.join(exetest.get_main_dir(), 'config/aliases.txt')) layers = aliases.apply_aliases(layers, alii) # transform the blueprint ztransforms = [] if transform_str: logmsg('transform', 'Transforming with: %s' % transform_str) newphase, transforms, ztransforms = \ transformer.parse_transform_str(transform_str) if newphase is not None: details['build_type'] = buildconfig.get_full_build_type_name(newphase) tran = Transformer(layers, details['start']) tran.transform(transforms) # do the x/y transformations details['start'] = tran.start layers = tran.layers logmsg('file', 'Results of transform:') loglines('file', lambda: FileLayer.str_layers(layers)) layers = FileLayers_to_GridLayers(layers) if not layers: # empty blueprint handling raise BlueprintError("Blueprint appears to be empty.") # override starting position if startpos command line option was given if startpos is not None: details['start'] = parse_startpos(startpos, layers[0].grid.width, layers[0].grid.height) # convert layers and other data to Blueprint bp = Blueprint('', layers, details) # get keys/macrocode to outline or plot the blueprint keys = [] if output_mode == 'csv': bp.analyze() # perform any awaiting z-transforms layers = bp.repeat_ztransforms(ztransforms, bp.layers, Blueprint.repeater_layers) bp.layers = layers output = str(bp) else: if visualize: keys = bp.trace_outline() else: bp.analyze() keys = bp.plot(ztransforms) output = keystroker.convert_keys(keys, output_mode, output_title) loglines('summary', lambda: str_summary(bp, keys)) return output