@@ -292,24 +292,15 @@ bool loader_get_application_name(Loader* loader, FuriString* name) {
292
292
return result .value ;
293
293
}
294
294
295
- bool loader_launch_app_after_current (
296
- Loader * loader ,
297
- const char * name ,
298
- const char * args ,
299
- LoaderDeferredLaunchErrorReport error_report ) {
295
+ bool loader_get_application_launch_path (Loader * loader , FuriString * name ) {
300
296
furi_check (loader );
301
297
302
298
LoaderMessageBoolResult result ;
303
299
304
300
LoaderMessage message = {
305
- .type = LoaderMessageTypeRememberNextApp ,
301
+ .type = LoaderMessageTypeGetApplicationLaunchPath ,
306
302
.api_lock = api_lock_alloc_locked (),
307
- .defer_start =
308
- {
309
- .name = name ,
310
- .args = args ,
311
- .error_report = error_report ,
312
- },
303
+ .application_name = name ,
313
304
.bool_value = & result ,
314
305
};
315
306
@@ -319,30 +310,38 @@ bool loader_launch_app_after_current(
319
310
return result .value ;
320
311
}
321
312
322
- bool loader_launch_current_app_after_deferred (
313
+ void loader_enqueue_launch (
323
314
Loader * loader ,
315
+ const char * name ,
324
316
const char * args ,
325
- LoaderDeferredLaunchErrorReport error_report ) {
317
+ LoaderDeferredLaunchFlag flags ) {
326
318
furi_check (loader );
327
319
328
- LoaderMessageBoolResult result ;
329
-
330
320
LoaderMessage message = {
331
- .type = LoaderMessageTypeStartSelfAfterDeferred ,
321
+ .type = LoaderMessageTypeEnqueueLaunch ,
332
322
.api_lock = api_lock_alloc_locked (),
333
323
.defer_start =
334
324
{
335
- /* name unset */
325
+ . name = name ,
336
326
.args = args ,
337
- .error_report = error_report ,
327
+ .flags = flags ,
338
328
},
339
- .bool_value = & result ,
340
329
};
341
330
342
331
furi_message_queue_put (loader -> queue , & message , FuriWaitForever );
343
332
api_lock_wait_unlock_and_free (message .api_lock );
333
+ }
344
334
345
- return result .value ;
335
+ void loader_clear_launch_queue (Loader * loader ) {
336
+ furi_check (loader );
337
+
338
+ LoaderMessage message = {
339
+ .type = LoaderMessageTypeClearLaunchQueue ,
340
+ .api_lock = api_lock_alloc_locked (),
341
+ };
342
+
343
+ furi_message_queue_put (loader -> queue , & message , FuriWaitForever );
344
+ api_lock_wait_unlock_and_free (message .api_lock );
346
345
}
347
346
348
347
// callbacks
@@ -377,26 +376,14 @@ static void
377
376
378
377
// implementation
379
378
380
- static void loader_deferred_launch_data_init (LoaderDeferredLaunchData * data ) {
381
- if (!data -> name_or_path ) data -> name_or_path = furi_string_alloc ();
382
- if (!data -> args ) data -> args = furi_string_alloc ();
383
- }
384
-
385
- static void loader_deferred_launch_data_reset (LoaderDeferredLaunchData * data ) {
386
- furi_string_free (data -> name_or_path );
387
- furi_string_free (data -> args );
388
- data -> name_or_path = NULL ;
389
- data -> args = NULL ;
390
- data -> do_launch = false;
391
- }
392
-
393
379
static Loader * loader_alloc (void ) {
394
380
Loader * loader = malloc (sizeof (Loader ));
395
381
loader -> pubsub = furi_pubsub_alloc ();
396
382
loader -> queue = furi_message_queue_alloc (1 , sizeof (LoaderMessage ));
397
383
loader -> gui = furi_record_open (RECORD_GUI );
398
384
loader -> view_holder = view_holder_alloc ();
399
385
loader -> loading = loading_alloc ();
386
+ LoaderDeferredLaunchRecordArray_init (loader -> launch_queue );
400
387
view_holder_attach_to_gui (loader -> view_holder , loader -> gui );
401
388
return loader ;
402
389
}
@@ -741,39 +728,29 @@ static void loader_do_unlock(Loader* loader) {
741
728
loader -> app .thread = NULL ;
742
729
}
743
730
744
- static bool loader_do_deferred_launch (
745
- Loader * loader ,
746
- LoaderDeferredLaunchData * launch_data ,
747
- LoaderDeferredLaunchData * error_report_launch_data ) {
748
- furi_assert (launch_data );
731
+ static bool loader_do_deferred_launch (Loader * loader , LoaderDeferredLaunchRecord * record ) {
732
+ furi_assert (loader );
733
+ furi_assert (record );
749
734
750
735
bool is_successful = false;
751
736
FuriString * error_message = furi_string_alloc ();
752
737
view_holder_set_view (loader -> view_holder , loading_get_view (loader -> loading ));
753
738
view_holder_send_to_front (loader -> view_holder );
754
739
755
740
do {
756
- const char * app_name_str = furi_string_get_cstr (launch_data -> name_or_path );
757
- const char * app_args = furi_string_get_cstr (launch_data -> args );
758
- FURI_LOG_I (TAG , "Autonomous launch: %s" , app_name_str );
741
+ const char * app_name_str = furi_string_get_cstr (record -> name_or_path );
742
+ const char * app_args = furi_string_get_cstr (record -> args );
743
+ FURI_LOG_I (TAG , "Deferred launch: %s" , app_name_str );
759
744
760
745
LoaderMessageLoaderStatusResult result =
761
746
loader_do_start_by_name (loader , app_name_str , app_args , error_message );
762
747
if (result .value == LoaderStatusOk ) {
763
748
is_successful = true;
749
+ break ;
764
750
}
765
751
766
- if (launch_data -> error_report & LoaderDeferredLaunchErrorReportGui )
752
+ if (record -> flags & LoaderDeferredLaunchFlagGui )
767
753
loader_show_gui_error (result , app_name_str , error_message );
768
-
769
- if ((launch_data -> error_report & LoaderDeferredLaunchErrorReportArgs ) &&
770
- error_report_launch_data ) {
771
- furi_string_printf (
772
- error_report_launch_data -> args ,
773
- "loader:deferred_launch_err:%s" ,
774
- furi_string_get_cstr (error_message ));
775
- loader_do_deferred_launch (loader , error_report_launch_data , NULL );
776
- }
777
754
} while (false);
778
755
779
756
view_holder_set_view (loader -> view_holder , NULL );
@@ -813,15 +790,10 @@ static void loader_do_app_closed(Loader* loader) {
813
790
event .type = LoaderEventTypeApplicationStopped ;
814
791
furi_pubsub_publish (loader -> pubsub , & event );
815
792
816
- if (loader -> chain .next .do_launch ) {
817
- loader -> chain .next .do_launch = false;
818
- if (!loader_do_deferred_launch (loader , & loader -> chain .next , & loader -> chain .previous ))
819
- loader_deferred_launch_data_reset (& loader -> chain .previous );
820
- loader_deferred_launch_data_reset (& loader -> chain .next );
821
- } else if (loader -> chain .previous .do_launch ) {
822
- loader -> chain .previous .do_launch = false;
823
- loader_do_deferred_launch (loader , & loader -> chain .previous , NULL );
824
- loader_deferred_launch_data_reset (& loader -> chain .previous );
793
+ if (LoaderDeferredLaunchRecordArray_size (loader -> launch_queue )) {
794
+ loader_do_deferred_launch (
795
+ loader , LoaderDeferredLaunchRecordArray_front (loader -> launch_queue ));
796
+ LoaderDeferredLaunchRecordArray_pop_at (NULL , loader -> launch_queue , 0 );
825
797
}
826
798
}
827
799
@@ -847,48 +819,25 @@ static bool loader_do_get_application_name(Loader* loader, FuriString* name) {
847
819
return false;
848
820
}
849
821
850
- static bool loader_do_remember_next_app (Loader * loader , LoaderMessageDeferStart defer_start ) {
851
- if (!loader_is_application_running (loader )) return false;
852
- if (!loader -> chain .next .do_launch && loader -> chain .previous .do_launch ) return false;
853
-
854
- if (defer_start .name ) {
855
- loader_deferred_launch_data_init (& loader -> chain .previous );
856
- loader_deferred_launch_data_init (& loader -> chain .next );
857
- loader -> chain .next .do_launch = true;
858
-
859
- furi_string_set (loader -> chain .previous .name_or_path , loader -> app .launch_path );
860
- furi_string_set_str (loader -> chain .next .name_or_path , defer_start .name );
861
- loader -> chain .next .error_report = defer_start .error_report ;
862
-
863
- if (defer_start .args )
864
- furi_string_set_str (loader -> chain .next .args , defer_start .args );
865
- else
866
- furi_string_reset (loader -> chain .next .args );
867
- } else {
868
- loader_deferred_launch_data_reset (& loader -> chain .previous );
869
- loader_deferred_launch_data_reset (& loader -> chain .next );
822
+ static bool loader_do_get_application_launch_path (Loader * loader , FuriString * path ) {
823
+ if (loader_is_application_running (loader )) {
824
+ furi_string_set (path , loader -> app .launch_path );
825
+ return true;
870
826
}
871
827
872
- return true ;
828
+ return false ;
873
829
}
874
830
875
- static bool
876
- loader_do_remember_to_launch_current (Loader * loader , LoaderMessageDeferStart defer_start ) {
877
- if (!loader_is_application_running (loader )) return false;
878
- if (!loader -> chain .next .do_launch ) return false;
879
- if (defer_start .error_report & LoaderDeferredLaunchErrorReportArgs ) return false;
880
-
881
- loader_deferred_launch_data_init (& loader -> chain .previous );
882
- loader -> chain .previous .do_launch = true;
883
-
884
- loader -> chain .previous .error_report = defer_start .error_report ;
831
+ static void loader_do_enqueue_launch (Loader * loader , LoaderMessageDeferStart * data ) {
832
+ furi_check (LoaderDeferredLaunchRecordArray_size (loader -> launch_queue ) < LAUNCH_QUEUE_MAX_SIZE );
885
833
886
- if (defer_start .args )
887
- furi_string_set_str (loader -> chain .previous .args , defer_start .args );
888
- else
889
- furi_string_reset (loader -> chain .previous .args );
890
-
891
- return true;
834
+ LoaderDeferredLaunchRecordArray_push_back (
835
+ loader -> launch_queue ,
836
+ (LoaderDeferredLaunchRecord ){
837
+ .name_or_path = furi_string_alloc_set_str (data -> name ),
838
+ .args = data -> args ? furi_string_alloc_set_str (data -> args ) : furi_string_alloc (),
839
+ .flags = data -> flags ,
840
+ });
892
841
}
893
842
894
843
// app
@@ -961,14 +910,17 @@ int32_t loader_srv(void* p) {
961
910
loader_do_get_application_name (loader , message .application_name );
962
911
api_lock_unlock (message .api_lock );
963
912
break ;
964
- case LoaderMessageTypeRememberNextApp :
913
+ case LoaderMessageTypeGetApplicationLaunchPath :
965
914
message .bool_value -> value =
966
- loader_do_remember_next_app (loader , message .defer_start );
915
+ loader_do_get_application_launch_path (loader , message .application_name );
967
916
api_lock_unlock (message .api_lock );
968
917
break ;
969
- case LoaderMessageTypeStartSelfAfterDeferred :
970
- message .bool_value -> value =
971
- loader_do_remember_to_launch_current (loader , message .defer_start );
918
+ case LoaderMessageTypeEnqueueLaunch :
919
+ loader_do_enqueue_launch (loader , & message .defer_start );
920
+ api_lock_unlock (message .api_lock );
921
+ break ;
922
+ case LoaderMessageTypeClearLaunchQueue :
923
+ LoaderDeferredLaunchRecordArray_reset (loader -> launch_queue );
972
924
api_lock_unlock (message .api_lock );
973
925
break ;
974
926
}
0 commit comments