mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Cleanup: macroize dive site table functions, keep table sorted
Turn the table functions of the dive site handling into macros as was already used for dives and dive trips. This has the effect that the table is kept sorted by UUID. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
a6f65d744f
commit
84f7179367
3 changed files with 25 additions and 47 deletions
|
@ -5,6 +5,7 @@
|
|||
#include "subsurface-string.h"
|
||||
#include "divelist.h"
|
||||
#include "membuffer.h"
|
||||
#include "table.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -108,12 +109,26 @@ void register_dive_site(struct dive_site *ds)
|
|||
add_dive_site_to_table(ds, &dive_site_table);
|
||||
}
|
||||
|
||||
static int compare_sites(const struct dive_site *a, const struct dive_site *b)
|
||||
{
|
||||
return a->uuid > b->uuid ? 1 : a->uuid == b->uuid ? 0 : -1;
|
||||
}
|
||||
|
||||
static int site_less_than(const struct dive_site *a, const struct dive_site *b)
|
||||
{
|
||||
return compare_sites(a, b) < 0;
|
||||
}
|
||||
|
||||
static MAKE_GROW_TABLE(dive_site_table, struct dive_site *, dive_sites)
|
||||
static MAKE_GET_INSERTION_INDEX(dive_site_table, struct dive_site *, dive_sites, site_less_than)
|
||||
static MAKE_ADD_TO(dive_site_table, struct dive_site *, dive_sites)
|
||||
static MAKE_REMOVE_FROM(dive_site_table, dive_sites)
|
||||
static MAKE_GET_IDX(dive_site_table, struct dive_site *, dive_sites)
|
||||
MAKE_SORT(dive_site_table, struct dive_site *, dive_sites, compare_sites)
|
||||
static MAKE_REMOVE(dive_site_table, struct dive_site *, dive_site)
|
||||
|
||||
void add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table)
|
||||
{
|
||||
int nr = ds_table->nr;
|
||||
int allocated = ds_table->allocated;
|
||||
struct dive_site **sites = ds_table->dive_sites;
|
||||
|
||||
/* Take care to never have the same uuid twice. This could happen on
|
||||
* reimport of a log where the dive sites have diverged */
|
||||
while (ds->uuid == 0 || get_dive_site_by_uuid(ds->uuid, ds_table) != NULL) {
|
||||
|
@ -123,16 +138,8 @@ void add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_tab
|
|||
ds->uuid |= (rand() & 0xff) << 24;
|
||||
}
|
||||
|
||||
if (nr >= allocated) {
|
||||
allocated = (nr + 32) * 3 / 2;
|
||||
sites = realloc(sites, allocated * sizeof(struct dive_site *));
|
||||
if (!sites)
|
||||
exit(1);
|
||||
ds_table->dive_sites = sites;
|
||||
ds_table->allocated = allocated;
|
||||
}
|
||||
sites[nr] = ds;
|
||||
ds_table->nr = nr + 1;
|
||||
int idx = dive_site_table_get_insertion_index(ds_table, ds);
|
||||
add_to_dive_site_table(ds_table, idx, ds);
|
||||
}
|
||||
|
||||
struct dive_site *alloc_dive_site()
|
||||
|
@ -192,29 +199,14 @@ void free_dive_site(struct dive_site *ds)
|
|||
|
||||
void unregister_dive_site(struct dive_site *ds)
|
||||
{
|
||||
remove_dive_site_from_table(ds, &dive_site_table);
|
||||
}
|
||||
|
||||
void remove_dive_site_from_table(struct dive_site *ds, struct dive_site_table *ds_table)
|
||||
{
|
||||
int nr = ds_table->nr;
|
||||
for (int i = 0; i < nr; i++) {
|
||||
if (ds == get_dive_site(i, ds_table)) {
|
||||
if (nr - 1 > i)
|
||||
memmove(&ds_table->dive_sites[i],
|
||||
&ds_table->dive_sites[i+1],
|
||||
(nr - 1 - i) * sizeof(ds_table->dive_sites[0]));
|
||||
ds_table->nr = nr - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
remove_dive_site(ds, &dive_site_table);
|
||||
}
|
||||
|
||||
void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table)
|
||||
{
|
||||
if (!ds)
|
||||
return;
|
||||
remove_dive_site_from_table(ds, ds_table);
|
||||
remove_dive_site(ds, ds_table);
|
||||
free_dive_site(ds);
|
||||
}
|
||||
|
||||
|
@ -395,16 +387,3 @@ struct dive_site *unregister_dive_from_dive_site(struct dive *d)
|
|||
d->dive_site = NULL;
|
||||
return ds;
|
||||
}
|
||||
|
||||
/* Assign arbitrary UUIDs to dive sites. This is called by before writing the dive log to XML or git. */
|
||||
static int compare_sites(const void *_a, const void *_b)
|
||||
{
|
||||
const struct dive_site *a = (const struct dive_site *)*(void **)_a;
|
||||
const struct dive_site *b = (const struct dive_site *)*(void **)_b;
|
||||
return a->uuid > b->uuid ? 1 : a->uuid == b->uuid ? 0 : -1;
|
||||
}
|
||||
|
||||
void dive_site_table_sort(struct dive_site_table *ds_table)
|
||||
{
|
||||
qsort(ds_table->dive_sites, ds_table->nr, sizeof(struct dive_site *), compare_sites);
|
||||
}
|
||||
|
|
|
@ -46,9 +46,8 @@ static inline struct dive_site *get_dive_site(int nr, struct dive_site_table *ds
|
|||
|
||||
int get_divesite_idx(const struct dive_site *ds, struct dive_site_table *ds_table);
|
||||
struct dive_site *get_dive_site_by_uuid(uint32_t uuid, struct dive_site_table *ds_table);
|
||||
void dive_site_table_sort(struct dive_site_table *ds_table);
|
||||
void sort_dive_site_table(struct dive_site_table *ds_table);
|
||||
void add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table);
|
||||
void remove_dive_site_from_table(struct dive_site *ds, struct dive_site_table *ds_table);
|
||||
void register_dive_site(struct dive_site *ds);
|
||||
void unregister_dive_site(struct dive_site *ds);
|
||||
struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table);
|
||||
|
|
|
@ -591,7 +591,7 @@ void save_dives_buffer(struct membuffer *b, const bool select_only, bool anonymi
|
|||
put_format(b, "</settings>\n");
|
||||
|
||||
/* save the dive sites - to make the output consistent let's sort the table, first */
|
||||
dive_site_table_sort(&dive_site_table);
|
||||
sort_dive_site_table(&dive_site_table);
|
||||
purge_empty_dive_sites(&dive_site_table);
|
||||
put_format(b, "<divesites>\n");
|
||||
for (i = 0; i < dive_site_table.nr; i++) {
|
||||
|
|
Loading…
Add table
Reference in a new issue