diff options
-rw-r--r-- | dive.h | 16 | ||||
-rw-r--r-- | gtk-gui.c | 81 | ||||
-rw-r--r-- | planner.c | 16 |
3 files changed, 91 insertions, 22 deletions
@@ -578,7 +578,23 @@ extern void dump_tissues(void); extern unsigned int deco_allowed_depth(double tissues_tolerance, double surface_pressure, struct dive *dive, gboolean smooth); extern void set_gf(double gflow, double gfhigh); +struct divedatapoint { + int time; + int depth; + int o2; + int he; + struct divedatapoint *next; +}; + +struct diveplan { + timestamp_t when; + int surface_pressure; + struct divedatapoint *dp; +}; + extern void test_planner(void); +void plan(struct diveplan *diveplan); +void plan_add_segment(struct diveplan *diveplan, int duration, int depth, int o2, int he); #ifdef DEBUGFILE extern char *debugfilename; @@ -11,6 +11,7 @@ #include <time.h> #include <unistd.h> #include <sys/stat.h> +#include <sys/time.h> #include <ctype.h> #include "dive.h" @@ -1129,6 +1130,22 @@ static void test_planner_cb(GtkWidget *w, gpointer data) test_planner(); } +static void check_last_not_empty(GtkTreeModel *model, GtkTreeIter *iter, const char *text) +{ + /* We only add a new empty entry if the current one isn't empty.. */ + while (isspace(*text)) + text++; + if (!*text) + return; + + /* Is there a 'next' entry? */ + if (gtk_tree_model_iter_next(model, iter)) + return; + + /* Ok, let's add a new empty entry at the end, then.. */ + gtk_list_store_append(GTK_LIST_STORE(model), iter); +} + /* * Get a value in tenths (so "10.2" == 102, "9" = 90) * @@ -1165,10 +1182,13 @@ static int get_permille(char *begin, char **end) return value; } -static int get_gas(char *text, int *o2_p, int *he_p) +static int validate_gas(char *text, int *o2_p, int *he_p) { int o2, he; + if (!text) + return 0; + while (isspace(*text)) text++; @@ -1212,11 +1232,12 @@ static void plan_gas_cb(GtkCellRendererText *cell, gchar *path, gchar *text, gpo return; /* Verify that it's an acceptable gas */ - if (!get_gas(text, &o2, &he)) + if (!validate_gas(text, &o2, &he)) return; /* Ok, looks fine, accept the string */ gtk_list_store_set(GTK_LIST_STORE(model), &iter, 2, text, -1); + check_last_not_empty(model, &iter, text); } static int validate_time(char *text, int *sec_p, int *rel_p) @@ -1224,6 +1245,9 @@ static int validate_time(char *text, int *sec_p, int *rel_p) int min, sec, rel; char *end; + if (!text) + return 0; + while (isspace(*text)) text++; @@ -1295,12 +1319,16 @@ static void plan_time_cb(GtkCellRendererText *cell, gchar *path, gchar *text, gp /* Ok, looks fine, accept the string */ gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, text, -1); + check_last_not_empty(model, &iter, text); } static int validate_depth(char *text, int *mm_p) { int depth, imperial; + if (!text) + return 0; + depth = get_tenths(text, &text); if (depth < 0) return 0; @@ -1346,8 +1374,49 @@ static void plan_depth_cb(GtkCellRendererText *cell, gchar *path, gchar *text, g /* Ok, looks fine, accept the string */ gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, text, -1); + check_last_not_empty(model, &iter, text); } +static void run_diveplan(GtkListStore *store) +{ + GtkTreeModel *model = GTK_TREE_MODEL(store); + struct diveplan diveplan = {}; + struct timeval tv; + GtkTreeIter iter; + int ok; + int lasttime = 0; + + gettimeofday(&tv, NULL); + diveplan.when = tv.tv_sec; + diveplan.surface_pressure = 1013; + + ok = gtk_tree_model_get_iter_first(model, &iter); + while (ok) { + gchar *time, *depth, *gas; + int sec, rel, mm, o2, he; + + gtk_tree_model_get(model, &iter, + 0, &time, + 1, &depth, + 2, &gas, + -1); + if (!validate_time(time, &sec, &rel)) + goto next; + if (rel) + sec += lasttime; + if (!validate_depth(depth, &mm)) + goto next; + if (!validate_gas(gas, &o2, &he)) + goto next; + + plan_add_segment(&diveplan, sec, mm, o2, he); +next: + lasttime = sec; + g_free(time); g_free(depth); g_free(gas); + ok = gtk_tree_model_iter_next(model, &iter); + } + plan(&diveplan); +} void input_plan() { @@ -1365,12 +1434,8 @@ void input_plan() container = gtk_dialog_get_content_area(GTK_DIALOG(planner)); store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + /* We always have an empty entry at the end */ gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, - 0, "7:30", - 1, "100 ft", - 2, "20/30", - -1); view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); g_object_unref(store); @@ -1383,7 +1448,7 @@ void input_plan() gtk_widget_show_all(planner); if (gtk_dialog_run(GTK_DIALOG(planner)) == GTK_RESPONSE_ACCEPT) { - // run plan + run_diveplan(store); } gtk_widget_destroy(planner); } @@ -10,20 +10,6 @@ int stoplevels[] = { 3000, 6000, 9000, 12000, 15000, 21000, 30000, 42000, 60000, 90000 }; -struct divedatapoint { - int time; - int depth; - int o2; - int he; - struct divedatapoint *next; -}; - -struct diveplan { - timestamp_t when; - int surface_pressure; - struct divedatapoint *dp; -}; - /* returns the tissue tolerance at the end of this (partial) dive */ double tissue_at_end(struct dive *dive) { @@ -189,6 +175,8 @@ void plan(struct diveplan *diveplan) if (!diveplan->surface_pressure) diveplan->surface_pressure = 1013; dive = create_dive_from_plan(diveplan); + if (!dive) + return; record_dive(dive); sample = &dive->dc.sample[dive->dc.samples - 1]; |