Skip to content

Commit 71f24fe

Browse files
author
Nejc Stebe
committed
introduce progress entering pause alongside paused
1 parent 4d08730 commit 71f24fe

10 files changed

Lines changed: 55 additions & 47 deletions

module_renderer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def __init__(
3030
run_state: RunState,
3131
event_bus: EventBus,
3232
stop_event: threading.Event | None = None,
33-
pause_event: threading.Event | None = None,
33+
enter_pause_event: threading.Event | None = None,
3434
):
3535
self.codeplainAPI = codeplainAPI
3636
self.filename = filename
@@ -40,7 +40,7 @@ def __init__(
4040
self.run_state = run_state
4141
self.event_bus = event_bus
4242
self.stop_event = stop_event
43-
self.pause_event = pause_event
43+
self.enter_pause_event = enter_pause_event
4444

4545
def _ensure_module_folders_exist(self, module_name: str, first_render_frid: str) -> tuple[str, str]:
4646
"""
@@ -183,7 +183,7 @@ def _build_render_context_for_module(
183183
event_bus=self.event_bus,
184184
test_script_timeout=self.args.test_script_timeout,
185185
stop_event=self.stop_event,
186-
pause_event=self.pause_event,
186+
enter_pause_event=self.enter_pause_event,
187187
)
188188

189189
def _render_module(

plain2code.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def render(args, run_state: RunState, event_bus: EventBus): # noqa: C901
203203
_check_connection(codeplainAPI)
204204

205205
stop_event = threading.Event()
206-
pause_event = threading.Event()
206+
enter_pause_event = threading.Event()
207207
signal.signal(signal.SIGTERM, lambda _signum, _frame: stop_event.set())
208208

209209
module_renderer = ModuleRenderer(
@@ -215,7 +215,7 @@ def render(args, run_state: RunState, event_bus: EventBus): # noqa: C901
215215
run_state,
216216
event_bus,
217217
stop_event=stop_event,
218-
pause_event=pause_event,
218+
enter_pause_event=enter_pause_event,
219219
)
220220

221221
render_error: list[Exception] = []
@@ -247,7 +247,7 @@ def run_render():
247247
conformance_tests_script=args.conformance_tests_script,
248248
prepare_environment_script=args.prepare_environment_script,
249249
state_machine_version=system_config.client_version,
250-
pause_event=pause_event,
250+
enter_pause_event=enter_pause_event,
251251
css_path="styles.css",
252252
)
253253
app.run()

plain2code_events.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,8 @@ class RenderModuleCompleted(BaseEvent):
6161
@dataclass
6262
class RenderModuleStarted(BaseEvent):
6363
module_name: str
64+
65+
66+
@dataclass
67+
class RenderPaused(BaseEvent):
68+
pass

render_machine/code_renderer.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from transitions.extensions.diagrams import HierarchicalGraphMachine
55

6-
from plain2code_events import RenderModuleCompleted, RenderModuleStarted, RenderStateUpdated
6+
from plain2code_events import RenderModuleCompleted, RenderModuleStarted, RenderPaused, RenderStateUpdated
77
from render_machine.render_context import RenderContext
88
from render_machine.state_machine_config import StateMachineConfig, States
99

@@ -40,8 +40,10 @@ def run(self):
4040
previous_state = None
4141

4242
while True:
43-
if self.render_context.pause_event and self.render_context.pause_event.is_set():
44-
while self.render_context.pause_event.is_set():
43+
if self.render_context.enter_pause_event.is_set():
44+
self.render_context.event_bus.publish(RenderPaused())
45+
46+
while self.render_context.enter_pause_event.is_set():
4547
time.sleep(PAUSE_POLL_INTERVAL_SECONDS)
4648

4749
self.render_context.event_bus.publish(

render_machine/render_context.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def __init__(
5454
event_bus: EventBus,
5555
test_script_timeout: Optional[int] = None,
5656
stop_event: Optional[threading.Event] = None,
57-
pause_event: Optional[threading.Event] = None,
57+
enter_pause_event: Optional[threading.Event] = None,
5858
):
5959
self.codeplain_api: CodeplainAPI = codeplain_api
6060
self.memory_manager = memory_manager
@@ -78,7 +78,7 @@ def __init__(
7878
self.run_state = run_state
7979
self.event_bus = event_bus
8080
self.stop_event = stop_event
81-
self.pause_event = pause_event
81+
self.enter_pause_event = enter_pause_event
8282
self.script_execution_history = ScriptExecutionHistory()
8383
self.starting_frid = None
8484
self.test_script_timeout = test_script_timeout

tui/components.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ class ProgressItem(Vertical):
136136
COMPLETED = "COMPLETED"
137137
STOPPED = "STOPPED"
138138
PAUSED = "PAUSED"
139+
PAUSING = "PAUSING"
139140

140141
def __init__(self, initial_text: str, **kwargs):
141142
super().__init__(**kwargs)
@@ -159,7 +160,9 @@ def _get_status_text(self, status: str) -> str:
159160
elif status == self.STOPPED:
160161
return "◼ stopped"
161162
elif status == self.PAUSED:
162-
return "⏸ paused"
163+
return "⏸ paused - ready to resume"
164+
elif status == self.PAUSING:
165+
return "◉ pausing - please wait"
163166
else:
164167
return "○ pending"
165168

tui/plain2code_tui.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@
1515
RenderFailed,
1616
RenderModuleCompleted,
1717
RenderModuleStarted,
18+
RenderPaused,
1819
RenderStateUpdated,
1920
)
2021
from render_machine.states import States
21-
from tui.widget_helpers import log_to_widget, set_frid_progress_to_paused
22+
from tui.widget_helpers import log_to_widget, transition_frid_progress
2223

2324
from .components import (
2425
CustomFooter,
2526
FRIDProgress,
2627
LogFilterChanged,
2728
LogLevelFilter,
29+
ProgressItem,
2830
RenderingInfoBox,
2931
ScriptOutputType,
3032
StructuredLogView,
@@ -65,7 +67,7 @@ def __init__(
6567
conformance_tests_script: str,
6668
prepare_environment_script: str,
6769
state_machine_version: str,
68-
pause_event: threading.Event | None = None,
70+
enter_pause_event: threading.Event | None = None,
6971
**kwargs,
7072
):
7173
super().__init__(**kwargs)
@@ -77,7 +79,7 @@ def __init__(
7779
self.conformance_tests_script: Optional[str] = conformance_tests_script
7880
self.prepare_environment_script: Optional[str] = prepare_environment_script
7981
self.state_machine_version = state_machine_version
80-
self.pause_event = pause_event
82+
self.enter_pause_event = enter_pause_event
8183
self._render_finished = False
8284

8385
# Initialize state handlers
@@ -138,6 +140,7 @@ def dispatch_wrapper(fn):
138140
self.event_bus.subscribe(RenderModuleStarted, self.on_render_module_started)
139141
self.event_bus.subscribe(RenderModuleCompleted, self.on_render_module_completed)
140142
self.event_bus.subscribe(LogMessageEmitted, self.on_log_message_emitted)
143+
self.event_bus.subscribe(RenderPaused, self.on_render_paused)
141144

142145
self._on_ready()
143146

@@ -250,6 +253,10 @@ def _handle_frid_state(
250253

251254
self._state_completion_handler.handle(segments, snapshot, previous_state_segments)
252255

256+
def on_render_paused(self, event: RenderPaused):
257+
transition_frid_progress(self, ProgressItem.PAUSING, ProgressItem.PAUSED)
258+
pass
259+
253260
def on_render_completed(self, event: RenderCompleted):
254261
"""Handle successful render completion."""
255262
self._render_success_handler.handle(event.rendered_code_path)
@@ -284,13 +291,14 @@ async def action_copy_selection(self) -> None:
284291

285292
def action_pause(self) -> None:
286293
"""Handle ctrl+shift+p: request the render machine to pause."""
287-
if not self._render_finished and self.pause_event is not None:
288-
set_frid_progress_to_paused(self)
289-
290-
if self.pause_event.is_set():
291-
self.pause_event.clear()
294+
if not self._render_finished and self.enter_pause_event is not None:
295+
if self.enter_pause_event.is_set():
296+
transition_frid_progress(self, ProgressItem.PAUSED, ProgressItem.PROCESSING)
297+
transition_frid_progress(self, ProgressItem.PAUSING, ProgressItem.PROCESSING)
298+
self.enter_pause_event.clear()
292299
else:
293-
self.pause_event.set()
300+
transition_frid_progress(self, ProgressItem.PROCESSING, ProgressItem.PAUSING)
301+
self.enter_pause_event.set()
294302

295303
def action_enter_exit(self) -> None:
296304
"""Handle enter: exit the TUI only after rendering has finished."""

tui/state_handlers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
display_error_message,
1414
display_success_message,
1515
get_frid_progress,
16-
set_frid_progress_to_stopped,
16+
transition_frid_progress,
1717
update_progress_item_status,
1818
update_progress_item_substates,
1919
)
@@ -331,7 +331,7 @@ def __init__(self, tui):
331331
self.tui = tui
332332

333333
def handle(self, error_message: str) -> None:
334-
set_frid_progress_to_stopped(self.tui)
334+
transition_frid_progress(self.tui, None, ProgressItem.STOPPED)
335335
display_error_message(self.tui, error_message)
336336

337337

tui/styles.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,10 @@ TestScriptsContainer {
194194
background: #c77777;
195195
}
196196

197-
.status.PAUSED {
197+
.status.PAUSED,
198+
.status.PAUSING {
198199
color: #fff;
199-
background: #5b8bf5;
200+
background: #0a1fd5;
200201
}
201202

202203
.description {

tui/widget_helpers.py

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -111,32 +111,21 @@ def display_success_message(tui, rendered_code_path: str):
111111
widget.update(message)
112112

113113

114-
def set_frid_progress_to_stopped(tui):
115-
progress_ids = [
116-
TUIComponents.FRID_PROGRESS_RENDER_FR.value,
117-
TUIComponents.FRID_PROGRESS_UNIT_TEST.value,
118-
TUIComponents.FRID_PROGRESS_REFACTORING.value,
119-
TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value,
120-
]
121-
122-
for widget_id in progress_ids:
123-
update_progress_item_status(tui, widget_id, ProgressItem.STOPPED)
124-
clear_progress_item_substates(tui, widget_id)
125-
114+
FRID_PROGRESS_IDS = [
115+
TUIComponents.FRID_PROGRESS_RENDER_FR.value,
116+
TUIComponents.FRID_PROGRESS_UNIT_TEST.value,
117+
TUIComponents.FRID_PROGRESS_REFACTORING.value,
118+
TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value,
119+
]
126120

127-
def set_frid_progress_to_paused(tui):
128-
progress_ids = [
129-
TUIComponents.FRID_PROGRESS_RENDER_FR.value,
130-
TUIComponents.FRID_PROGRESS_UNIT_TEST.value,
131-
TUIComponents.FRID_PROGRESS_REFACTORING.value,
132-
TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value,
133-
]
134121

135-
for widget_id in progress_ids:
122+
def transition_frid_progress(tui, from_status: str | None, to_status: str):
123+
"""Transition all FRID progress items matching from_status to to_status."""
124+
for widget_id in FRID_PROGRESS_IDS:
136125
try:
137126
widget = tui.query_one(f"#{widget_id}", ProgressItem)
138-
if widget.current_status == ProgressItem.PROCESSING:
139-
update_progress_item_status(tui, widget_id, ProgressItem.PAUSED)
127+
if widget.current_status == from_status or from_status is None:
128+
update_progress_item_status(tui, widget_id, to_status)
140129
except Exception:
141130
pass
142131

0 commit comments

Comments
 (0)