Event
This commit is contained in:
@@ -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
10
src/event/CMakeLists.txt
Normal 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
106
src/event/event.c
Normal 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
79
src/event/event.h
Normal 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);
|
||||
29
src/script/module/moduletime.h
Normal file
29
src/script/module/moduletime.h
Normal 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);
|
||||
}
|
||||
@@ -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 ( \
|
||||
|
||||
Reference in New Issue
Block a user