mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	To allow efficient moving of downloaded dives from the download thread to the model, implement a general move function that moves table data. Instantiate that function for the dive and dive_site tables. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
		
			
				
	
	
		
			113 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| /* This header defines a number of macros that generate table-manipulation functions.
 | |
|  * There is no design behind these macros - the functions were take as-is and transformed
 | |
|  * into macros. Thus, this whole header could do with some redesign. */
 | |
| #ifndef CORE_TABLE_H
 | |
| #define CORE_TABLE_H
 | |
| 
 | |
| #define MAKE_GROW_TABLE(table_type, item_type, array_name) \
 | |
| 	item_type *grow_##table_type(struct table_type *table)				\
 | |
| 	{										\
 | |
| 		int nr = table->nr, allocated = table->allocated;			\
 | |
| 		item_type *items = table->array_name;					\
 | |
| 											\
 | |
| 		if (nr >= allocated) {							\
 | |
| 			allocated = (nr + 32) * 3 / 2;					\
 | |
| 			items = realloc(items, allocated * sizeof(item_type));		\
 | |
| 			if (!items)							\
 | |
| 				exit(1);						\
 | |
| 			table->array_name = items;					\
 | |
| 			table->allocated = allocated;					\
 | |
| 		}									\
 | |
| 		return items;								\
 | |
| 	}
 | |
| 
 | |
| /* get the index where we want to insert an object so that everything stays
 | |
|  * ordered according to a comparison function() */
 | |
| #define MAKE_GET_INSERTION_INDEX(table_type, item_type, array_name, fun)		\
 | |
| 	int table_type##_get_insertion_index(struct table_type *table, item_type item)	\
 | |
| 	{										\
 | |
| 		/* we might want to use binary search here */				\
 | |
| 		for (int i = 0; i < table->nr; i++) {					\
 | |
| 			if (fun(item, table->array_name[i]))				\
 | |
| 				return i;						\
 | |
| 		}									\
 | |
| 		return table->nr;							\
 | |
| 	}
 | |
| 
 | |
| /* add object at the given index to a table. */
 | |
| #define MAKE_ADD_TO(table_type, item_type, array_name)					\
 | |
| 	void add_to_##table_type(struct table_type *table, int idx, item_type item)	\
 | |
| 	{										\
 | |
| 		int i;									\
 | |
| 		grow_##table_type(table);						\
 | |
| 		table->nr++;								\
 | |
| 											\
 | |
| 		for (i = idx; i < table->nr; i++) {					\
 | |
| 			item_type tmp = table->array_name[i];				\
 | |
| 			table->array_name[i] = item;					\
 | |
| 			item = tmp;							\
 | |
| 		}									\
 | |
| 	}
 | |
| 
 | |
| #define MAKE_REMOVE_FROM(table_type, array_name)						\
 | |
| 	void remove_from_##table_type(struct table_type *table, int idx)			\
 | |
| 	{											\
 | |
| 		int i;										\
 | |
| 		for (i = idx; i < table->nr - 1; i++)						\
 | |
| 			table->array_name[i] = table->array_name[i + 1];			\
 | |
| 		memset(&table->array_name[--table->nr], 0, sizeof(table->array_name[0]));	\
 | |
| 	}
 | |
| 
 | |
| #define MAKE_GET_IDX(table_type, item_type, array_name)						\
 | |
| 	int get_idx_in_##table_type(const struct table_type *table, const item_type item)	\
 | |
| 	{											\
 | |
| 		for (int i = 0; i < table->nr; ++i) {						\
 | |
| 			if (table->array_name[i] == item)					\
 | |
| 				return i;							\
 | |
| 		}										\
 | |
| 		return -1;									\
 | |
| 	}
 | |
| 
 | |
| #define MAKE_SORT(table_type, item_type, array_name, fun)					\
 | |
| 	static int sortfn_##table_type(const void *_a, const void *_b)				\
 | |
| 	{											\
 | |
| 		const item_type a = (const item_type)*(const void **)_a;			\
 | |
| 		const item_type b = (const item_type)*(const void **)_b;			\
 | |
| 		return fun(a, b);								\
 | |
| 	}											\
 | |
| 												\
 | |
| 	void sort_##table_type(struct table_type *table)					\
 | |
| 	{											\
 | |
| 		qsort(table->array_name, table->nr, sizeof(item_type), sortfn_##table_type);	\
 | |
| 	}
 | |
| 
 | |
| #define MAKE_REMOVE(table_type, item_type, item_name)				\
 | |
| 	int remove_##item_name(const item_type item, struct table_type *table)	\
 | |
| 	{									\
 | |
| 		int idx = get_idx_in_##table_type(table, item);			\
 | |
| 		if (idx >= 0)							\
 | |
| 			remove_from_##table_type(table, idx);			\
 | |
| 		return idx;							\
 | |
| 	}
 | |
| 
 | |
| #define MAKE_CLEAR_TABLE(table_type, array_name, item_name)			\
 | |
| 	void clear_##table_type(struct table_type *table)			\
 | |
| 	{									\
 | |
| 		for (int i = 0; i < table->nr; i++)				\
 | |
| 			free_##item_name(table->array_name[i]);			\
 | |
| 		table->nr = 0;							\
 | |
| 	}
 | |
| 
 | |
| /* Move data of one table to the other - source table is empty after call. */
 | |
| #define MAKE_MOVE_TABLE(table_type, array_name)					\
 | |
| 	void move_##table_type(struct table_type *src, struct table_type *dst)	\
 | |
| 	{									\
 | |
| 		clear_##table_type(dst);					\
 | |
| 		free(dst->array_name);						\
 | |
| 		*dst = *src;							\
 | |
| 		src->nr = src->allocated = 0;					\
 | |
| 		src->array_name = NULL;						\
 | |
| 	}
 | |
| 
 | |
| #endif
 |