summaryrefslogtreecommitdiffstats
path: root/core/equipment.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/equipment.c')
-rw-r--r--core/equipment.c117
1 files changed, 78 insertions, 39 deletions
diff --git a/core/equipment.c b/core/equipment.c
index d97ed6e4f..13e4a0486 100644
--- a/core/equipment.c
+++ b/core/equipment.c
@@ -24,6 +24,11 @@ static void free_weightsystem(weightsystem_t w)
free((void *)w.description);
}
+static void free_cylinder(cylinder_t c)
+{
+ free((void *)c.type.description);
+}
+
void copy_weights(const struct weightsystem_table *s, struct weightsystem_table *d)
{
clear_weightsystem_table(d);
@@ -41,6 +46,16 @@ MAKE_REMOVE_FROM(weightsystem_table, weightsystems)
//MAKE_REMOVE(weightsystem_table, weightsystem_t, weightsystem)
MAKE_CLEAR_TABLE(weightsystem_table, weightsystems, weightsystem)
+/* cylinder table functions */
+//static MAKE_GET_IDX(cylinder_table, cylinder_t, cylinders)
+static MAKE_GROW_TABLE(cylinder_table, cylinder_t, cylinders)
+//static MAKE_GET_INSERTION_INDEX(cylinder_table, cylinder_t, cylinders, cylinder_less_than)
+MAKE_ADD_TO(cylinder_table, cylinder_t, cylinders)
+MAKE_REMOVE_FROM(cylinder_table, cylinders)
+//MAKE_SORT(cylinder_table, cylinder_t, cylinders, comp_cylinders)
+//MAKE_REMOVE(cylinder_table, cylinder_t, cylinder)
+MAKE_CLEAR_TABLE(cylinder_table, cylinders, cylinder)
+
const char *cylinderuse_text[NUM_GAS_USE] = {
QT_TRANSLATE_NOOP("gettextFromC", "OC-gas"), QT_TRANSLATE_NOOP("gettextFromC", "diluent"), QT_TRANSLATE_NOOP("gettextFromC", "oxygen"), QT_TRANSLATE_NOOP("gettextFromC", "not used")
};
@@ -104,34 +119,27 @@ void add_cloned_weightsystem(struct weightsystem_table *t, weightsystem_t ws)
add_to_weightsystem_table(t, t->nr, w_clone);
}
-bool same_weightsystem(weightsystem_t w1, weightsystem_t w2)
-{
- return w1.weight.grams == w2.weight.grams &&
- same_string(w1.description, w2.description);
-}
-
-bool cylinder_nodata(const cylinder_t *cyl)
+/* Add a clone of a cylinder to the end of a cylinder table.
+ * Cloned in means that the description-string is copied. */
+void add_cloned_cylinder(struct cylinder_table *t, cylinder_t cyl)
{
- return !cyl->type.size.mliter &&
- !cyl->type.workingpressure.mbar &&
- !cyl->type.description &&
- !cyl->gasmix.o2.permille &&
- !cyl->gasmix.he.permille &&
- !cyl->start.mbar &&
- !cyl->end.mbar &&
- !cyl->gas_used.mliter &&
- !cyl->deco_gas_used.mliter;
+ cyl.type.description = copy_string(cyl.type.description);
+ add_to_cylinder_table(t, t->nr, cyl);
}
-static bool cylinder_nosamples(const cylinder_t *cyl)
+bool same_weightsystem(weightsystem_t w1, weightsystem_t w2)
{
- return !cyl->sample_start.mbar &&
- !cyl->sample_end.mbar;
+ return w1.weight.grams == w2.weight.grams &&
+ same_string(w1.description, w2.description);
}
-bool cylinder_none(const cylinder_t *cyl)
+bool same_cylinder(cylinder_t cyl1, cylinder_t cyl2)
{
- return cylinder_nodata(cyl) && cylinder_nosamples(cyl);
+ return same_string(cyl1.type.description, cyl2.type.description) &&
+ same_gasmix(cyl1.gasmix, cyl2.gasmix) &&
+ cyl1.start.mbar == cyl2.start.mbar &&
+ cyl1.end.mbar == cyl2.end.mbar &&
+ cyl1.cylinder_use == cyl2.cylinder_use;
}
void get_gas_string(struct gasmix gasmix, char *text, int len)
@@ -161,18 +169,16 @@ int gas_volume(const cylinder_t *cyl, pressure_t p)
return lrint(cyl->type.size.mliter * bar_to_atm(bar) / z_factor);
}
-int find_best_gasmix_match(struct gasmix mix, const cylinder_t array[])
+int find_best_gasmix_match(struct gasmix mix, const struct cylinder_table *cylinders)
{
int i;
int best = -1, score = INT_MAX;
- for (i = 0; i < MAX_CYLINDERS; i++) {
+ for (i = 0; i < cylinders->nr; i++) {
const cylinder_t *match;
int distance;
- match = array + i;
- if (cylinder_nodata(match))
- continue;
+ match = cylinders->cylinders + i;
distance = gasmix_distance(mix, match->gasmix);
if (distance >= score)
continue;
@@ -258,10 +264,7 @@ struct ws_info_t ws_info[MAX_WS_INFO] = {
void remove_cylinder(struct dive *dive, int idx)
{
- cylinder_t *cyl = dive->cylinder + idx;
- int nr = MAX_CYLINDERS - idx - 1;
- memmove(cyl, cyl + 1, nr * sizeof(*cyl));
- memset(cyl + nr, 0, sizeof(*cyl));
+ remove_from_cylinder_table(&dive->cylinders, idx);
}
void remove_weightsystem(struct dive *dive, int idx)
@@ -275,10 +278,8 @@ void reset_cylinders(struct dive *dive, bool track_gas)
{
pressure_t decopo2 = {.mbar = prefs.decopo2};
- for (int i = 0; i < MAX_CYLINDERS; i++) {
- cylinder_t *cyl = &dive->cylinder[i];
- if (cylinder_none(cyl))
- continue;
+ for (int i = 0; i < dive->cylinders.nr; i++) {
+ cylinder_t *cyl = &dive->cylinders.cylinders[i];
if (cyl->depth.mm == 0) /* if the gas doesn't give a mod, calculate based on prefs */
cyl->depth = gas_mod(cyl->gasmix, decopo2, dive, M_OR_FT(3,10));
if (track_gas)
@@ -290,7 +291,7 @@ void reset_cylinders(struct dive *dive, bool track_gas)
static void copy_cylinder_type(const cylinder_t *s, cylinder_t *d)
{
- free(d->type.description);
+ free_cylinder(*d);
d->type = s->type;
d->type.description = s->type.description ? strdup(s->type.description) : NULL;
d->gasmix = s->gasmix;
@@ -306,16 +307,54 @@ void copy_cylinder_types(const struct dive *s, struct dive *d)
if (!s || !d)
return;
- for (i = 0; i < MAX_CYLINDERS; i++)
- copy_cylinder_type(s->cylinder + i, d->cylinder + i);
+ for (i = 0; i < s->cylinders.nr && i < d->cylinders.nr; i++)
+ copy_cylinder_type(s->cylinders.cylinders + i, d->cylinders.cylinders + i);
+
+ for ( ; i < s->cylinders.nr; i++)
+ add_cloned_cylinder(&d->cylinders, s->cylinders.cylinders[i]);
+}
+
+void add_empty_cylinder(struct cylinder_table *t)
+{
+ cylinder_t cyl = { 0 };
+ cyl.type.description = strdup("");
+ add_to_cylinder_table(t, t->nr, cyl);
+}
+
+/* access to cylinders is controlled by two functions:
+ * - get_cylinder() returns the cylinder of a dive and supposes that
+ * the cylinder with the given index exists. If it doesn't, an error
+ * message is printed and NULL returned.
+ * - get_or_create_cylinder() creates an empty cylinder if it doesn't exist.
+ * Multiple cylinders might be created if the index is bigger than the
+ * number of existing cylinders
+ */
+cylinder_t *get_cylinder(const struct dive *d, int idx)
+{
+ if (idx < 0 || idx >= d->cylinders.nr) {
+ fprintf(stderr, "Warning: accessing invalid cylinder %d (%d existing)\n", idx, d->cylinders.nr);
+ return NULL;
+ }
+ return &d->cylinders.cylinders[idx];
+}
+
+cylinder_t *get_or_create_cylinder(struct dive *d, int idx)
+{
+ if (idx < 0) {
+ fprintf(stderr, "Warning: accessing invalid cylinder %d\n", idx);
+ return NULL;
+ }
+ while (idx >= d->cylinders.nr)
+ add_empty_cylinder(&d->cylinders);
+ return &d->cylinders.cylinders[idx];
}
#ifdef DEBUG_CYL
void dump_cylinders(struct dive *dive, bool verbose)
{
printf("Cylinder list:\n");
- for (int i = 0; i < MAX_CYLINDERS; i++) {
- cylinder_t *cyl = &dive->cylinder[i];
+ for (int i = 0; i < dive->cylinders; i++) {
+ cylinder_t *cyl = &dive->cylinders.cylinders[i];
printf("%02d: Type %s, %3.1fl, %3.0fbar\n", i, cyl->type.description, cyl->type.size.mliter / 1000.0, cyl->type.workingpressure.mbar / 1000.0);
printf(" Gasmix O2 %2.0f%% He %2.0f%%\n", cyl->gasmix.o2.permille / 10.0, cyl->gasmix.he.permille / 10.0);