API redesign progress
Jef Driesen
jefdriesen at telenet.be
Wed Jul 4 15:53:41 UTC 2012
Hi,
Now that we are discussing major api improvements, let's also have a
look at the sample parsing api. The current api generates a stream of
sample values, where the time value is special in the sense that it
starts a new sample. I think it would be cleaner to somehow return an
opaque sample, and then get all the values available for that sample.
Something similar to this:
void
sample_cb (dc_sample_t *sample, void *userdata)
{
dc_sample_get_time (sample, ...);
dc_sample_get_depth (sample, ...);
dc_sample_get_something (sample, ...);
...
}
Let's discuss this a bit in more detail.
1. Sample types
The first question is of course which sample types do we want to
support? The absolute minimum to support is:
* time
* depth
* pressure
* temperature
At the moment we also have:
* events: Anything that happens only at specific point in time. All
other sample types are typically measurements obtained from a sensor (or
calculations based on them), with values available for each sample point
(or at least every x sample points). But that is not the case for
events. Typical examples are warnings, gas changes, etc. At the moment
many events are supported, but the api sucks. The current plan is remove
the events, use the vendor type instead (see below), and then add back
support for the important events with a better api. The details of this
last part are still unclear, but support for gas switches is definitely
high on the list.
* rbt: The RBT (remaining bottom time) is the time you can spend at
the current depth and still have enough gas supply to make a safe
ascent. It's currently available for the Uwatec Smart/Galileo only.
Other air integrated dive computers often support a similar concept, so
I think we can just keep this. Maybe rename it to the less cryptic
"airtime"? Note that the actual interpretation may vary between models,
depending on whether factors like the safety reserve, the ascent time,
decompression time, etc are taking into account or not.
* heartbeat: Another Uwatec Smart/Galileo feature. Although I don't
know any other model that supports a heart monitor sensor, but it
doesn't cause any trouble either. So I think we can keep this one too.
BTW, is the correct name heartbeat or heartrate? I think it's heartrate,
expressed in beats per minute (bpm). It's a bit confusing because both
have the same translation in my native language.
* bearing: Yet another Uwatec Smart/Galileo feature. There are several
other models that have a digital compass, but they usually report it as
an event, not a sample type. I also believe it makes more sense to
consider a change in the compass bearing as an event. It's a setting you
change, not some sensor that is polled every sample. I don't think any
dive computer will ever generate a continuous stream with compass
bearings. So I think we should drop this. BTW, is the correct name
comnpass bearing or heading?
* vendor: A vendor specific extension. This is intended for all
samples that don't fit well into one of the types supported by the
libdivecomputer library. The application is responsible for parsing the
raw data, but at least it doesn't have to care about where and how the
samples are stored. There are actually two variants of the vendor type
today. For the first variant each piece of info gets its own vendor
sample. That means a dc_sample_t can contain multiple vendor values. The
second variant is the raw data representing the entire dc_sample_t data.
Both have their use, so I propose to reserve the vendor type for the
first case, and add a new raw type for the second case.
What else should we support? Some common requests I get are:
* gas switches
* no decompression time
* decompression stops
* ...
Decompression is a bit troublesome. Some models have just a simple deco
flag. Others provide a time and depth, which is typically the time to
surface (TTS) (e.g. total time for all stops and ascent combined) and
the depth of the current stop. But their are plenty of other
interpretations possible too. I won't be surprised some of the more
technical dive computers provide a full decoplan (e.g. time at each
depth). I have no idea how to support something like this in a clean
way.
Note that an alternative solution would be to implement a decompression
algorithm in the application and calculate all kinds of deco related
parameters (tissue saturation, deco stops, etc) that way. It won't
necessary match with your dive computer, but at least you would get a
consistent application experience, regardless of the type of dive
computer you have. Personally, I think this makes more sense for a
general purpose logbook application, but not everyone may agree with
that of course.
2. Which sample types are present?
With the current callback api, you just get all the sample types pushed
to the application. With the new proposal the application needs to
retrieve each sample value manually. Thus somehow we need a mechanism to
query which sample types are available in the dc_sample_t object.
Suggestions are welcome.
Also, how do we deal with sample types that can occur multiple times
(e.g. vendor extensions, pressure values for multiple tanks, alarms,
etc)?
3. Memory management
To be consistent with the dc_dive_t object, the dc_sample_t object
should be allocated by the dc_dive_t object and freed by the
application. However I'm not convinced that is a good idea. The number
of samples is usually relative large (e.g. 3600 samples for a 1 hour
dive at a 1 second sample rate) and in the typical scenario there is no
reason to retain the sample object after having extracting the values
(e.g. you call free right before leaving the callback function). Thus
you end up with several hundreds or thousands of tiny objects that are
allocated and immediately freed again. That's just very inefficient if
you ask me!
A possible workaround would be to make the objects reference counted.
Then, if the application doesn't keep a reference to the object, we can
re-use the previous one, instead of creating a new one from scratch. But
the drawback is that if we want to support passing objects between
threads (see my previous email) the reference counting should be made
thread-safe too.
Note that I'm not an export on multi-threading, so please correct me if
I'm writing nonsense! Also everything I wrote so far is open for
discussion. Feedback is highly appreciated!
Jef
More information about the Devel
mailing list