Event
Some checks failed
Build Dusk / run-tests (push) Failing after 1m44s
Build Dusk / build-linux (push) Successful in 1m50s
Build Dusk / build-psp (push) Failing after 1m53s

This commit is contained in:
2026-01-27 10:41:32 -06:00
parent c7b9a53535
commit 9b73f1717f
6 changed files with 227 additions and 0 deletions

View File

@@ -55,6 +55,7 @@ add_subdirectory(debug)
add_subdirectory(display)
add_subdirectory(engine)
add_subdirectory(error)
add_subdirectory(event)
add_subdirectory(input)
add_subdirectory(item)
add_subdirectory(locale)

10
src/event/CMakeLists.txt Normal file
View File

@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
event.c
)

106
src/event/event.c Normal file
View File

@@ -0,0 +1,106 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "event.h"
#include "assert/assert.h"
#include "util/memory.h"
void eventInit(
event_t *event,
eventlistener_t *array,
const uint16_t maxListeners
) {
assertNotNull(event, "Event cannot be NULL");
assertNotNull(array, "Listener array cannot be NULL");
assertTrue(maxListeners > 0, "Max listeners must be greater than 0");
memoryZero(event, sizeof(event_t));
event->listenerArray = array;
event->maxListeners = maxListeners;
}
eventsub_t eventSubscribe(
event_t *event,
const eventcallback_t callback,
const void *user
) {
assertNotNull(event, "Event cannot be NULL");
assertNotNull(callback, "Callback cannot be NULL");
assertTrue(
event->listenerCount < event->maxListeners,
"Maximum number of listeners reached"
);
// Gen a new ID
eventsub_t id = event->nextId++;
// Did we wrap?
assertTrue(event->nextId != 0, "Event subscription ID overflow");
// Append listener
eventlistener_t *listener = &event->listenerArray[event->listenerCount++];
memoryZero(listener, sizeof(eventlistener_t));
listener->callback = callback;
listener->user = (void*)user;
listener->id = id;
return id;
}
void eventUnsubscribe(event_t *event, const eventsub_t id) {
assertNotNull(event, "Event cannot be NULL");
assertFalse(event->isInvoking, "Cannot unsubscribe while invoking event");
if(event->listenerCount == 0) return;
// Find listener
uint16_t index = 0;
do {
if(event->listenerArray[index].id == id) {
// Found it, remove by swapping with last and reducing count
event->listenerArray[index] = event->listenerArray[--event->listenerCount];
return;
}
index++;
} while(index < event->listenerCount);
// Did we find it?
if(index == event->listenerCount) return;
// Shift remaining listeners down (if any)
if(index < event->listenerCount - 1) {
memoryMove(
&event->listenerArray[index],
&event->listenerArray[index + 1],
sizeof(eventlistener_t) * (event->listenerCount - index - 1)
);
}
event->listenerCount--;
}
void eventInvoke(event_t *event, const void *eventParams) {
assertNotNull(event, "Event cannot be NULL");
if(event->listenerCount == 0) return;
event->isInvoking = true;
uint16_t i = 0;
eventdata_t data ={
.event = event,
.eventParams = eventParams,
};
do {
data.user = event->listenerArray[i].user;
event->listenerArray[i].callback(&data);
i++;
} while(i < event->listenerCount);
event->isInvoking = false;
}

79
src/event/event.h Normal file
View File

@@ -0,0 +1,79 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct event_s event_t;
typedef struct {
void *user;
const void *eventParams;
const event_t *event;
} eventdata_t;
typedef void (*eventcallback_t)(eventdata_t *data);
typedef struct {
eventcallback_t callback;
void *user;
uint16_t id;
} eventlistener_t;
typedef uint16_t eventsub_t;
typedef struct event_s {
eventlistener_t *listenerArray;
uint16_t listenerCount;
uint16_t maxListeners;
eventsub_t nextId;
bool_t isInvoking;
} event_t;
/**
* Initialize an event structure.
*
* @param event The event to initialize.
* @param array The array to hold event listeners.
* @param maxListeners The maximum number of listeners.
*/
void eventInit(
event_t *event,
eventlistener_t *array,
const uint16_t maxListeners
);
/**
* Subscribe to an event.
*
* @param event The event to subscribe to.
* @param callback The callback function to invoke.
* @param user User data to pass to the callback.
* @return The subscription ID, used to unsubscribe later.
*/
eventsub_t eventSubscribe(
event_t *event,
const eventcallback_t callback,
const void *user
);
/**
* Unsubscribe from an event.
*
* @param event The event to unsubscribe from.
* @param subscription The subscription ID to remove.
*/
void eventUnsubscribe(event_t *event, const eventsub_t subscription);
/**
* Invoke an event, calling all subscribed listeners.
*
* @param event The event to invoke.
* @param eventParams Parameters to pass to the event listeners.
*/
void eventInvoke(event_t *event, const void *eventParams);

View File

@@ -0,0 +1,29 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/scriptcontext.h"
#include "time/time.h"
int moduleTimeGetDelta(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
lua_pushnumber(L, TIME.delta);
return 1;
}
int moduleTimeGetTime(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
lua_pushnumber(L, TIME.time);
return 1;
}
void moduleTime(scriptcontext_t *ctx) {
assertNotNull(ctx, "Script context cannot be NULL");
scriptContextRegFunc(ctx, "timeGetDelta", moduleTimeGetDelta);
scriptContextRegFunc(ctx, "timeGetTime", moduleTimeGetTime);
}

View File

@@ -12,6 +12,7 @@
#include "script/module/modulescene.h"
#include "script/module/moduleitem.h"
#include "script/module/modulelocale.h"
#include "script/module/moduletime.h"
const scriptmodule_t SCRIPT_MODULE_LIST[] = {
{ .name = "system", .callback = moduleSystem },
@@ -20,6 +21,7 @@ const scriptmodule_t SCRIPT_MODULE_LIST[] = {
{ .name = "scene", .callback = moduleScene },
{ .name = "item", .callback = moduleItem },
{ .name = "locale", .callback = moduleLocale },
{ .name = "time", .callback = moduleTime },
};
#define SCRIPT_MODULE_COUNT ( \