diff --git a/protopirate_app.c b/protopirate_app.c index 4a864f0..0ab3b3a 100644 --- a/protopirate_app.c +++ b/protopirate_app.c @@ -172,6 +172,7 @@ ProtoPirateApp* protopirate_app_alloc() { app->setting = subghz_setting_alloc(); app->loaded_file_path = NULL; app->start_tx_time = 0; + app->deferred_storage_timer = NULL; subghz_setting_load(app->setting, EXT_PATH("subghz/assets/setting_user")); // Apply loaded frequency and preset, with validation diff --git a/protopirate_app_i.h b/protopirate_app_i.h index 3c453ba..2450738 100644 --- a/protopirate_app_i.h +++ b/protopirate_app_i.h @@ -82,10 +82,12 @@ struct ProtoPirateApp { View* view_about; FuriString* file_path; ProtoPirateReceiver* protopirate_receiver; + FuriTimer* deferred_storage_timer; ProtoPirateTxRx* txrx; SubGhzSetting* setting; ProtoPirateLock lock; FuriString* loaded_file_path; + bool deferred_storage_in_progress; bool auto_save; bool check_saved; bool sound; diff --git a/scenes/protopirate_scene_receiver.c b/scenes/protopirate_scene_receiver.c index 14862e4..1246499 100644 --- a/scenes/protopirate_scene_receiver.c +++ b/scenes/protopirate_scene_receiver.c @@ -9,9 +9,12 @@ #define TAG "ProtoPirateSceneRx" +#define DEFERRED_STORAGE_TIME 1000 + // Forward declaration void protopirate_scene_receiver_view_callback(ProtoPirateCustomEvent event, void* context); static void protopirate_scene_receiver_start_rx_stack(ProtoPirateApp* app); +static void protopirate_scene_receiver_process_deferred_storage(ProtoPirateApp* app); static void protopirate_scene_receiver_update_statusbar(void* context) { furi_check(context); @@ -51,6 +54,10 @@ static void protopirate_scene_receiver_callback( FURI_LOG_I(TAG, "=== SIGNAL DECODED (%s) ===", decoder_base->protocol->name); + //If save is happening, dont attempt to add to history yet. + while(app->deferred_storage_in_progress) + furi_delay_ms(25); + uint16_t count_before = protopirate_history_get_item(app->txrx->history); bool added = protopirate_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset); @@ -76,11 +83,21 @@ static void protopirate_scene_receiver_callback( protopirate_view_receiver_set_idx_menu(app->protopirate_receiver, last_index); uint16_t new_idx = protopirate_history_get_item(app->txrx->history) - 1; + + bool start_timer = false; if(app->auto_save) { protopirate_history_mark_auto_save_pending(app->txrx->history, new_idx); + start_timer = true; } if(app->check_saved) { protopirate_history_mark_saved_match_pending(app->txrx->history, new_idx); + start_timer = true; + } + + //Restart the timer. + if(start_timer) { + furi_timer_stop(app->deferred_storage_timer); + furi_timer_start(app->deferred_storage_timer, DEFERRED_STORAGE_TIME); } view_dispatcher_send_custom_event( @@ -206,11 +223,15 @@ static void protopirate_scene_receiver_process_saved_match(ProtoPirateApp* app) } static void protopirate_scene_receiver_process_deferred_storage(ProtoPirateApp* app) { + app->deferred_storage_in_progress = true; if(protopirate_scene_receiver_process_auto_save(app)) { return; } protopirate_scene_receiver_process_saved_match(app); + + furi_timer_stop(app->deferred_storage_timer); + app->deferred_storage_in_progress = false; } static bool protopirate_scene_receiver_bind_rx_stack(ProtoPirateApp* app) { @@ -271,6 +292,10 @@ static void protopirate_scene_receiver_start_rx_stack(ProtoPirateApp* app) { FURI_LOG_I(TAG, "RX started, state: %d", app->txrx->txrx_state); } +void deferred_storage_timer_callback(void* app) { + protopirate_scene_receiver_process_deferred_storage(app); +} + void protopirate_scene_receiver_on_enter(void* context) { furi_check(context); ProtoPirateApp* app = context; @@ -314,6 +339,9 @@ void protopirate_scene_receiver_on_enter(void* context) { protopirate_scene_receiver_update_statusbar(app); + app->deferred_storage_timer = + furi_timer_alloc(deferred_storage_timer_callback, FuriTimerTypePeriodic, app); + #ifndef REMOVE_LOGS bool is_external = app->txrx->radio_device ? radio_device_loader_is_external(app->txrx->radio_device) : false; @@ -424,8 +452,6 @@ bool protopirate_scene_receiver_on_event(void* context, SceneManagerEvent event) break; } } else if(event.type == SceneManagerEventTypeTick) { - protopirate_scene_receiver_process_deferred_storage(app); - if(app->txrx->hopper_state != ProtoPirateHopperStateOFF) { if(protopirate_hopper_update(app) && protopirate_scene_receiver_bind_rx_stack(app)) { protopirate_rx(app, app->txrx->preset->frequency); @@ -467,6 +493,9 @@ void protopirate_scene_receiver_on_exit(void* context) { ProtoPirateApp* app = context; FURI_LOG_I(TAG, "=== EXITING RECEIVER SCENE ==="); + furi_timer_stop(app->deferred_storage_timer); + furi_timer_free(app->deferred_storage_timer); + app->deferred_storage_timer = NULL; const bool leaving_for_subscene = (scene_manager_get_scene_state(app->scene_manager, ProtoPirateSceneReceiver) == 1);