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

View File

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