def dirty_update(self): tick = get_current_tick() # If there is any time-dependant image change, there is no way # to predict what changes from one frame to the next - just mark # all shape as dirty. if any("tick" in transformer.signatures for transformer in self.context.transformers): self.dirty_set() return # Collect rects from sprites if self.has_sprites: for sprite in self.sprites: if not sprite.active: continue for rect in sprite.dirty_rects: self.dirty_registry.push( (tick, sprite.owner_coords(rect), sprite.shape)) # mark dirty pixels tile_size = (DIRTY_TILE_SIZE, DIRTY_TILE_SIZE) self_rect = Rect((0, 0), self.size) for tile in self.dirty_pixels: rect = Rect(tile * DIRTY_TILE_SIZE, width_height=tile_size) rect = rect.intersection(self_rect) if not rect: continue self.dirty_registry.push((tick, rect, None)) self.dirty_pixels = set()
def dirty_set(self, rect=None): tick = get_current_tick() if rect is None: rect = Rect((0, 0), self.size) else: rect = Rect(rect) if not isinstance(rect, Rect) else rect self.dirty_registry.reset_to((tick, rect, None))
def build_args(channel, signature): nonlocal transformer, pixel, values, ch_num args = {} for parameter in signature: if parameter == "self": args["self"] = transformer elif parameter == "value": args["value"] = values[ch_num] elif parameter in Transformer.channels and parameter != "pixel": args[parameter] = getattr(pixel, parameter if parameter != "char" else "value") elif parameter == "pos": args["pos"] = V2(pos) elif parameter == "pixel": args["pixel"] = pixel elif parameter == "source": args["source"] = source elif parameter == "tick": args["tick"] = get_current_tick() elif parameter == "context": args["context"] = source.context elif hasattr(transformer, parameter): # Allows for custom parameters that can be made available # for specific uses of transformers. # (ex.: 'sequence_index' for transformers inlined in rich-text rendering) args[parameter] = getattr(transformer, parameter) return args
def _enter_iteration(self): cm = self.locals.context_map = {} for key, value in self.context: cm[key] = [(value, "original")] marks = self.text_plane.marks if self.text_plane else MarkMap() self.marks = marks.prepare( self.mark_sequence, self.text_plane.ticks if self.text_plane else get_current_tick(), self.cooked_text, self.context, ) self._active_transformers = []
def __init__(self, type, dispatch=True, **kwargs): """Event object - used to deliver messages across various program units in animations or interactive apps. Args: - type (EventTypes): The event type - dispatch (bool): whether the event should automatically queue itself for being consumed. Default: True - kwargs: any other attributes that should be set on the Event object. """ from terminedia.utils import get_current_tick self.__dict__.update(kwargs) self.timestamp = time.time() self.tick = kwargs.pop("tick", None) or get_current_tick() self.type = type if dispatch: _event_dispatch(self)
def shape(self): tick = get_current_tick() return self.shapes[(tick // self.tick_cycle) % len(self.shapes)]
def pos(self, value): if getattr(self, "owner", None): self.owner.dirty_registry.push( (get_current_tick(), self.rect, None)) self._pos = V2(value)
def active(self, value): self.__dict__["active"] = value # self.dirty_previous_rect = None if getattr(self, "owner", None): self.owner.dirty_registry.push( (get_current_tick(), self.rect, None))
def dirty_clear(self, threshold=None): tick = threshold if threshold is not None else get_current_tick() self.dirty_last_clear = tick self.dirty_registry.reset() # clear_left(tick) self.dirty_save_current_sprite_rects(tick)