From: Axy Date: Sun, 27 Sep 2026 21:36:45 +0000 (+0200) Subject: Cleanup and run conditions X-Git-Url: https://git.uwuaxy.net/Project%20Status.png?a=commitdiff_plain;h=c038d78be52a46fcca912cfa8da97afb221e1365;p=axy%2Fft%2Fpacman.git Cleanup and run conditions --- diff --git a/src/pacman/ecs/schedule.py b/src/pacman/ecs/schedule.py index d9742f4..58fe9b5 100644 --- a/src/pacman/ecs/schedule.py +++ b/src/pacman/ecs/schedule.py @@ -72,6 +72,7 @@ class Schedule[T]: def __init__(self) -> None: self._dag: DAG[T | DAGLabel | None] = DAG() self._group_appartenance: dict[T | SystemSet, set[SystemSet]] = {} + self._run_predicates: dict[T | SystemSet, Callable[[], bool]] = {} def add_ordering( self, @@ -79,6 +80,7 @@ class Schedule[T]: pre: Iterable[T | SystemSet], post: Iterable[T | SystemSet], group: Iterable[SystemSet], + cond: Callable[[], bool] | None, ) -> None: def get_pre(e: T | SystemSet) -> T | DAGLabel: if isinstance(e, SystemSet): @@ -102,19 +104,25 @@ class Schedule[T]: self._dag.add_edge(get_pre(e), get_pre(item)) self._dag.add_edge(get_post(item), get_post(e)) self._group_appartenance[item].add(e) + if cond is not None: + if (prev := self._run_predicates.get(item)) is not None: + self._run_predicates[item] = lambda: prev() and cond() + else: + self._run_predicates[item] = cond - def traverse( - self, run_cond: Callable[[T | SystemSet], bool] - ) -> Generator[T]: + def traverse(self) -> Generator[T]: cond_cache: dict[T | SystemSet, bool] = {} def should_run(val: T | SystemSet) -> bool: if val in cond_cache: return cond_cache[val] - res = all( - should_run(parent) - for parent in self._group_appartenance.get(val, set()) - ) and run_cond(val) + res = ( + all( + should_run(parent) + for parent in self._group_appartenance.get(val, set()) + ) + and self._run_predicates.get(val, lambda: True)() + ) cond_cache[val] = res return res diff --git a/src/pacman/ecs/world.py b/src/pacman/ecs/world.py index b173484..f81f768 100644 --- a/src/pacman/ecs/world.py +++ b/src/pacman/ecs/world.py @@ -823,7 +823,7 @@ class World(FromWorld): def add_raw_system[T]( self, - system: Callable[..., T], + system: System[T], default: Callable[[], T] = _system_failed, ) -> RawSystem[T]: extractors = self._sys_extractors(system) @@ -853,7 +853,7 @@ class World(FromWorld): def tick(self, schedule: ScheduleLabel) -> None: if schedule not in self._schedules: return - for system in self._schedules[schedule].traverse(lambda _: True): + for system in self._schedules[schedule].traverse(): system() def run( @@ -868,13 +868,10 @@ class World(FromWorld): self, schedule: ScheduleLabel, *systems: "System | Systems", - sets: set[SystemSet] | None = None, - ) -> "World": - if sets is None: - sets = set() + ) -> Self: if schedule not in self._schedules: self._schedules[schedule] = Schedule() - Systems(*systems).in_set(*sets)._apply(self, self._schedules[schedule]) + Systems(*systems)._apply(self, self._schedules[schedule]) return self def with_hook[T: Component]( @@ -882,7 +879,7 @@ class World(FromWorld): cycle: Literal["insert", "remove"], ty: type[T], hook: ComponentHook[T], - ) -> "World": + ) -> Self: comp_id = self.component_id(resolve_type_aliases(ty)) hooks = cast(ComponentHooks[T], self._components_cache[comp_id][1]) sys = self.add_system(hook, default=lambda _: None) @@ -893,7 +890,7 @@ class World(FromWorld): hooks.add_remove(sys) return self - def with_plugins(self, *plugins: Plugin) -> "World": + def with_plugins(self, *plugins: Plugin) -> Self: for plugin in plugins: if isinstance(plugin, tuple): self.with_plugins(plugin) @@ -915,23 +912,28 @@ class Systems: self._pre: list[System | SystemSet] = [] self._post: list[System | SystemSet] = [] self._in_set: list[SystemSet] = [] + self._conds: list[System[bool]] = [] - def chain(self) -> "Systems": + def chain(self) -> Self: self._chain = True return self - def after(self, *systems: System | SystemSet) -> "Systems": + def after(self, *systems: System | SystemSet) -> Self: self._pre.extend(systems) return self - def before(self, *systems: System | SystemSet) -> "Systems": + def before(self, *systems: System | SystemSet) -> Self: self._post.extend(systems) return self - def in_set(self, *sets: SystemSet) -> "Systems": + def in_set(self, *sets: SystemSet) -> Self: self._in_set.extend(sets) return self + def run_if(self, *conds: System[bool]) -> Self: + self._conds.extend(conds) + return self + def _apply(self, world: World, sched: Schedule[RawSystem]) -> SystemSet: global _order_groups _order_groups += 1 @@ -946,14 +948,18 @@ class Systems: ) for e in self._systems ) - sched.add_ordering((label,), self._pre, self._post, self._in_set) + for cond in self._conds: + sched.add_ordering( + (label,), (), (), (), world.add_raw_system(cond, lambda: False) + ) + sched.add_ordering((label,), self._pre, self._post, self._in_set, None) if self._chain: prev: tuple[SystemSet | RawSystem] | tuple[()] = () for system in systems: - sched.add_ordering((system,), prev, (), (label,)) + sched.add_ordering((system,), prev, (), (label,), None) prev = (system,) else: - sched.add_ordering(systems, (), (), (label,)) + sched.add_ordering(systems, (), (), (label,), None) return label