Scapegoat TIL

DEV - Refactoring my film development flipper zero application

Today I made several significant improvements to my film development application's architecture and user experience. Let me walk you through the key changes:

1. State Machine Refinement

The biggest architectural change was introducing a cleaner separation between process states and view states. The application now has four distinct process states:

NotStarted -> Running -> Paused -> WaitingForUser

This is managed separately from the view states (ProcessSelection, MainView, Settings, etc.), making the codebase more maintainable and reducing bugs from intermingled concerns.

2. View Navigation and User Flow

I completely revamped the navigation with dedicated views:

The most interesting UX change was modifying how the back button works in paused state - instead of showing an exit dialog, it now resumes the process, which feels more intuitive during development.

3. State Transitions

I extracted state transition logic into a dedicated method:

void enter_state(AppState new_state) {
    FURI_LOG_D(
        "FilmDev",
        "State transition: %s -> %s",
        get_state_name(current_state),
        get_state_name(new_state));
    
    previous_state = current_state;
    current_state = new_state;
}

This centralized approach improves logging and maintainability, while making state transitions more predictable.

4. Model Changes

I moved to a protected model pattern where state access is controlled through lock guards:

auto model = this->model.lock();
if(model->is_process_active()) {
    // Safe state access
}

This prevents race conditions and makes the application more robust when handling timer-based updates and user interactions.