1010use AaronFrancis \Solo \Commands \Command ;
1111use AaronFrancis \Solo \Facades \Solo ;
1212use AaronFrancis \Solo \Support \Frames ;
13+ use Carbon \CarbonImmutable ;
1314use Chewie \Concerns \CreatesAnAltScreen ;
1415use Chewie \Concerns \Loops ;
1516use Chewie \Concerns \RegistersRenderers ;
@@ -154,13 +155,7 @@ protected function showDashboard(): void
154155
155156 $ this ->currentCommand ()->focus ();
156157
157- $ this ->loop (function () use ($ listener ) {
158- $ this ->currentCommand ()->catchUpScroll ();
159- $ this ->render ();
160-
161- $ listener ->once ();
162- $ this ->frames ->next ();
163- }, 25_000 );
158+ $ this ->loop (fn () => $ this ->loopCallback ($ listener ), 25_000 );
164159
165160 // @TODO reconsider using?
166161 // $this->loopWithListener($listener, function () {
@@ -169,8 +164,19 @@ protected function showDashboard(): void
169164 // });
170165 }
171166
167+ public function loopCallback (?KeyPressListener $ listener = null )
168+ {
169+ $ this ->currentCommand ()->catchUpScroll ();
170+ $ this ->render ();
171+
172+ $ listener ?->once();
173+ $ this ->frames ->next ();
174+ }
175+
172176 public function quit (): void
173177 {
178+ $ initiated = CarbonImmutable::now ();
179+
174180 foreach ($ this ->commands as $ command ) {
175181 /** @var Command $command */
176182
@@ -179,17 +185,20 @@ public function quit(): void
179185 $ command ->stop ();
180186 }
181187
182- while (true ) {
183- $ any = array_reduce ($ this ->commands , function ($ carry , $ command ) {
184- return $ carry || $ command ->processRunning ();
185- }, false );
188+ // We do need to continue looping though, because the `marshalRogueProcess` runs
189+ // in the loop. We'll break the loop after all processes are dead or after
190+ // 3 seconds. If all the processes aren't dead after three seconds then
191+ // the monitoring process should clean it up in the background.
192+ $ this ->loop (function () use ($ initiated ) {
193+ // Run the renderer so it doesn't look like Solo is frozen.
194+ $ this ->loopCallback ();
186195
187- if ( $ any ) {
188- Sleep:: for ( 100 )-> milliseconds ();
189- } else {
190- break ;
191- }
192- }
196+ $ allDead = array_reduce ( $ this -> commands , function ( $ carry , Command $ command ) {
197+ return $ carry && $ command -> processStopped ();
198+ }, true );
199+
200+ return !( $ allDead || $ initiated -> addSeconds ( 3 )-> isPast ());
201+ }, 25_000 );
193202
194203 $ this ->terminal ()->exit ();
195204 }
0 commit comments