diff --git a/commands/command_event.cpp b/commands/command_event.cpp index 391dfe0a9..11b9a56fc 100644 --- a/commands/command_event.cpp +++ b/commands/command_event.cpp @@ -2,6 +2,7 @@ #include "command_event.h" #include "core/dive.h" +#include "core/event.h" #include "core/selection.h" #include "core/subsurface-qt/divelistnotifier.h" #include "core/libdivecomputer.h" diff --git a/commands/command_event.h b/commands/command_event.h index b7e67f218..b9662ecd4 100644 --- a/commands/command_event.h +++ b/commands/command_event.h @@ -6,7 +6,6 @@ #include "command_base.h" - // We put everything in a namespace, so that we can shorten names without polluting the global namespace namespace Command { diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 079d1a1fe..08fca0864 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -77,6 +77,8 @@ set(SUBSURFACE_CORE_LIB_SRCS divesitehelpers.h downloadfromdcthread.cpp downloadfromdcthread.h + event.c + event.h equipment.c equipment.h errorhelper.c diff --git a/core/dive.c b/core/dive.c index f25864905..a9c69a3b0 100644 --- a/core/dive.c +++ b/core/dive.c @@ -13,6 +13,7 @@ #include "divelist.h" #include "divesite.h" #include "errorhelper.h" +#include "event.h" #include "qthelper.h" #include "membuffer.h" #include "picture.h" @@ -21,7 +22,6 @@ #include "structured_list.h" #include "fulltext.h" - /* one could argue about the best place to have this variable - * it's used in the UI, but it seems to make the most sense to have it * here */ @@ -123,58 +123,6 @@ int legacy_format_o2pressures(const struct dive *dive, const struct divecomputer return o2sensor < 0 ? 256 : o2sensor; } -int event_is_gaschange(const struct event *ev) -{ - return ev->type == SAMPLE_EVENT_GASCHANGE || - ev->type == SAMPLE_EVENT_GASCHANGE2; -} - -bool event_is_divemodechange(const struct event *ev) -{ - return same_string(ev->name, "modechange"); -} - -struct event *create_event(unsigned int time, int type, int flags, int value, const char *name) -{ - int gas_index = -1; - struct event *ev; - unsigned int size, len = strlen(name); - - size = sizeof(*ev) + len + 1; - ev = malloc(size); - if (!ev) - return NULL; - memset(ev, 0, size); - memcpy(ev->name, name, len); - ev->time.seconds = time; - ev->type = type; - ev->flags = flags; - ev->value = value; - - /* - * Expand the events into a sane format. Currently - * just gas switches - */ - switch (type) { - case SAMPLE_EVENT_GASCHANGE2: - /* High 16 bits are He percentage */ - ev->gas.mix.he.permille = (value >> 16) * 10; - - /* Extension to the GASCHANGE2 format: cylinder index in 'flags' */ - /* TODO: verify that gas_index < num_cylinders. */ - if (flags > 0) - gas_index = flags-1; - /* Fallthrough */ - case SAMPLE_EVENT_GASCHANGE: - /* Low 16 bits are O2 percentage */ - ev->gas.mix.o2.permille = (value & 0xffff) * 10; - ev->gas.index = gas_index; - break; - } - - return ev; -} - /* warning: does not test idx for validity */ struct event *create_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx) { @@ -195,11 +143,6 @@ struct event *create_gas_switch_event(struct dive *dive, struct divecomputer *dc return ev; } -struct event *clone_event_rename(const struct event *ev, const char *name) -{ - return create_event(ev->time.seconds, ev->type, ev->flags, ev->value, name); -} - void add_event_to_dc(struct divecomputer *dc, struct event *ev) { struct event **p; @@ -253,19 +196,6 @@ void swap_event(struct divecomputer *dc, struct event *from, struct event *to) } } -bool same_event(const struct event *a, const struct event *b) -{ - if (a->time.seconds != b->time.seconds) - return 0; - if (a->type != b->type) - return 0; - if (a->flags != b->flags) - return 0; - if (a->value != b->value) - return 0; - return !strcmp(a->name, b->name); -} - /* Remove given event from dive computer. Does *not* free the event. */ void remove_event_from_dc(struct divecomputer *dc, struct event *event) { @@ -546,22 +476,6 @@ void selective_copy_dive(const struct dive *s, struct dive *d, struct dive_compo } #undef CONDITIONAL_COPY_STRING -struct event *clone_event(const struct event *src_ev) -{ - struct event *ev; - if (!src_ev) - return NULL; - - size_t size = sizeof(*src_ev) + strlen(src_ev->name) + 1; - ev = (struct event*) malloc(size); - if (!ev) - exit(1); - memcpy(ev, src_ev, size); - ev->next = NULL; - - return ev; -} - /* copies all events in this dive computer */ void copy_events(const struct divecomputer *s, struct divecomputer *d) { @@ -2811,15 +2725,6 @@ struct dive *try_to_merge(struct dive *a, struct dive *b, bool prefer_downloaded return res; } -void free_events(struct event *ev) -{ - while (ev) { - struct event *next = ev->next; - free(ev); - ev = next; - } -} - static void free_extra_data(struct extra_data *ed) { free((void *)ed->key); diff --git a/core/dive.h b/core/dive.h index 735e760c1..27e73375f 100644 --- a/core/dive.h +++ b/core/dive.h @@ -20,41 +20,14 @@ extern "C" { #endif +struct event; + extern int last_xml_version; extern const char *cylinderuse_text[NUM_GAS_USE]; extern const char *divemode_text_ui[]; extern const char *divemode_text[]; -/* - * Events are currently based straight on what libdivecomputer gives us. - * We need to wrap these into our own events at some point to remove some of the limitations. - */ -struct event { - struct event *next; - duration_t time; - int type; - /* This is the annoying libdivecomputer format. */ - int flags, value; - /* .. and this is our "extended" data for some event types */ - union { - enum divemode_t divemode; // for divemode change events - /* - * NOTE! The index may be -1, which means "unknown". In that - * case, the get_cylinder_index() function will give the best - * match with the cylinders in the dive based on gasmix. - */ - struct { // for gas switch events - int index; - struct gasmix mix; - } gas; - }; - bool deleted; - char name[]; -}; - -extern int event_is_gaschange(const struct event *ev); - extern void fill_pressures(struct gas_pressures *pressures, const double amb_pressure, struct gasmix mix, double po2, enum divemode_t dctype); /* Linear interpolation between 'a' and 'b', when we are 'part'way into the 'whole' distance from a to b */ @@ -323,21 +296,16 @@ extern int split_dive(const struct dive *dive, struct dive **new1, struct dive * extern int split_dive_at_time(const struct dive *dive, duration_t time, struct dive **new1, struct dive **new2); extern struct dive *merge_dives(const struct dive *a, const struct dive *b, int offset, bool prefer_downloaded, struct dive_trip **trip, struct dive_site **site); extern struct dive *try_to_merge(struct dive *a, struct dive *b, bool prefer_downloaded); -extern struct event *clone_event(const struct event *src_ev); extern void copy_events(const struct divecomputer *s, struct divecomputer *d); extern void copy_events_until(const struct dive *sd, struct dive *dd, int time); -extern void free_events(struct event *ev); extern void copy_used_cylinders(const struct dive *s, struct dive *d, bool used_only); extern void copy_samples(const struct divecomputer *s, struct divecomputer *d); extern bool is_cylinder_used(const struct dive *dive, int idx); extern bool is_cylinder_prot(const struct dive *dive, int idx); extern void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int time, int idx); -extern struct event *create_event(unsigned int time, int type, int flags, int value, const char *name); extern struct event *create_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx); -extern struct event *clone_event_rename(const struct event *ev, const char *name); extern void add_event_to_dc(struct divecomputer *dc, struct event *ev); extern void swap_event(struct divecomputer *dc, struct event *from, struct event *to); -extern bool same_event(const struct event *a, const struct event *b); extern struct event *add_event(struct divecomputer *dc, unsigned int time, int type, int flags, int value, const char *name); extern void remove_event_from_dc(struct divecomputer *dc, struct event *event); extern void update_event_name(struct dive *d, struct event *event, const char *name); @@ -350,11 +318,8 @@ extern int nr_weightsystems(const struct dive *dive); /* UI related protopypes */ -extern void remember_event(const char *eventname); extern void invalidate_dive_cache(struct dive *dc); -extern void clear_events(void); - extern void set_autogroup(bool value); extern int total_weight(const struct dive *); @@ -370,10 +335,6 @@ extern void subsurface_command_line_exit(int *, char ***); extern bool is_dc_planner(const struct divecomputer *dc); extern bool has_planned(const struct dive *dive, bool planned); -/* Since C doesn't have parameter-based overloading, two versions of get_next_event. */ -extern const struct event *get_next_event(const struct event *event, const char *name); -extern struct event *get_next_event_mutable(struct event *event, const char *name); - /* Get gasmixes at increasing timestamps. * In "evp", pass a pointer to a "struct event *" which is NULL-initialized on first invocation. * On subsequent calls, pass the same "evp" and the "gasmix" from previous calls. diff --git a/core/divelist.c b/core/divelist.c index 3599ec498..7f93bacf2 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -7,6 +7,7 @@ #include "device.h" #include "divesite.h" #include "dive.h" +#include "event.h" #include "filterpreset.h" #include "fulltext.h" #include "planner.h" diff --git a/core/event.c b/core/event.c new file mode 100644 index 000000000..8f73aefd8 --- /dev/null +++ b/core/event.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "event.h" +#include "subsurface-string.h" + +#include +#include + +int event_is_gaschange(const struct event *ev) +{ + return ev->type == SAMPLE_EVENT_GASCHANGE || + ev->type == SAMPLE_EVENT_GASCHANGE2; +} + +bool event_is_divemodechange(const struct event *ev) +{ + return same_string(ev->name, "modechange"); +} + +struct event *clone_event(const struct event *src_ev) +{ + struct event *ev; + if (!src_ev) + return NULL; + + size_t size = sizeof(*src_ev) + strlen(src_ev->name) + 1; + ev = (struct event*) malloc(size); + if (!ev) + exit(1); + memcpy(ev, src_ev, size); + ev->next = NULL; + + return ev; +} + +void free_events(struct event *ev) +{ + while (ev) { + struct event *next = ev->next; + free(ev); + ev = next; + } +} + +struct event *create_event(unsigned int time, int type, int flags, int value, const char *name) +{ + int gas_index = -1; + struct event *ev; + unsigned int size, len = strlen(name); + + size = sizeof(*ev) + len + 1; + ev = malloc(size); + if (!ev) + return NULL; + memset(ev, 0, size); + memcpy(ev->name, name, len); + ev->time.seconds = time; + ev->type = type; + ev->flags = flags; + ev->value = value; + + /* + * Expand the events into a sane format. Currently + * just gas switches + */ + switch (type) { + case SAMPLE_EVENT_GASCHANGE2: + /* High 16 bits are He percentage */ + ev->gas.mix.he.permille = (value >> 16) * 10; + + /* Extension to the GASCHANGE2 format: cylinder index in 'flags' */ + /* TODO: verify that gas_index < num_cylinders. */ + if (flags > 0) + gas_index = flags-1; + /* Fallthrough */ + case SAMPLE_EVENT_GASCHANGE: + /* Low 16 bits are O2 percentage */ + ev->gas.mix.o2.permille = (value & 0xffff) * 10; + ev->gas.index = gas_index; + break; + } + + return ev; +} + +struct event *clone_event_rename(const struct event *ev, const char *name) +{ + return create_event(ev->time.seconds, ev->type, ev->flags, ev->value, name); +} + +bool same_event(const struct event *a, const struct event *b) +{ + if (a->time.seconds != b->time.seconds) + return 0; + if (a->type != b->type) + return 0; + if (a->flags != b->flags) + return 0; + if (a->value != b->value) + return 0; + return !strcmp(a->name, b->name); +} + +/* collect all event names and whether we display them */ +struct ev_select *ev_namelist = NULL; +int evn_used = 0; +static int evn_allocated = 0; + +void clear_events(void) +{ + for (int i = 0; i < evn_used; i++) + free(ev_namelist[i].ev_name); + evn_used = 0; +} + +void remember_event(const char *eventname) +{ + int i = 0, len; + + if (!eventname || (len = strlen(eventname)) == 0) + return; + while (i < evn_used) { + if (!strncmp(eventname, ev_namelist[i].ev_name, len)) + return; + i++; + } + if (evn_used == evn_allocated) { + evn_allocated += 10; + ev_namelist = realloc(ev_namelist, evn_allocated * sizeof(struct ev_select)); + if (!ev_namelist) + /* we are screwed, but let's just bail out */ + return; + } + ev_namelist[evn_used].ev_name = strdup(eventname); + ev_namelist[evn_used].plot_ev = true; + evn_used++; +} diff --git a/core/event.h b/core/event.h new file mode 100644 index 000000000..4c729e3f3 --- /dev/null +++ b/core/event.h @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef EVENT_H +#define EVENT_H + +#include "divemode.h" +#include "gas.h" +#include "units.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Events are currently based straight on what libdivecomputer gives us. + * We need to wrap these into our own events at some point to remove some of the limitations. + */ +struct event { + struct event *next; + duration_t time; + int type; + /* This is the annoying libdivecomputer format. */ + int flags, value; + /* .. and this is our "extended" data for some event types */ + union { + enum divemode_t divemode; // for divemode change events + /* + * NOTE! The index may be -1, which means "unknown". In that + * case, the get_cylinder_index() function will give the best + * match with the cylinders in the dive based on gasmix. + */ + struct { // for gas switch events + int index; + struct gasmix mix; + } gas; + }; + bool deleted; + char name[]; +}; + +struct ev_select { + char *ev_name; + bool plot_ev; +}; + +/* collect all event names and whether we display them */ +extern struct ev_select *ev_namelist; +extern int evn_used; + +extern int event_is_gaschange(const struct event *ev); +extern bool event_is_divemodechange(const struct event *ev); +extern struct event *clone_event(const struct event *src_ev); +extern void free_events(struct event *ev); +extern struct event *create_event(unsigned int time, int type, int flags, int value, const char *name); +extern struct event *clone_event_rename(const struct event *ev, const char *name); +extern bool same_event(const struct event *a, const struct event *b); +extern void remember_event(const char *eventname); +extern void clear_events(void); + +/* Since C doesn't have parameter-based overloading, two versions of get_next_event. */ +extern const struct event *get_next_event(const struct event *event, const char *name); +extern struct event *get_next_event_mutable(struct event *event, const char *name); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/gaspressures.c b/core/gaspressures.c index bf329add4..2fa85368c 100644 --- a/core/gaspressures.c +++ b/core/gaspressures.c @@ -20,6 +20,7 @@ #include "ssrf.h" #include "dive.h" +#include "event.h" #include "display.h" #include "profile.h" #include "gaspressures.h" diff --git a/core/import-cobalt.c b/core/import-cobalt.c index 22bf14dbb..7feb325f1 100644 --- a/core/import-cobalt.c +++ b/core/import-cobalt.c @@ -6,6 +6,7 @@ #include "ssrf.h" #include "divesite.h" +#include "gas.h" #include "subsurface-string.h" #include "parse.h" #include "divelist.h" diff --git a/core/libdivecomputer.c b/core/libdivecomputer.c index f9551decd..b7d6ab14e 100644 --- a/core/libdivecomputer.c +++ b/core/libdivecomputer.c @@ -19,6 +19,7 @@ #include "dive.h" #include "display.h" #include "errorhelper.h" +#include "event.h" #include "sha1.h" #include "subsurface-time.h" #include "timer.h" diff --git a/core/load-git.c b/core/load-git.c index 2f2da1efb..839c5019b 100644 --- a/core/load-git.c +++ b/core/load-git.c @@ -16,6 +16,7 @@ #include "dive.h" #include "divesite.h" +#include "event.h" #include "errorhelper.h" #include "trip.h" #include "subsurface-string.h" diff --git a/core/parse.h b/core/parse.h index 7c4529739..224403585 100644 --- a/core/parse.h +++ b/core/parse.h @@ -4,7 +4,9 @@ #define MAX_EVENT_NAME 128 -#include "dive.h" // for struct event! +#include "event.h" +#include "picture.h" +#include "dive.h" // for "struct extra_data" #include "filterpreset.h" #include diff --git a/core/planner.c b/core/planner.c index 475be1a20..f03b87f9a 100644 --- a/core/planner.c +++ b/core/planner.c @@ -15,6 +15,7 @@ #include "subsurface-string.h" #include "deco.h" #include "errorhelper.h" +#include "event.h" #include "planner.h" #include "subsurface-time.h" #include "gettext.h" diff --git a/core/profile.c b/core/profile.c index 1cc73f158..0e7db76d2 100644 --- a/core/profile.c +++ b/core/profile.c @@ -9,9 +9,10 @@ #include #include "dive.h" -#include "subsurface-string.h" #include "display.h" #include "divelist.h" +#include "event.h" +#include "subsurface-string.h" #include "profile.h" #include "gaspressures.h" @@ -115,41 +116,6 @@ int get_maxdepth(const struct plot_info *pi) return md; } -/* collect all event names and whether we display them */ -struct ev_select *ev_namelist; -int evn_allocated; -int evn_used; - -void clear_events(void) -{ - for (int i = 0; i < evn_used; i++) - free(ev_namelist[i].ev_name); - evn_used = 0; -} - -void remember_event(const char *eventname) -{ - int i = 0, len; - - if (!eventname || (len = strlen(eventname)) == 0) - return; - while (i < evn_used) { - if (!strncmp(eventname, ev_namelist[i].ev_name, len)) - return; - i++; - } - if (evn_used == evn_allocated) { - evn_allocated += 10; - ev_namelist = realloc(ev_namelist, evn_allocated * sizeof(struct ev_select)); - if (!ev_namelist) - /* we are screwed, but let's just bail out */ - return; - } - ev_namelist[evn_used].ev_name = strdup(eventname); - ev_namelist[evn_used].plot_ev = true; - evn_used++; -} - /* UNUSED! */ static int get_local_sac(struct plot_info *pi, int idx1, int idx2, struct dive *dive) __attribute__((unused)); diff --git a/core/profile.h b/core/profile.h index 96b672187..7158861bd 100644 --- a/core/profile.h +++ b/core/profile.h @@ -80,11 +80,6 @@ struct plot_data { bool icd_warning; }; -struct ev_select { - char *ev_name; - bool plot_ev; -}; - extern void compare_samples(struct plot_info *p1, int idx1, int idx2, char *buf, int bufsize, bool sum); extern void init_plot_info(struct plot_info *pi); extern void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi, bool fast, const struct deco_state *planner_ds); diff --git a/core/save-git.c b/core/save-git.c index 041f01223..4fabe35cf 100644 --- a/core/save-git.c +++ b/core/save-git.c @@ -24,6 +24,7 @@ #include "trip.h" #include "device.h" #include "errorhelper.h" +#include "event.h" #include "membuffer.h" #include "git-access.h" #include "version.h" diff --git a/core/save-html.c b/core/save-html.c index ec348e56d..65b21a723 100644 --- a/core/save-html.c +++ b/core/save-html.c @@ -10,6 +10,7 @@ #include "gettext.h" #include "divesite.h" #include "errorhelper.h" +#include "event.h" #include "file.h" #include "picture.h" #include "tag.h" diff --git a/core/save-xml.c b/core/save-xml.c index 812201e48..13d038c22 100644 --- a/core/save-xml.c +++ b/core/save-xml.c @@ -21,6 +21,7 @@ #include "subsurface-time.h" #include "trip.h" #include "device.h" +#include "event.h" #include "file.h" #include "membuffer.h" #include "picture.h" diff --git a/core/statistics.c b/core/statistics.c index 8ebd4a4e0..d22b6755c 100644 --- a/core/statistics.c +++ b/core/statistics.c @@ -12,6 +12,7 @@ #include "dive.h" #include "display.h" +#include "event.h" #include "subsurface-time.h" #include "trip.h" #include "statistics.h" diff --git a/packaging/ios/Subsurface-mobile.pro b/packaging/ios/Subsurface-mobile.pro index bcd60efcc..605bce4cd 100644 --- a/packaging/ios/Subsurface-mobile.pro +++ b/packaging/ios/Subsurface-mobile.pro @@ -56,6 +56,7 @@ SOURCES += ../../subsurface-mobile-main.cpp \ ../../core/device.cpp \ ../../core/dive.c \ ../../core/divefilter.cpp \ + ../../core/event.c \ ../../core/filterconstraint.cpp \ ../../core/filterpreset.cpp \ ../../core/divelist.c \ @@ -204,6 +205,7 @@ HEADERS += \ ../../core/device.h \ ../../core/devicedetails.h \ ../../core/dive.h \ + ../../core/event.h \ ../../core/git-access.h \ ../../core/gpslocation.h \ ../../core/imagedownloader.h \ diff --git a/profile-widget/diveeventitem.cpp b/profile-widget/diveeventitem.cpp index dcb4d8af0..33f909ecc 100644 --- a/profile-widget/diveeventitem.cpp +++ b/profile-widget/diveeventitem.cpp @@ -3,6 +3,7 @@ #include "qt-models/diveplotdatamodel.h" #include "profile-widget/divecartesianaxis.h" #include "profile-widget/animationfunctions.h" +#include "core/event.h" #include "core/libdivecomputer.h" #include "core/profile.h" #include "core/gettextfromc.h" @@ -12,9 +13,6 @@ #define DEPTH_NOT_FOUND (-2342) -extern struct ev_select *ev_namelist; -extern int evn_used; - DiveEventItem::DiveEventItem(QGraphicsItem *parent) : DivePixmapItem(parent), vAxis(NULL), hAxis(NULL), diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index f3a636fe8..fb2dff744 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "profile-widget/profilewidget2.h" #include "qt-models/diveplotdatamodel.h" +#include "core/event.h" #include "core/subsurface-string.h" #include "core/qthelper.h" #include "core/picture.h" @@ -1377,10 +1378,6 @@ void ProfileWidget2::setPlanState() } #endif -extern struct ev_select *ev_namelist; -extern int evn_allocated; -extern int evn_used; - bool ProfileWidget2::isPlanner() { return currentState == PLAN; diff --git a/profile-widget/tankitem.cpp b/profile-widget/tankitem.cpp index 4967633ed..adf9ba99c 100644 --- a/profile-widget/tankitem.cpp +++ b/profile-widget/tankitem.cpp @@ -2,6 +2,7 @@ #include "profile-widget/tankitem.h" #include "qt-models/diveplotdatamodel.h" #include "profile-widget/divetextitem.h" +#include "core/event.h" #include "core/profile.h" #include diff --git a/smtk-import/smartrak.c b/smtk-import/smartrak.c index 5f027ee5e..aaa9cb47f 100644 --- a/smtk-import/smartrak.c +++ b/smtk-import/smartrak.c @@ -30,6 +30,7 @@ #include "core/subsurface-string.h" #include "core/gettext.h" #include "core/divelist.h" +#include "core/event.h" #include "core/libdivecomputer.h" #include "core/divesite.h" #include "core/membuffer.h" diff --git a/tests/testplan.cpp b/tests/testplan.cpp index b567fe5d7..84f900af7 100644 --- a/tests/testplan.cpp +++ b/tests/testplan.cpp @@ -2,6 +2,7 @@ #include "testplan.h" #include "core/deco.h" #include "core/dive.h" +#include "core/event.h" #include "core/planner.h" #include "core/qthelper.h" #include "core/subsurfacestartup.h"