10
10
use AaronFrancis \Solo \Commands \Command ;
11
11
use AaronFrancis \Solo \Facades \Solo ;
12
12
use AaronFrancis \Solo \Support \Frames ;
13
+ use Carbon \CarbonImmutable ;
13
14
use Chewie \Concerns \CreatesAnAltScreen ;
14
15
use Chewie \Concerns \Loops ;
15
16
use Chewie \Concerns \RegistersRenderers ;
@@ -154,13 +155,7 @@ protected function showDashboard(): void
154
155
155
156
$ this ->currentCommand ()->focus ();
156
157
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 );
164
159
165
160
// @TODO reconsider using?
166
161
// $this->loopWithListener($listener, function () {
@@ -169,8 +164,19 @@ protected function showDashboard(): void
169
164
// });
170
165
}
171
166
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
+
172
176
public function quit (): void
173
177
{
178
+ $ initiated = CarbonImmutable::now ();
179
+
174
180
foreach ($ this ->commands as $ command ) {
175
181
/** @var Command $command */
176
182
@@ -179,17 +185,20 @@ public function quit(): void
179
185
$ command ->stop ();
180
186
}
181
187
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 ();
186
195
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 );
193
202
194
203
$ this ->terminal ()->exit ();
195
204
}
0 commit comments