Fix some more export bugs

This commit is contained in:
Alexander Rosenberg 2024-04-13 15:43:57 -07:00
parent da9a2acf4e
commit ab88ae4fac
Signed by: school-rpi4
GPG Key ID: 5CCFC80B0B47B04B
2 changed files with 40 additions and 38 deletions

View File

@ -152,15 +152,9 @@ static enum {
} export_confirm_action(ExportScreen *screen,
SensorState *state,
const char *fmt, ...) {
int done_status = EXPORT_CONFIRM_CONTINUE;
if (screen->current_op && export_check_bg_task(screen)) {
// background task done
done_status = EXPORT_CONFIRM_CONTINUE;
goto confirm_done;
}
int done_status;
if (state->back_down || (state->sel_down && !screen->confirm_state)) {
done_status = EXPORT_CONFIRM_NO;
screen->need_redraw = true;
goto confirm_done;
}
if (state->sel_down) {
@ -193,6 +187,7 @@ static enum {
lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF,
LCD_DISPLAY_ON);
screen->confirm_state = false;
screen->need_redraw = true;
return done_status;
}
@ -225,12 +220,14 @@ static const char BACKGROUND_CHARS[] = {
* True if done, false otherwise
*/
static bool export_do_background_action(ExportScreen *screen, SensorState *state) {
if (state->down_down || state->up_down || state->back_down ||
state->sel_down) {
screen->last_cancel_stage = screen->stage;
screen->stage = EXPORT_SCREEN_CONFIRM_CANCEL;
if (!screen->show_cancel_screen && (state->down_down || state->up_down ||
state->back_down || state->sel_down)) {
screen->show_cancel_screen = true;
screen->need_redraw = true;
return false;
// we need to make sure that the confirm action screen ignores actions
// for this iteration of the UI loop
state->back_down = state->up_down =
state->sel_down = state->down_down = false;
}
if (!screen->current_op) {
screen->stage = EXPORT_SCREEN_FAILED;
@ -240,16 +237,32 @@ static bool export_do_background_action(ExportScreen *screen, SensorState *state
if (export_check_bg_task(screen)) {
return true;
}
time_t now = time(NULL);
if (screen->need_redraw || now != screen->last_char_change) {
lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF,
LCD_DISPLAY_ON);
screen->last_char_change = now;
screen->need_redraw = false;
lcd_clear(state->lcd);
lcd_move_to(state->lcd, 0, 0);
lcd_write_string(state->lcd, "Working");
lcd_write_char(state->lcd, BACKGROUND_CHARS[screen->working_char++ % NBACKGROUND_CHAR]);
if (screen->show_cancel_screen) {
int confirm_status = export_confirm_action(screen, state, "Really cancel?");
if (confirm_status == EXPORT_CONFIRM_YES) {
async_operation_free(screen->current_op);
screen->current_op = NULL;
AsyncOperation *op = drive_unmount(&screen->drives[screen->cur_drive], true);
async_operation_poll(op, true);
async_operation_free(op);
screen->stage = EXPORT_SCREEN_CANCELED;
screen->need_redraw = true;
} else if (confirm_status == EXPORT_CONFIRM_NO) {
screen->need_redraw = true;
screen->show_cancel_screen = false;
}
} else {
time_t now = time(NULL);
if (screen->need_redraw || now != screen->last_char_change) {
lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF,
LCD_DISPLAY_ON);
screen->last_char_change = now;
screen->need_redraw = false;
lcd_clear(state->lcd);
lcd_move_to(state->lcd, 0, 0);
lcd_write_string(state->lcd, "Working");
lcd_write_char(state->lcd, BACKGROUND_CHARS[screen->working_char++ % NBACKGROUND_CHAR]);
}
}
return false;
}
@ -291,6 +304,7 @@ static void export_handle_write(ExportScreen *screen, SensorState *state) {
return;
}
// if we have no current op, start a new one
screen->show_cancel_screen = false;
pid_t pid = fork();
if (pid < 0) {
warn("failed to start write background task");
@ -344,6 +358,7 @@ static bool export_screen_dispatch(ExportScreen *screen,
case EXPORT_SCREEN_WRITE_NEWFS:
if (!screen->current_op) {
screen->current_op = drive_newfs_msdos(cur_drive);
screen->show_cancel_screen = false;
}
if (export_do_background_action(screen, state)) {
screen->stage = EXPORT_SCREEN_MOUNTING;
@ -353,6 +368,7 @@ static bool export_screen_dispatch(ExportScreen *screen,
case EXPORT_SCREEN_MOUNTING:
if (!screen->current_op) {
screen->current_op = drive_mount(cur_drive);
screen->show_cancel_screen = false;
}
if (export_do_background_action(screen, state)) {
char *path = export_build_cur_path(screen);
@ -387,27 +403,13 @@ static bool export_screen_dispatch(ExportScreen *screen,
case EXPORT_SCREEN_UNMOUNT:
if (!screen->current_op) {
screen->current_op = drive_unmount(cur_drive, false);
screen->show_cancel_screen = false;
}
if (export_do_background_action(screen, state)) {
screen->stage = EXPORT_SCREEN_DONE;
screen->need_redraw = true;
}
break;
case EXPORT_SCREEN_CONFIRM_CANCEL:
confirm_status = export_confirm_action(screen, state, "Really cancel?");
if (confirm_status == EXPORT_CONFIRM_YES) {
async_operation_free(screen->current_op);
screen->current_op = NULL;
AsyncOperation *op = drive_unmount(cur_drive, true);
async_operation_poll(op, true);
async_operation_free(op);
screen->stage = EXPORT_SCREEN_CANCELED;
screen->need_redraw = true;
} else if (confirm_status == EXPORT_CONFIRM_NO) {
screen->stage = screen->last_cancel_stage;
screen->need_redraw = true;
}
break;
case EXPORT_SCREEN_CANCELED:
return export_show_message(screen, state, "Cancelled!");
case EXPORT_SCREEN_FAILED:

View File

@ -30,7 +30,6 @@ typedef struct {
EXPORT_SCREEN_WRITING,
EXPORT_SCREEN_UNMOUNT,
EXPORT_SCREEN_DONE,
EXPORT_SCREEN_CONFIRM_CANCEL,
EXPORT_SCREEN_CANCELED,
EXPORT_SCREEN_FAILED,
EXPORT_SCREEN_NO_DRIVES,
@ -54,6 +53,7 @@ typedef struct {
sqlite3 *db_cache;
int last_cancel_stage;
AsyncOperation *current_op;
bool show_cancel_screen;
} ExportScreen;
ExportScreen *export_screen_new(void);