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:
- Added a
WaitingConfirmationViewfor user interactions - Created a
PausedViewwith its own status display and controls - Implemented a central
DispatchMenufor process control - Added proper
RuntimeSettingsfor adjusting parameters mid-process
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.