Added memory checks
This commit is contained in:
9
src/item/backpack.h
Normal file
9
src/item/backpack.h
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "inventory.h"
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "inventory.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/sort.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
void inventoryInit(
|
||||
@@ -113,7 +114,11 @@ void inventoryRemove(inventory_t *inventory, const itemid_t item) {
|
||||
if(stack->item != item) continue;
|
||||
|
||||
// Match found, shift everything else down
|
||||
memoryMove(stack, stack + 1, end - (stack + 1));
|
||||
memoryMove(
|
||||
stack,
|
||||
stack + 1,
|
||||
(end - (stack + 1)) * sizeof(inventorystack_t)
|
||||
);
|
||||
|
||||
// Clear last stack.
|
||||
inventorystack_t *last = end - 1;
|
||||
@@ -162,4 +167,31 @@ bool_t inventoryIsFull(const inventory_t *inventory) {
|
||||
|
||||
bool_t inventoryItemFull(const inventory_t *inventory, const itemid_t item) {
|
||||
return inventoryGetCount(inventory, item) == ITEM_STACK_QUANTITY_MAX;
|
||||
}
|
||||
|
||||
void inventorySortById(inventory_t *inventory) {
|
||||
assertNotNull(inventory, "Inventory pointer is NULL.");
|
||||
assertNotNull(inventory->storage, "Storage pointer is NULL.");
|
||||
assertTrue(inventory->storageSize > 0, "Storage too small.");
|
||||
|
||||
// Get count of used stacks
|
||||
size_t count = 0;
|
||||
inventorystack_t *stack = inventory->storage;
|
||||
inventorystack_t *end = stack + inventory->storageSize;
|
||||
do {
|
||||
if(stack->item == ITEM_ID_NULL) break;
|
||||
count++;
|
||||
} while(++stack < end);
|
||||
|
||||
if(count == 0) return; // Nothing to sort
|
||||
|
||||
int_t comparator(const void *a, const void *b) {
|
||||
const inventorystack_t *stackA = (const inventorystack_t*)a;
|
||||
const inventorystack_t *stackB = (const inventorystack_t*)b;
|
||||
if(stackA->item < stackB->item) return -1;
|
||||
if(stackA->item > stackB->item) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sort((void*)inventory->storage, count, sizeof(inventorystack_t), comparator);
|
||||
}
|
||||
@@ -100,4 +100,18 @@ bool_t inventoryIsFull(const inventory_t *inventory);
|
||||
* @param item The item ID to check.
|
||||
* @return true if the item stack is full, false otherwise.
|
||||
*/
|
||||
bool_t inventoryItemFull(const inventory_t *inventory, const itemid_t item);
|
||||
bool_t inventoryItemFull(const inventory_t *inventory, const itemid_t item);
|
||||
|
||||
/**
|
||||
* Sorts the inventory by item ID in ascending order.
|
||||
*
|
||||
* @param inventory The inventory to sort.
|
||||
*/
|
||||
void inventorySortById(inventory_t *inventory);
|
||||
|
||||
/**
|
||||
* Sorts the inventory by item type in ascending order.
|
||||
*
|
||||
* @param inventory The inventory to sort.
|
||||
*/
|
||||
void inventorySortByType(inventory_t *inventory);
|
||||
@@ -16,4 +16,14 @@ const item_t ITEMS[] = {
|
||||
[ITEM_ID_POTION] = {
|
||||
.type = ITEM_TYPE_MEDICINE
|
||||
},
|
||||
|
||||
// Potato
|
||||
[ITEM_ID_POTATO] = {
|
||||
.type = ITEM_TYPE_INGREDIENT
|
||||
},
|
||||
|
||||
// Apple
|
||||
[ITEM_ID_APPLE] = {
|
||||
.type = ITEM_TYPE_INGREDIENT
|
||||
}
|
||||
};
|
||||
@@ -12,10 +12,12 @@ typedef struct {
|
||||
itemtype_t type;
|
||||
} item_t;
|
||||
|
||||
typedef uint8_t itemid_t;
|
||||
typedef enum {
|
||||
ITEM_ID_NULL = 0,
|
||||
|
||||
#define ITEM_ID_NULL 0
|
||||
#define ITEM_ID_POTION 1
|
||||
#define ITEM_ID_POTATO 2
|
||||
ITEM_ID_POTION,
|
||||
ITEM_ID_POTATO,
|
||||
ITEM_ID_APPLE
|
||||
} itemid_t;
|
||||
|
||||
extern const item_t ITEMS[];
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "dusk.h"
|
||||
|
||||
typedef enum {
|
||||
ITEM_TYPE_NULL,
|
||||
ITEM_TYPE_NULL = 0,
|
||||
|
||||
ITEM_TYPE_MEDICINE,
|
||||
ITEM_TYPE_INGREDIENT,
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
array.c
|
||||
memory.c
|
||||
string.c
|
||||
math.c
|
||||
sort.c
|
||||
)
|
||||
39
src/util/array.c
Normal file
39
src/util/array.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "array.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
void arrayReverse(
|
||||
void *array,
|
||||
const size_t count,
|
||||
const size_t size
|
||||
) {
|
||||
assertNotNull(array, "Cannot reverse NULL memory.");
|
||||
assertTrue(size > 0, "Element size must be greater than zero.");
|
||||
|
||||
if(count == 0) return;
|
||||
|
||||
// For half the array length, swap elements
|
||||
uint8_t *start = (uint8_t*)array;
|
||||
uint8_t *end = start + (count - 1) * size;
|
||||
uint8_t *temp = (uint8_t*)memoryAllocate(size);
|
||||
|
||||
// Floorf
|
||||
size_t i;
|
||||
for(i = 0; i < count / 2; i++) {
|
||||
// Swap start and end
|
||||
memoryCopy(temp, start, size);
|
||||
memoryCopy(start, end, size);
|
||||
memoryCopy(end, temp, size);
|
||||
start += size;
|
||||
end -= size;
|
||||
}
|
||||
|
||||
memoryFree(temp);
|
||||
}
|
||||
22
src/util/array.h
Normal file
22
src/util/array.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
|
||||
/**
|
||||
* Reverses the order of elements in an array.
|
||||
*
|
||||
* @param array The array to reverse.
|
||||
* @param count The number of elements in the array.
|
||||
* @param size The size of each element (the stride).
|
||||
*/
|
||||
void arrayReverse(
|
||||
void *array,
|
||||
const size_t count,
|
||||
const size_t size
|
||||
);
|
||||
@@ -9,16 +9,22 @@
|
||||
#include "assert/assert.h"
|
||||
#include "util/math.h"
|
||||
|
||||
size_t memoryGetAllocatedCount(void) {
|
||||
return MEMORY_POINTERS_IN_USE;
|
||||
}
|
||||
|
||||
void * memoryAllocate(const size_t size) {
|
||||
assertTrue(size > 0, "Cannot allocate 0 bytes of memory.");
|
||||
void *ptr = malloc(size);
|
||||
assertNotNull(ptr, "Memory allocation failed.");
|
||||
MEMORY_POINTERS_IN_USE++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void memoryFree(void *ptr) {
|
||||
assertNotNull(ptr, "Cannot free NULL memory.");
|
||||
free(ptr);
|
||||
MEMORY_POINTERS_IN_USE--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,15 @@
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
|
||||
static size_t MEMORY_POINTERS_IN_USE = 0;
|
||||
|
||||
/**
|
||||
* Gets the number of currently allocated memory blocks.
|
||||
*
|
||||
* @return The number of allocated memory blocks.
|
||||
*/
|
||||
size_t memoryGetAllocatedCount(void);
|
||||
|
||||
/**
|
||||
* Allocates memory.
|
||||
*
|
||||
|
||||
71
src/util/sort.c
Normal file
71
src/util/sort.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <stdlib.h>
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "sort.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
void sortBubble(
|
||||
void *array,
|
||||
const size_t count,
|
||||
const size_t size,
|
||||
const sortcompare_t compare
|
||||
) {
|
||||
assertNotNull(array, "Cannot sort NULL memory.");
|
||||
assertTrue(count > 0, "Cannot sort 0 elements.");
|
||||
assertTrue(size > 0, "Element size must be greater than zero.");
|
||||
assertNotNull(compare, "Compare function cannot be NULL.");
|
||||
|
||||
// Create variables
|
||||
uint8_t *temp = (uint8_t*)memoryAllocate(size);
|
||||
bool_t swapped;
|
||||
uint8_t *a, *b;
|
||||
size_t i;
|
||||
|
||||
do {
|
||||
swapped = false;
|
||||
for(i = 1; i < count; i++) {
|
||||
a = array + (i - 1) * size;
|
||||
b = array + i * size;
|
||||
if(compare(a, b) > 0) {
|
||||
// Swap
|
||||
memoryCopy(temp, a, size);
|
||||
memoryCopy(a, b, size);
|
||||
memoryCopy(b, temp, size);
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
} while(swapped);
|
||||
|
||||
memoryFree(temp);
|
||||
}
|
||||
|
||||
void sortQuick(
|
||||
void *array,
|
||||
const size_t count,
|
||||
const size_t size,
|
||||
const sortcompare_t compare
|
||||
) {
|
||||
assertNotNull(array, "Cannot sort NULL memory.");
|
||||
assertTrue(count > 0, "Cannot sort 0 elements.");
|
||||
assertTrue(size > 0, "Element size must be greater than zero.");
|
||||
assertNotNull(compare, "Compare function cannot be NULL.");
|
||||
|
||||
// qsort expects a comparator returning int, which matches sortcompare_t
|
||||
qsort(array, count, size, compare);
|
||||
}
|
||||
|
||||
void sortArrayU8(uint8_t *array, const size_t count) {
|
||||
int_t compare(const void *a, const void *b) {
|
||||
uint8_t valA = *(const uint8_t*)a;
|
||||
uint8_t valB = *(const uint8_t*)b;
|
||||
return (valA > valB) - (valA < valB);
|
||||
}
|
||||
|
||||
return sort((void*)array, count, sizeof(uint8_t), compare);
|
||||
}
|
||||
56
src/util/sort.h
Normal file
56
src/util/sort.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
|
||||
typedef int_t (*sortcompare_t)(const void*, const void*);
|
||||
|
||||
/**
|
||||
* Sorts an array using the bubble sort algorithm.
|
||||
*
|
||||
* @param array The array to sort.
|
||||
* @param count The number of elements in the array.
|
||||
* @param size The size of each element.
|
||||
* @param compare The comparison function.
|
||||
*/
|
||||
void sortBubble(
|
||||
void *array,
|
||||
const size_t count,
|
||||
const size_t size,
|
||||
const sortcompare_t compare
|
||||
);
|
||||
|
||||
/**
|
||||
* Sorts an array using the quicksort algorithm.
|
||||
*
|
||||
* @param array The array to sort.
|
||||
* @param count The number of elements in the array.
|
||||
* @param size The size of each element.
|
||||
* @param compare The comparison function.
|
||||
*/
|
||||
void sortQuick(
|
||||
void *array,
|
||||
const size_t count,
|
||||
const size_t size,
|
||||
const sortcompare_t compare
|
||||
);
|
||||
|
||||
/**
|
||||
* Preferred sort function.
|
||||
*
|
||||
* @see sortQuick
|
||||
*/
|
||||
#define sort sortQuick
|
||||
|
||||
/**
|
||||
* Sorts an array of uint8_t in ascending order.
|
||||
*
|
||||
* @param array The array to sort.
|
||||
* @param count The number of elements in the array.
|
||||
*/
|
||||
void sortArrayU8(uint8_t *array, const size_t count);
|
||||
Reference in New Issue
Block a user