Adding some assertions
This commit is contained in:
24
src/assert/assert.h
Normal file
24
src/assert/assert.h
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
|
||||
#define ASSERT_TRUE(x) assert(x)
|
||||
|
||||
#define ASSERT_NOT_NULL(x) ASSERT_TRUE(x != NULL)
|
||||
|
||||
#define ASSERT_IF(x, y) (x ? y : false)
|
||||
|
||||
#define ASSERT_EQUAL(x, y) ASSERT_TRUE(x == y)
|
||||
#define ASSERT_NOT_EQUAL(x, y) ASSERT_TRUE(x != y)
|
||||
|
||||
#define ASSERT_LESS_THAN(x, y) ASSERT_TRUE(x < y)
|
||||
#define ASSERT_LESS_THAN_EQUAL_TO (x, y) ASSERT_TRUE(x <= y)
|
||||
|
||||
#define ASSERT_GREATER_THAN(x, y) ASSERT_TRUE(x > y)
|
||||
#define ASSERT_GREATER_THAN_EQUAL_TO(x, y) ASSERT_TRUE(x >= y)
|
@ -19,8 +19,8 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8_t channels;
|
||||
char *file;
|
||||
char *path;
|
||||
const char *file;
|
||||
const char *path;
|
||||
int16_t baseWidth;
|
||||
int16_t baseHeight;
|
||||
|
||||
|
@ -9,4 +9,5 @@ target_sources(${PROJECT_NAME}
|
||||
client.c
|
||||
engine.c
|
||||
thread.c
|
||||
event.c
|
||||
)
|
||||
|
81
src/engine/event.c
Normal file
81
src/engine/event.c
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "event.h"
|
||||
|
||||
void eventManagerInit(eventmanager_t *manager) {
|
||||
uint8_t i;
|
||||
|
||||
ASSERT_NOT_NULL(manager);
|
||||
|
||||
for(i = 0; i < EVENT_LISTENER_COUNT_MAX; i++) {
|
||||
manager->listeners[i].callback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool _eventManagerFindFree(int32_t i, void *item) {
|
||||
return ((eventlistener_t *) item)->callback == NULL;
|
||||
}
|
||||
|
||||
eventlistener_t * eventManagerSubscribe(
|
||||
eventmanager_t *man, event_t event, void *user, eventcallback_t *callback
|
||||
) {
|
||||
int32_t first;
|
||||
eventlistener_t *listener;
|
||||
|
||||
ASSERT_NOT_NULL(man);
|
||||
ASSERT_NOT_NULL(callback);
|
||||
|
||||
// Find the first available space.
|
||||
first = arrayFindCallback(
|
||||
sizeof(eventmanager_t), man->listeners,
|
||||
EVENT_LISTENER_COUNT_MAX, _eventManagerFindFree
|
||||
);
|
||||
|
||||
ASSERT_LESS_THAN(first, EVENT_LISTENER_COUNT_MAX);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(first, 0);
|
||||
|
||||
// Insert
|
||||
listener = man->listeners + first;
|
||||
listener->callback = callback;
|
||||
listener->user = user;
|
||||
listener->event = event;
|
||||
|
||||
return listener;
|
||||
}
|
||||
|
||||
void eventManagerUnsubscribe(eventmanager_t *man, eventlistener_t *listener) {
|
||||
ASSERT_NOT_NULL(man);
|
||||
ASSERT_NOT_NULL(listener);
|
||||
|
||||
listener->callback = NULL;
|
||||
}
|
||||
|
||||
bool eventManagerTrigger(
|
||||
eventmanager_t *manager, event_t event, void *args[], int32_t argc
|
||||
) {
|
||||
uint8_t i;
|
||||
eventlistener_t *listener;
|
||||
bool result;
|
||||
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(argc, 0);
|
||||
ASSERT_IF(
|
||||
argc > 0,
|
||||
ASSERT_NOT_NULL(args)
|
||||
);
|
||||
|
||||
for(i = 0; i < EVENT_LISTENER_COUNT_MAX; i++) {
|
||||
listener = manager->listeners + i;
|
||||
if(listener->callback == NULL) continue;
|
||||
if(listener->event != event) continue;
|
||||
|
||||
result = listener->callback(listener->user, event, args, argc);
|
||||
if(!result) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
68
src/engine/event.h
Normal file
68
src/engine/event.h
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "../assert/assert.h"
|
||||
#include "../util/array.h"
|
||||
|
||||
#define EVENT_LISTENER_COUNT_MAX 128
|
||||
|
||||
typedef uint8_t event_t;
|
||||
|
||||
typedef bool eventcallback_t(
|
||||
void *user, event_t event, void *args[], int32_t argc
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
void *user;
|
||||
event_t event;
|
||||
eventcallback_t *callback;
|
||||
} eventlistener_t;
|
||||
|
||||
typedef struct {
|
||||
eventlistener_t listeners[EVENT_LISTENER_COUNT_MAX];
|
||||
} eventmanager_t;
|
||||
|
||||
/**
|
||||
* Initialize the event manager.
|
||||
*
|
||||
* @param manager Event manager to initialize.
|
||||
*/
|
||||
void eventManagerInit(eventmanager_t *manager);
|
||||
|
||||
/**
|
||||
* Subscribe to an event on a given event manager.
|
||||
*
|
||||
* @param man Event manager to subscribe to.
|
||||
* @param event Event to subscribe to.
|
||||
* @param user Any custom user data to provide to the event callback.
|
||||
* @param callback Callback to fire when the event is triggered.
|
||||
* @return The event listener that was subscribed to.
|
||||
*/
|
||||
eventlistener_t * eventManagerSubscribe(
|
||||
eventmanager_t *man, event_t event, void *user, eventcallback_t *callback
|
||||
);
|
||||
|
||||
/**
|
||||
* Unsubscribe an event listener that was previously subscribed.
|
||||
*
|
||||
* @param listener Listener to unsubscribe.
|
||||
*/
|
||||
void eventManagerUnsubscribe(eventmanager_t *man, eventlistener_t *listener);
|
||||
|
||||
/**
|
||||
* Trigger a specific event on the event manager.
|
||||
*
|
||||
* @param manager Manager to trigger the event on.
|
||||
* @param event Event to trigger
|
||||
* @param args Array of pointers for event arguments.
|
||||
* @param argc Count of event arguments.
|
||||
* @return True if no events are subscribed, otherwise only returns true if all
|
||||
* event listeners also return true.
|
||||
*/
|
||||
bool eventManagerTrigger(
|
||||
eventmanager_t *manager, event_t event, void *args[], int32_t argc
|
||||
);
|
@ -11,22 +11,26 @@ assetmanagerloaderdefinition_t ASSET_MANAGER_LOADERS[] = {
|
||||
{
|
||||
&_assetManagerLoaderTextureAsync,
|
||||
&_assetManagerLoaderTextureSync,
|
||||
&_assetManagerLoaderTextureDispose
|
||||
&_assetManagerLoaderTextureDispose,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
&_assetManagerLoaderFontAsync,
|
||||
&_assetManagerLoaderFontSync,
|
||||
&_assetManagerLoaderFontDispose
|
||||
&_assetManagerLoaderFontDispose,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
&_assetManagerLoaderShaderAsync,
|
||||
&_assetManagerLoaderShaderSync,
|
||||
&_assetManagerLoaderShaderDispose
|
||||
&_assetManagerLoaderShaderDispose,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
&_assetManagerLoaderScaledTextureAsync,
|
||||
&_assetManagerLoaderScaledTextureSync,
|
||||
&_assetManagerLoaderScaledTextureDispose
|
||||
&_assetManagerLoaderScaledTextureDispose,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "font.h"
|
||||
|
||||
assetmanageritem_t * assetManagerLoadFont(
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, char *fileName
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, const char fileName[]
|
||||
) {
|
||||
assetmanageritem_t *item;
|
||||
item = assetManagerItemGet(manager, fileName);
|
||||
|
@ -19,7 +19,7 @@
|
||||
* @return A pointer to the asset manager item for tracking.
|
||||
*/
|
||||
assetmanageritem_t * assetManagerLoadFont(
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, char *fileName
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, const char fileName[]
|
||||
);
|
||||
|
||||
bool _assetManagerLoaderFontAsync(assetmanageritem_t *item);
|
||||
|
@ -7,7 +7,9 @@
|
||||
|
||||
#include "item.h"
|
||||
|
||||
assetmanageritem_t * assetManagerItemGet(assetmanager_t *man, char *key) {
|
||||
assetmanageritem_t * assetManagerItemGet(
|
||||
assetmanager_t *man, const char key[]
|
||||
) {
|
||||
uint8_t i;
|
||||
assetmanageritem_t *item;
|
||||
|
||||
@ -19,11 +21,13 @@ assetmanageritem_t * assetManagerItemGet(assetmanager_t *man, char *key) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assetmanageritem_t * assetManagerItemAdd(assetmanager_t *manager, char *key) {
|
||||
assetmanageritem_t * assetManagerItemAdd(
|
||||
assetmanager_t *manager, const char key[]
|
||||
) {
|
||||
// Check if key already exists.
|
||||
assetmanageritem_t *item = manager->items + manager->itemCount++;
|
||||
item->state = ASSET_MANAGER_STATE_NOT_READY;
|
||||
memcpy(item->key, key, strlen(key) + 1);
|
||||
item->key = key;
|
||||
item->holderCount = 0x00;
|
||||
return item;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* @param key Key to search for.
|
||||
* @return The matching asset manager item, or NULL if not found.
|
||||
*/
|
||||
assetmanageritem_t * assetManagerItemGet(assetmanager_t *man, char *key);
|
||||
assetmanageritem_t * assetManagerItemGet(assetmanager_t *man, const char key[]);
|
||||
|
||||
/**
|
||||
* Private method, simply adds an item to the manager and resets the state.
|
||||
@ -24,7 +24,9 @@ assetmanageritem_t * assetManagerItemGet(assetmanager_t *man, char *key);
|
||||
* @param key Key to use when adding.
|
||||
* @return The added and reset item.
|
||||
*/
|
||||
assetmanageritem_t * assetManagerItemAdd(assetmanager_t *manager, char *key);
|
||||
assetmanageritem_t * assetManagerItemAdd(
|
||||
assetmanager_t *manager, const char key[]
|
||||
);
|
||||
|
||||
/**
|
||||
* Add or get the index that a given holder has as a manager item.
|
||||
|
@ -8,7 +8,8 @@
|
||||
#include "scaledtexture.h"
|
||||
|
||||
assetmanageritem_t * assetManagerLoadScaledTexture(
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, char *path, char *file
|
||||
assetmanager_t *manager, assetmanagerowner_t owner,
|
||||
const char path[], const char file[]
|
||||
) {
|
||||
assetmanageritem_t *item;
|
||||
texturescale_t *st;
|
||||
|
@ -21,7 +21,8 @@
|
||||
* @return A pointer to the asset manager item for tracking.
|
||||
*/
|
||||
assetmanageritem_t * assetManagerLoadScaledTexture(
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, char *path, char *file
|
||||
assetmanager_t *manager, assetmanagerowner_t owner,
|
||||
const char path[], const char file[]
|
||||
);
|
||||
|
||||
bool _assetManagerLoaderScaledTextureAsync(assetmanageritem_t *item);
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
assetmanageritem_t * assetManagerLoadShader(
|
||||
assetmanager_t *manager, assetmanagerowner_t owner,
|
||||
char *fileVert, char *fileFrag
|
||||
const char fileVert[], const char fileFrag[]
|
||||
) {
|
||||
assetmanageritem_t *item;
|
||||
char buffer[ASSET_MANAGER_ITEM_NAME_MAX];
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
assetmanageritem_t * assetManagerLoadShader(
|
||||
assetmanager_t *manager, assetmanagerowner_t owner,
|
||||
char *fileVert, char *fileFrag
|
||||
const char fileVert[], const char fileFrag[]
|
||||
);
|
||||
|
||||
bool _assetManagerLoaderShaderAsync(assetmanageritem_t *item);
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "texture.h"
|
||||
|
||||
assetmanageritem_t * assetManagerLoadTexture(
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, char *fileName
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, const char fileName[]
|
||||
) {
|
||||
assetmanageritem_t *item;
|
||||
item = assetManagerItemGet(manager, fileName);
|
||||
|
@ -19,7 +19,7 @@
|
||||
* @return A pointer to the asset manager item for tracking.
|
||||
*/
|
||||
assetmanageritem_t * assetManagerLoadTexture(
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, char *fileName
|
||||
assetmanager_t *manager, assetmanagerowner_t owner, const char fileName[]
|
||||
);
|
||||
|
||||
bool _assetManagerLoaderTextureAsync(assetmanageritem_t *item);
|
||||
|
@ -50,7 +50,7 @@ typedef union {
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
uint8_t state;
|
||||
char key[ASSET_MANAGER_ITEM_NAME_MAX];
|
||||
const char *key;
|
||||
assetmanagerassetdata_t data;
|
||||
assetmanagerowner_t holders[ASSET_MANAGER_HOLDERS_MAX];
|
||||
uint8_t holderCount;
|
||||
@ -64,6 +64,7 @@ typedef struct {
|
||||
assetmanagerloader_t *loadAsync;
|
||||
assetmanagerloader_t *loadSync;
|
||||
assetmanagerloader_t *dispose;
|
||||
assetmanagerloader_t *update;
|
||||
} assetmanagerloaderdefinition_t;
|
||||
|
||||
|
||||
|
@ -10,6 +10,6 @@
|
||||
|
||||
typedef struct {
|
||||
font_t font;
|
||||
char *fileName;
|
||||
const char *fileName;
|
||||
char *data;
|
||||
} assetmanagerfont_t;
|
@ -9,8 +9,8 @@
|
||||
|
||||
typedef struct {
|
||||
shaderprogram_t shader;
|
||||
char *fileVert;
|
||||
char *fileFrag;
|
||||
const char *fileVert;
|
||||
const char *fileFrag;
|
||||
char *dataVert;
|
||||
char *dataFrag;
|
||||
} assetmanagershader_t;
|
@ -9,7 +9,7 @@
|
||||
|
||||
typedef struct {
|
||||
texture_t texture;
|
||||
char *fileName;
|
||||
const char *fileName;
|
||||
int32_t width, height;
|
||||
pixel_t *data;
|
||||
} assetmanagertexture_t;
|
@ -7,7 +7,24 @@
|
||||
|
||||
#include "game.h"
|
||||
|
||||
#define EVENT_TEST 0x00
|
||||
|
||||
eventmanager_t eventManager;
|
||||
|
||||
bool onEventTriggered(void *user, event_t event, void *args[], int32_t argc) {
|
||||
printf("Event!\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gameInit(game_t *game) {
|
||||
|
||||
eventManagerInit(&eventManager);
|
||||
eventManagerSubscribe(&eventManager, EVENT_TEST, NULL, onEventTriggered);
|
||||
eventManagerTrigger(&eventManager, EVENT_TEST, NULL, 0);
|
||||
eventManagerTrigger(&eventManager, EVENT_TEST, NULL, 0);
|
||||
printf("Done.\n");
|
||||
|
||||
|
||||
// Init the engine and the rendering pipeline
|
||||
engineInit(&game->engine);
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
#include "../../libs.h"
|
||||
#include "../../engine/engine.h"
|
||||
#include "../../engine/event.h"
|
||||
#include "../../display/primitive/primitive.h"
|
||||
#include "../../display/primitive/quad.h"
|
||||
#include "../../display/primitive/cube.h"
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
// Windows Fixes
|
||||
|
16
src/libs.hpp
16
src/libs.hpp
@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "libs.h"
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
@ -8,17 +8,31 @@
|
||||
#include "array.h"
|
||||
|
||||
void * arrayGet(size_t size, void *array, int32_t index) {
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_NOT_NULL(array);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(index, 0);
|
||||
|
||||
return (char *)array + (index * (size/sizeof(char)));
|
||||
}
|
||||
|
||||
void arraySet(size_t size, void *array, int32_t index, void *data) {
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_NOT_NULL(array);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(index, 0);
|
||||
|
||||
memcpy(arrayGet(size, array, index), data, size);
|
||||
}
|
||||
|
||||
void arrayShuffle(size_t size, void *array, int32_t arrayLength) {
|
||||
int32_t x, y;
|
||||
void *itemDest, *itemSource;
|
||||
void *temporary = malloc(size);
|
||||
void *itemDest, *itemSource, *temporary;
|
||||
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_NOT_NULL(array);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(arrayLength, 0);
|
||||
|
||||
temporary = malloc(size);
|
||||
ASSERT_NOT_NULL(temporary);
|
||||
|
||||
for(x = 0; x < arrayLength-1; x++) {
|
||||
// Select random element from remaining elements.
|
||||
@ -45,6 +59,11 @@ int32_t arrayFind(size_t size, void *array, int32_t length, void *value) {
|
||||
int32_t i;
|
||||
void *item;
|
||||
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(length, 0);
|
||||
ASSERT_NOT_NULL(array);
|
||||
ASSERT_NOT_NULL(value);
|
||||
|
||||
for(i = 0; i < length; i++) {
|
||||
// Get the item and compare.
|
||||
item = arrayGet(size, array, i);
|
||||
@ -55,16 +74,44 @@ int32_t arrayFind(size_t size, void *array, int32_t length, void *value) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t arrayFindCallback(
|
||||
size_t size, void *array, int32_t length, arrayiterationcallback_t *callback
|
||||
) {
|
||||
int32_t i;
|
||||
void *item;
|
||||
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_GREATER_THAN(length, 0);
|
||||
ASSERT_NOT_NULL(array);
|
||||
ASSERT_NOT_NULL(callback);
|
||||
|
||||
for(i = 0; i < length; i++) {
|
||||
item = arrayGet(size, array, i);
|
||||
if(callback(i, item)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool arrayContains(size_t size, void *array, int32_t length, void *value) {
|
||||
int32_t i = arrayFind(size, array, length, value);
|
||||
return i != -1;
|
||||
}
|
||||
|
||||
void arrayCopy(size_t size, void *source, int32_t length, void *dest) {
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_NOT_NULL(source);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(length, 0);
|
||||
ASSERT_NOT_NULL(dest);
|
||||
|
||||
memcpy(dest, source, size * length);
|
||||
}
|
||||
|
||||
void arraySort(size_t size, void *array, int32_t length, arraysort_t *sort) {
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_NOT_NULL(array);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(length, 0);
|
||||
ASSERT_NOT_NULL(sort);
|
||||
|
||||
qsort(array, length, size, sort);
|
||||
}
|
||||
|
||||
@ -86,7 +133,13 @@ int32_t _arraySorterUint8(const void* left, const void* right) {
|
||||
|
||||
int32_t arrayFindString(char **array, int32_t arrayLength, char *value) {
|
||||
int32_t i;
|
||||
|
||||
ASSERT_NOT_NULL(array);
|
||||
ASSERT_NOT_NULL(value);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(arrayLength, 0);
|
||||
|
||||
for(i = 0; i < arrayLength; i++) {
|
||||
ASSERT_NOT_NULL(array[i]);
|
||||
if(strcmp(array[i], value) == 0) return i;
|
||||
}
|
||||
return -1;
|
||||
@ -95,10 +148,19 @@ int32_t arrayFindString(char **array, int32_t arrayLength, char *value) {
|
||||
void arrayRewind(size_t size, void *source, int32_t length, int32_t start,
|
||||
int32_t count
|
||||
) {
|
||||
void *temporary;
|
||||
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_NOT_NULL(source);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(length, 0);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(start, 0);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(count, -1);
|
||||
|
||||
if(count == -1) count = length - start;
|
||||
|
||||
// Create a temporary new array to house the data.
|
||||
void *temporary = malloc(size * count);
|
||||
temporary = malloc(size * count);
|
||||
ASSERT_NOT_NULL(temporary);
|
||||
|
||||
// Copy the data from the source to the temporary array.
|
||||
arrayCopy(size, arrayGet(size, source, start), count, temporary);
|
||||
@ -113,11 +175,22 @@ void arrayRewind(size_t size, void *source, int32_t length, int32_t start,
|
||||
void arraySplice(
|
||||
size_t size, void *array, int32_t start, int32_t count, int32_t length
|
||||
) {
|
||||
// Take the end of the array...
|
||||
int32_t takeStart = start + count;
|
||||
int32_t takeLength = length - takeStart;
|
||||
int32_t takeStart, takeLength;
|
||||
void *temporary;
|
||||
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_NOT_NULL(array);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(start, 0);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(count, 0);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(length, 0);
|
||||
|
||||
// Take the end of the array...
|
||||
takeStart = start + count;
|
||||
takeLength = length - takeStart;
|
||||
|
||||
temporary = malloc(size * takeLength);
|
||||
ASSERT_NOT_NULL(temporary);
|
||||
|
||||
void *temporary = malloc(size * takeLength);
|
||||
arrayCopy(size, arrayGet(size, array, takeStart), takeLength, temporary);
|
||||
|
||||
// Now copy it back into the original array
|
||||
@ -127,12 +200,18 @@ void arraySplice(
|
||||
|
||||
|
||||
int32_t arraySum(
|
||||
size_t size, void *array, int32_t length, arraysumcallback_t *callback
|
||||
size_t size, void *array, int32_t length, arrayiterationcallback_t *callback
|
||||
) {
|
||||
int32_t i, count;
|
||||
|
||||
ASSERT_GREATER_THAN(size, 0);
|
||||
ASSERT_NOT_NULL(array);
|
||||
ASSERT_GREATER_THAN_EQUAL_TO(length, 0);
|
||||
ASSERT_NOT_NULL(callback);
|
||||
|
||||
count = 0;
|
||||
for(i = 0; i < length; i++) {
|
||||
if(!callback(arrayGet(size, array, i))) continue;
|
||||
if(!callback(i, arrayGet(size, array, i))) continue;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "../assert/assert.h"
|
||||
#include "rand.h"
|
||||
|
||||
/**
|
||||
@ -25,6 +26,15 @@ typedef int32_t arraysort_t(const void*, const void*);
|
||||
*/
|
||||
typedef bool arraysumcallback_t(void*);
|
||||
|
||||
/**
|
||||
* Generic array iteration callback.
|
||||
*
|
||||
* @param i Index of the item within the array.
|
||||
* @param itm Item at that index.
|
||||
* @return Depending on the usage of the iteration callback.
|
||||
*/
|
||||
typedef bool arrayiterationcallback_t(int32_t i, void *itm);
|
||||
|
||||
/**
|
||||
* Retreive the pointer to an elment within the array of unknown type.
|
||||
*
|
||||
@ -66,6 +76,20 @@ void arrayShuffle(size_t size, void *array, int32_t arrayLength);
|
||||
*/
|
||||
int32_t arrayFind(size_t size, void *array, int32_t length, void *value);
|
||||
|
||||
/**
|
||||
* Find the first index within the array that matches the result of the callback
|
||||
* when the callback returns true.
|
||||
*
|
||||
* @param size Size of each element within the array.
|
||||
* @param array Array to search.
|
||||
* @param length Length of the array to search.
|
||||
* @param callback Callback to use when performing lookup.
|
||||
* @return The first index that matches, or -1 if no match is found.
|
||||
*/
|
||||
int32_t arrayFindCallback(
|
||||
size_t size, void *array, int32_t length, arrayiterationcallback_t *callback
|
||||
);
|
||||
|
||||
/**
|
||||
* Compares each item in an array with the specified value, and returns true if
|
||||
* found within the array. This is a shorthand for arrayFind without an int32_t
|
||||
@ -169,5 +193,5 @@ void arraySplice(
|
||||
* @return The count of items that matched the callback invokation.
|
||||
*/
|
||||
int32_t arraySum(
|
||||
size_t size, void *array, int32_t length, arraysumcallback_t *callback
|
||||
size_t size, void *array, int32_t length, arrayiterationcallback_t *callback
|
||||
);
|
Reference in New Issue
Block a user