diff --git a/examples/advanced_usages/overrides.c b/examples/advanced_usages/overrides.c index cf72b30..00a8acb 100644 --- a/examples/advanced_usages/overrides.c +++ b/examples/advanced_usages/overrides.c @@ -1,13 +1,28 @@ /* ** Example: overrides ** -** TODO full commentary +** This example shows using the overrides system in Metadesk to plug in a +** custom memory allocator and file loading routine. There are more options +** in the overrides than are presented here. A full list of the overrides +** options is kept in md.c 'Overrides & Options Macros' +** +** A few of the reasons one might want to use the Metadesk overrides are: +** 1. Plugging in a custom allocator to control the memory allocations +** 2. Plugging in a custom arena implementation for more seamless +** interoperation between the codebase and library +** 3. Provide implementation for unsupported OSes without having to modify + ** md.h or md.c +** 4. Remove dependency on CRT +** 5. Remove dependency on OS headers ** */ - //~ example allocator ///////////////////////////////////////////////////////// +// @notes This isn't really "the example" but we need something to play the +// role of a custom allocator, imagine this is any alloc & free style +// allocator you might already have in a codebase. + typedef struct ExampleAllocatorNode{ struct ExampleAllocatorNode *next; struct ExampleAllocatorNode *prev; @@ -25,6 +40,11 @@ void examp_free(ExampleAllocator *a, void *ptr); //~ include metadesk header /////////////////////////////////////////////////// +// @notes We include the metadesk header before we define the overrides because +// some overrides require that metadesk base types be visible. There are +// exceptions to this pattern, in particular overrides for types need to be +// defined before including md.h, we aren't going that far here. + #include "md.h" @@ -32,6 +52,12 @@ void examp_free(ExampleAllocator *a, void *ptr); // override memory to use malloc/free +// @notes A common practice in setting up allocator overrides is to use a pass +// through opaque user context pointer. We took a look at that for *long time* +// and just really don't like the amount of baggage it adds to the entire API. +// Instead we recommend handling the context pointer with a global for single +// threaded use cases, or with a pointer in thread local storage for +// multi-threaded cases. ExampleAllocator* md_example_allocator = 0; void* md_reserve_by_example_allocator(unsigned long long size); @@ -40,7 +66,7 @@ void md_release_by_example_allocator(void *ptr, unsigned long long ignore); #define MD_IMPL_Reserve md_reserve_by_example_allocator #define MD_IMPL_Commit(p,z) (1) #define MD_IMPL_Decommit(p,z) ((void)0) -#define MD_IMPL_Release(p,z) md_release_by_example_allocator +#define MD_IMPL_Release md_release_by_example_allocator // override file loading diff --git a/source/md.c b/source/md.c index 6b19270..defa30c 100644 --- a/source/md.c +++ b/source/md.c @@ -4,6 +4,11 @@ ** Overrides & Options Macros ** ** Overridable +** "basic types" ** REQUIRED +** #define/typedef MD_i8, MD_i16, MD_i32, MD_i64 +** #define/typedef MD_u8, MD_u16, MD_u32, MD_u64 +** #define/typedef MD_f32, MD_f64 +** ** "memset" ** REQUIRED ** #define MD_IMPL_Memset (void*, int, uint64) -> void* ** #define MD_IMPL_Memmove (void*, void*, uint64) -> void* @@ -42,6 +47,7 @@ ** ** Default Implementation Controls ** These controls default to '1' i.e. 'enabled' +** #define MD_DEFAULT_BASIC_TYPES -> construct "basic types" from stdint.h header ** #define MD_DEFAULT_MEMSET -> construct "memset" from CRT ** #define MD_DEFAULT_FILE_ITER -> construct "file iteration" from OS headers ** #define MD_DEFAULT_MEMORY -> construct "low level memory" from OS headers diff --git a/source/md.h b/source/md.h index 5d158d2..970eb32 100644 --- a/source/md.h +++ b/source/md.h @@ -29,6 +29,9 @@ #define MD_VERSION_MIN 0 //~ Set default values for controls +#if !defined(MD_DEFAULT_BASIC_TYPES) +# define MD_DEFAULT_BASIC_TYPES 1 +#endif #if !defined(MD_DEFAULT_MEMSET) # define MD_DEFAULT_MEMSET 1 #endif @@ -374,9 +377,11 @@ //~ Basic Types -#include #include +#if defined(MD_DEFAULT_BASIC_TYPES) + +#include typedef int8_t MD_i8; typedef int16_t MD_i16; typedef int32_t MD_i32; @@ -385,13 +390,16 @@ typedef uint8_t MD_u8; typedef uint16_t MD_u16; typedef uint32_t MD_u32; typedef uint64_t MD_u64; -typedef int8_t MD_b8; -typedef int16_t MD_b16; -typedef int32_t MD_b32; -typedef int64_t MD_b64; typedef float MD_f32; typedef double MD_f64; +#endif + +typedef MD_i8 MD_b8; +typedef MD_i16 MD_b16; +typedef MD_i32 MD_b32; +typedef MD_i64 MD_b64; + //~ Default Arena #if MD_DEFAULT_ARENA