Start handling dive events

Parse them, save them, take them from libdivecomputer.

This doesn't merge them or show them in the profile yet, though.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2011-09-22 18:02:54 -07:00
parent 50c2bb7c71
commit 3a77eb8510
5 changed files with 112 additions and 8 deletions

23
dive.c
View file

@ -5,6 +5,29 @@
#include "dive.h"
void add_event(struct dive *dive, int time, int type, int flags, int value, const char *name)
{
struct event *ev, **p;
unsigned int size, len = strlen(name);
size = sizeof(*ev) + len + 1;
ev = malloc(size);
if (!ev)
return;
memset(ev, 0, size);
memcpy(ev->name, name, len);
ev->time.seconds = time;
ev->type = type;
ev->flags = flags;
ev->value = value;
ev->next = NULL;
p = &dive->events;
while (*p)
p = &(*p)->next;
*p = ev;
}
double get_depth_units(unsigned int mm, int *frac, const char **units)
{
int decimals;

18
dive.h
View file

@ -142,6 +142,21 @@ struct sample {
int cylinderindex;
};
/*
* Events are currently pretty meaningless. This is
* just based on the random data that libdivecomputer
* gives us. I'm not sure what a real "architected"
* event model would actually look like, but right
* now you can associate a list of events with a dive,
* and we'll do something about it.
*/
struct event {
struct event *next;
duration_t time;
int type, flags, value;
char name[];
};
#define MAX_CYLINDERS (8)
struct dive {
@ -156,6 +171,7 @@ struct dive {
depth_t visibility;
temperature_t airtemp, watertemp;
cylinder_t cylinder[MAX_CYLINDERS];
struct event *events;
int samples, alloc_samples;
struct sample sample[];
};
@ -227,6 +243,8 @@ extern struct dive *try_to_merge(struct dive *a, struct dive *b);
extern void renumber_dives(int nr);
extern void add_event(struct dive *dive, int time, int type, int flags, int value, const char *name);
/* UI related protopypes */
extern void init_ui(int argc, char **argv);

View file

@ -118,7 +118,7 @@ static int parse_gasmixes(struct dive *dive, parser_t *parser, int ngases)
return PARSER_STATUS_SUCCESS;
}
static void handle_event(struct dive **divep, struct sample *sample, parser_sample_value_t value)
static void handle_event(struct dive *dive, struct sample *sample, parser_sample_value_t value)
{
int type, time;
static const char *events[] = {
@ -152,9 +152,7 @@ static void handle_event(struct dive **divep, struct sample *sample, parser_samp
if (sample)
time += sample->time.seconds;
printf(" <event type=\"%u\" time=\"%u:%02u\" flags=\"%u\" value=\"%u\" name=\"%s\" />\n",
type, time / 60, time % 60,
value.event.flags, value.event.value, name);
add_event(dive, time, type, value.event.flags, value.event.value, name);
}
void
@ -188,7 +186,7 @@ sample_cb(parser_sample_type_t type, parser_sample_value_t value, void *userdata
sample->temperature.mkelvin = (value.temperature + 273.15) * 1000 + 0.5;
break;
case SAMPLE_TYPE_EVENT:
handle_event(divep, sample, value);
handle_event(dive, sample, value);
break;
case SAMPLE_TYPE_RBT:
printf(" <rbt>%u</rbt>\n", value.rbt);

View file

@ -92,8 +92,14 @@ const struct units IMPERIAL_units = {
*/
static struct dive *dive;
static struct sample *sample;
static struct {
int active;
duration_t time;
int type, flags, value;
const char *name;
} event;
static struct tm tm;
static int event_index, cylinder_index;
static int cylinder_index;
static enum import_source {
UNKNOWN,
@ -558,6 +564,32 @@ static int uddf_fill_sample(struct sample *sample, const char *name, int len, ch
0;
}
static void eventtime(char *buffer, void *_duration)
{
duration_t *duration = _duration;
sampletime(buffer, duration);
if (sample)
duration->seconds += sample->time.seconds;
}
static void try_to_fill_event(const char *name, char *buf)
{
int len = strlen(name);
start_match("event", name, buf);
if (MATCH(".event", utf8_string, &event.name))
return;
if (MATCH(".name", utf8_string, &event.name))
return;
if (MATCH(".time", eventtime, &event.time))
return;
if (MATCH(".type", get_index, &event.type))
return;
if (MATCH(".flags", get_index, &event.flags))
return;
nonmatch("event", name, buf);
}
/* We're in samples - try to convert the random xml value to something useful */
static void try_to_fill_sample(struct sample *sample, const char *name, char *buf)
{
@ -1137,11 +1169,15 @@ static void dive_end(void)
static void event_start(void)
{
memset(&event, 0, sizeof(event));
event.active = 1;
}
static void event_end(void)
{
event_index++;
if (event.name)
add_event(dive, event.time.seconds, event.type, event.flags, event.value, event.name);
event.active = 0;
}
static void cylinder_start(void)
@ -1156,7 +1192,6 @@ static void cylinder_end(void)
static void sample_start(void)
{
sample = prepare_sample(&dive);
event_index = 0;
}
static void sample_end(void)
@ -1176,6 +1211,10 @@ static void entry(const char *name, int size, const char *raw)
return;
memcpy(buf, raw, size);
buf[size] = 0;
if (event.active) {
try_to_fill_event(name, buf);
return;
}
if (sample) {
try_to_fill_sample(sample, name, buf);
return;

View file

@ -218,6 +218,12 @@ static void save_cylinder_info(FILE *f, struct dive *dive)
}
}
static void show_index(FILE *f, int value, const char *pre, const char *post)
{
if (value)
fprintf(f, " %s%d%s", pre, value, post);
}
static void save_sample(FILE *f, struct sample *sample)
{
fprintf(f, " <sample time='%u:%02u min'", FRACTION(sample->time.seconds,60));
@ -229,6 +235,25 @@ static void save_sample(FILE *f, struct sample *sample)
fprintf(f, " />\n");
}
static void save_one_event(FILE *f, struct event *ev)
{
fprintf(f, " <event time='%d:%02d min'", FRACTION(ev->time.seconds,60));
show_index(f, ev->type, "type='", "'");
show_index(f, ev->flags, "flags='", "'");
show_index(f, ev->value, "value='", "'");
show_utf8(f, ev->name, " name='", "'");
fprintf(f, " />\n");
}
static void save_events(FILE *f, struct event *ev)
{
while (ev) {
save_one_event(f, ev);
ev = ev->next;
}
}
static void save_dive(FILE *f, struct dive *dive)
{
int i;
@ -245,6 +270,7 @@ static void save_dive(FILE *f, struct dive *dive)
FRACTION(dive->duration.seconds, 60));
save_overview(f, dive);
save_cylinder_info(f, dive);
save_events(f, dive->events);
for (i = 0; i < dive->samples; i++)
save_sample(f, dive->sample+i);
fprintf(f, "</dive>\n");