About to refator tools... again

This commit is contained in:
2025-09-01 17:22:33 -05:00
parent 3ce1566a2e
commit 4541d5219b
14 changed files with 468 additions and 43 deletions

View File

@@ -9,4 +9,5 @@ target_sources(${DUSK_TARGET_NAME}
memory.c
string.c
math.c
reflist.c
)

83
src/util/reflist.c Normal file
View File

@@ -0,0 +1,83 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "reflist.h"
#include "util/memory.h"
#include "assert/assert.h"
void refListInit(
reflist_t *list,
ref_t *array,
const uint_fast16_t max
) {
assertNotNull(list, "Reference list cannot be NULL");
assertNotNull(array, "Reference array cannot be NULL");
assertTrue(max > 0, "Reference list max must be greater than 0");
assertTrue(max <= UINT16_MAX, "Reference list too large");
memoryZero(list, sizeof(reflist_t));
memoryZero(array, sizeof(ref_t) * max);
list->array = array;
list->max = max;
}
ref_t refListLock(reflist_t *list) {
assertFalse(refListIsFull(list), "Reference list is full");
ref_t ref = list->refNext++;
assertTrue(ref > 0, "Reference ID overflow");
assertTrue(ref < UINT16_MAX, "Reference ID too large.");
bool_t empty = list->onNotEmpty && refListIsEmpty(list);
list->array[list->count++] = ref;
if(empty) list->onNotEmpty(list);
if(list->onAdd) list->onAdd(list, ref);
if(list->onFull && refListIsFull(list)) list->onFull(list);
return ref;
}
void refListUnlock(reflist_t *list, const ref_t ref) {
assertFalse(refListIsEmpty(list), "Reference list is empty");
ref_t *slot = list->array;
ref_t *end = list->array + list->count;
do {
if(*slot == ref) break;
++slot;
} while(slot < end);
assertTrue(slot < end, "Reference not found in list");
memoryMove(slot, slot + 1, (end - slot - 1) * sizeof(ref_t));
list->count--;
if(list->onRemove) list->onRemove(list, ref);
if(list->onEmpty && refListIsEmpty(list)) list->onEmpty(list);
}
bool_t refListIsFull(const reflist_t *list) {
assertNotNull(list, "Reference list cannot be NULL");
assertNotNull(list->array, "Reference list array cannot be NULL");
assertTrue(list->max > 0, "Reference list max must be greater than 0");
assertTrue(list->max <= UINT16_MAX, "Reference list too large");
return (list->count >= list->max);
}
bool_t refListIsEmpty(const reflist_t *list) {
assertNotNull(list, "Reference list cannot be NULL");
assertNotNull(list->array, "Reference list array cannot be NULL");
assertTrue(list->max > 0, "Reference list max must be greater than 0");
assertTrue(list->max <= UINT16_MAX, "Reference list too large");
return (list->count == 0);
}

77
src/util/reflist.h Normal file
View File

@@ -0,0 +1,77 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef uint_fast16_t ref_t;
typedef struct reflist_s reflist_t;
typedef struct reflist_s {
ref_t *array;
uint_fast16_t max;
uint_fast16_t count;
ref_t refNext;
void *user;
void (*onNotEmpty)(reflist_t *list);
void (*onFull)(reflist_t *list);
void (*onAdd)(reflist_t *list, const ref_t ref);
void (*onRemove)(reflist_t *list, const ref_t ref);
void (*onEmpty)(reflist_t *list);
} reflist_t;
/**
* Initialize a reference list. Reference lists just hold a list of references
* that are "holding on to" a given object/resource.
*
* @param list The reference list to initialize.
* @param array The array to use as backing storage for the list.
* @param max The maximum number of references the list can hold.
*/
void refListInit(
reflist_t *list,
ref_t *array,
const uint_fast16_t max
);
/**
* Lock a reference in the list. This will return a new reference ID that can be
* used to access the locked reference.
*
* @param list The reference list to lock a reference in.
* @return The locked reference ID, or 0 if the list is full.
*/
ref_t refListLock(reflist_t *list);
/**
* Unlock a reference in the list. This will free up the reference ID for
* reuse.
*
* @param list The reference list to unlock a reference in.
* @param ref The reference ID to unlock.
*/
void refListUnlock(reflist_t *list, const ref_t ref);
/**
* Checks if the reference list is full.
*
* @param list The reference list to check.
* @return true if the list is full, false otherwise.
*/
bool_t refListIsFull(const reflist_t *list);
/**
* Checks if the reference list is empty.
*
* @param list The reference list to check.
* @return true if the list is empty, false otherwise.
*/
bool_t refListIsEmpty(const reflist_t *list);