mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 21:20:19 +00:00
d054e8c457
This commit is a little bigger than I usually prefer, but it's all somewhat interconnected. - we pass around the cylinders throughout the planning process and as we create the plan we calculate the gas consumption in every segment and track this both in the end pressure of the cylinder and over time in the samples - because of that we no longer try to calculate the gas consumption after being done planning; we just use what we calculated along the way - we also no longer add gases during the planning process - all gases have to come from the list of cylinders passed in (which makes sense as we should only use those gases that the user added in the UI or inherited from a the selected dive (when starting to plan with a dive already selected) With this patch I think we are close do being able to move all of the planning logic back into the planner.c code where it belongs. The one issue that still bothers me is that we are juggling so many dive structures and then keep copying content around. It seems like we should be able to reduce that. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
192 lines
4.9 KiB
C
192 lines
4.9 KiB
C
/* equipment.c */
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <time.h>
|
|
#include "gettext.h"
|
|
#include "dive.h"
|
|
#include "display.h"
|
|
#include "divelist.h"
|
|
|
|
/* placeholders for a few functions that we need to redesign for the Qt UI */
|
|
void add_cylinder_description(cylinder_type_t *type)
|
|
{
|
|
const char *desc;
|
|
int i;
|
|
|
|
desc = type->description;
|
|
if (!desc)
|
|
return;
|
|
for (i = 0; i < 100 && tank_info[i].name != NULL; i++) {
|
|
if (strcmp(tank_info[i].name, desc) == 0)
|
|
return;
|
|
}
|
|
if (i < 100) {
|
|
tank_info[i].name = desc;
|
|
tank_info[i].ml = type->size.mliter;
|
|
tank_info[i].bar = type->workingpressure.mbar / 1000;
|
|
}
|
|
}
|
|
void add_weightsystem_description(weightsystem_t *weightsystem)
|
|
{
|
|
const char *desc;
|
|
int i;
|
|
|
|
desc = weightsystem->description;
|
|
if (!desc)
|
|
return;
|
|
for (i = 0; i < 100 && ws_info[i].name != NULL; i++) {
|
|
if (strcmp(ws_info[i].name, desc) == 0) {
|
|
ws_info[i].grams = weightsystem->weight.grams;
|
|
return;
|
|
}
|
|
}
|
|
if (i < 100) {
|
|
ws_info[i].name = desc;
|
|
ws_info[i].grams = weightsystem->weight.grams;
|
|
}
|
|
}
|
|
|
|
bool cylinder_nodata(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;
|
|
}
|
|
|
|
static bool cylinder_nosamples(cylinder_t *cyl)
|
|
{
|
|
return !cyl->sample_start.mbar &&
|
|
!cyl->sample_end.mbar;
|
|
}
|
|
|
|
bool cylinder_none(void *_data)
|
|
{
|
|
cylinder_t *cyl = _data;
|
|
return cylinder_nodata(cyl) && cylinder_nosamples(cyl);
|
|
}
|
|
|
|
bool weightsystem_none(void *_data)
|
|
{
|
|
weightsystem_t *ws = _data;
|
|
return !ws->weight.grams && !ws->description;
|
|
}
|
|
|
|
bool no_weightsystems(weightsystem_t *ws)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_WEIGHTSYSTEMS; i++)
|
|
if (!weightsystem_none(ws + i))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
static bool one_weightsystem_equal(weightsystem_t *ws1, weightsystem_t *ws2)
|
|
{
|
|
return ws1->weight.grams == ws2->weight.grams &&
|
|
same_string(ws1->description, ws2->description);
|
|
}
|
|
|
|
bool weightsystems_equal(weightsystem_t *ws1, weightsystem_t *ws2)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_WEIGHTSYSTEMS; i++)
|
|
if (!one_weightsystem_equal(ws1 + i, ws2 + i))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* We hardcode the most common standard cylinders,
|
|
* we should pick up any other names from the dive
|
|
* logs directly.
|
|
*/
|
|
struct tank_info_t tank_info[100] = {
|
|
/* Need an empty entry for the no-cylinder case */
|
|
{ "", },
|
|
|
|
/* Size-only metric cylinders */
|
|
{ "10.0 l", .ml = 10000 },
|
|
{ "11.1 l", .ml = 11100 },
|
|
|
|
/* Most common AL cylinders */
|
|
{ "AL40", .cuft = 40, .psi = 3000 },
|
|
{ "AL50", .cuft = 50, .psi = 3000 },
|
|
{ "AL63", .cuft = 63, .psi = 3000 },
|
|
{ "AL72", .cuft = 72, .psi = 3000 },
|
|
{ "AL80", .cuft = 80, .psi = 3000 },
|
|
{ "AL100", .cuft = 100, .psi = 3300 },
|
|
|
|
/* Somewhat common LP steel cylinders */
|
|
{ "LP85", .cuft = 85, .psi = 2640 },
|
|
{ "LP95", .cuft = 95, .psi = 2640 },
|
|
{ "LP108", .cuft = 108, .psi = 2640 },
|
|
{ "LP121", .cuft = 121, .psi = 2640 },
|
|
|
|
/* Somewhat common HP steel cylinders */
|
|
{ "HP65", .cuft = 65, .psi = 3442 },
|
|
{ "HP80", .cuft = 80, .psi = 3442 },
|
|
{ "HP100", .cuft = 100, .psi = 3442 },
|
|
{ "HP119", .cuft = 119, .psi = 3442 },
|
|
{ "HP130", .cuft = 130, .psi = 3442 },
|
|
|
|
/* Common European steel cylinders */
|
|
{ "3L 232 bar", .ml = 3000, .bar = 232 },
|
|
{ "3L 300 bar", .ml = 3000, .bar = 300 },
|
|
{ "10L 300 bar", .ml = 10000, .bar = 300 },
|
|
{ "12L 200 bar", .ml = 12000, .bar = 200 },
|
|
{ "12L 232 bar", .ml = 12000, .bar = 232 },
|
|
{ "12L 300 bar", .ml = 12000, .bar = 300 },
|
|
{ "15L 200 bar", .ml = 15000, .bar = 200 },
|
|
{ "15L 232 bar", .ml = 15000, .bar = 232 },
|
|
{ "D7 300 bar", .ml = 14000, .bar = 300 },
|
|
{ "D8.5 232 bar", .ml = 17000, .bar = 232 },
|
|
{ "D12 232 bar", .ml = 24000, .bar = 232 },
|
|
|
|
/* We'll fill in more from the dive log dynamically */
|
|
{ NULL, }
|
|
};
|
|
|
|
/*
|
|
* We hardcode the most common weight system types
|
|
* This is a bit odd as the weight system types don't usually encode weight
|
|
*/
|
|
struct ws_info_t ws_info[100] = {
|
|
{ QT_TRANSLATE_NOOP("gettextFromC", "integrated"), 0 },
|
|
{ QT_TRANSLATE_NOOP("gettextFromC", "belt"), 0 },
|
|
{ QT_TRANSLATE_NOOP("gettextFromC", "ankle"), 0 },
|
|
{ QT_TRANSLATE_NOOP("gettextFromC", "backplate weight"), 0 },
|
|
{ QT_TRANSLATE_NOOP("gettextFromC", "clip-on"), 0 },
|
|
};
|
|
|
|
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));
|
|
}
|
|
|
|
void remove_weightsystem(struct dive *dive, int idx)
|
|
{
|
|
weightsystem_t *ws = dive->weightsystem + idx;
|
|
int nr = MAX_WEIGHTSYSTEMS - idx - 1;
|
|
memmove(ws, ws + 1, nr * sizeof(*ws));
|
|
memset(ws + nr, 0, sizeof(*ws));
|
|
}
|
|
|
|
void reset_cylinders(struct dive *dive)
|
|
{
|
|
int i;
|
|
for (i = 0; i < MAX_CYLINDERS; i++) {
|
|
if (dive->cylinder[i].type.workingpressure.mbar)
|
|
dive->cylinder[i].start.mbar = dive->cylinder[i].end.mbar = dive->cylinder[i].type.workingpressure.mbar;
|
|
}
|
|
}
|