1717from typing import TYPE_CHECKING , NamedTuple
1818
1919from mhfu .live import brain as live
20- from mhfu .live .brain import Brain
20+ from mhfu .live .brain import Brain , Reader
2121from mhfu_port import behaviour
22+ from mhfu_port .behaviour import Trigger
2223from mhfu_port .manifest import Manifest , ManifestError
2324from ppsspp_debug import DebuggerError
2425
@@ -86,6 +87,21 @@ def match(brain: Brain, m: Manifest) -> dict[int, int] | str:
8687 return out
8788
8889
90+ Writer = Callable [[Reader , int , Manifest , Trigger ], str ]
91+ """Raises a trigger in the game at the brain `cfg`; says what it did."""
92+
93+
94+ def _signal (s : Reader , cfg : int , m : Manifest , t : Trigger ) -> str :
95+ index = behaviour .signals (m )[t .name ]
96+ live .fire_signal (s , cfg , index )
97+ return f"raised signal { t .name } in the game (board signal { index } )"
98+
99+
100+ FIRE : dict [str , Writer ] = {"on_signal" : _signal }
101+ """What Fire can raise in the running game, by the trigger's kind, and how: the one table. A
102+ trigger with no entry has no Fire button."""
103+
104+
89105class Watch :
90106 """The state of Watch the game: `fires` (rank to count; None when not watching or there is
91107 nothing to show) and `status` say what the marks show, `lit` which frames flash."""
@@ -101,6 +117,24 @@ def __init__(self, clock: Callable[[], float] = time.monotonic) -> None:
101117 self ._asked = self ._lost = float ("-inf" )
102118 self ._since : int | None = None
103119
120+ @property
121+ def cfg (self ) -> int | None :
122+ """Where the brain was found in this attach; None until it is."""
123+ return self ._cfg
124+
125+ def blocker (self ) -> str | None :
126+ """Why the game cannot be written to now: it is not watched, not running, its brain not
127+ found or not these rules. None when the brain is found and runs this port's rules."""
128+ if not self .on :
129+ return "turn on Watch the game first: it finds the framework in the game"
130+ if self .fires is None or self ._cfg is None :
131+ return (
132+ self .status
133+ if self .status != READING
134+ else "Watch the game has not read the game yet"
135+ )
136+ return None
137+
104138 def set (self , on : bool ) -> None :
105139 self .on = on
106140 self .reset ()
0 commit comments