Skip to content

Commit

Permalink
Added event with test.
Browse files Browse the repository at this point in the history
  • Loading branch information
Chukobyte committed Mar 24, 2024
1 parent 14eca20 commit 6f0fe23
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 43 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ endif ()

add_library(${PROJECT_NAME} STATIC
seika/seika.c
seika/event.c
seika/file_system.c
seika/logger.c
seika/platform.c
Expand Down
4 changes: 2 additions & 2 deletions seika/ecs/ec_system.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ void ska_ecs_system_event_entity_end(SkaEntity entity) {
// NodeComponent* nodeComponent = (NodeComponent*)ska_ecs_component_manager_get_component_unchecked(entity, CreComponentDataIndex_NODE);
// if (nodeComponent != NULL) {
// // Note: Node events should not be created during this time
// ska_event_notify_observers(&nodeComponent->onSceneTreeExit, &(SESubjectNotifyPayload) {
// ska_event_notify_observers(&nodeComponent->onSceneTreeExit, &(SkaSubjectNotifyPayload) {
// .data = &entity
// });
// }
Expand All @@ -219,7 +219,7 @@ void ska_ecs_system_event_entity_entered_scene(SkaEntity entity) {
// Notify scene enter observers before calling it on systems
// NodeComponent* nodeComponent = (NodeComponent*) ska_ecs_component_manager_get_component_unchecked(entity, CreComponentDataIndex_NODE);
// if (nodeComponent != NULL) {
// ska_event_notify_observers(&nodeComponent->onSceneTreeEnter, &(SESubjectNotifyPayload) {
// ska_event_notify_observers(&nodeComponent->onSceneTreeEnter, &(SkaSubjectNotifyPayload) {
// .data = &entity
// });
// }
Expand Down
47 changes: 47 additions & 0 deletions seika/event.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "event.h"

#include "seika/memory.h"
#include "seika/assert.h"
#include "seika/data_structures/array_utils.h"

//--- Observer ---//
SkaObserver* ska_observer_new(SkaObserverOnNotify onNotifyFunc) {
SKA_ASSERT(onNotifyFunc != NULL);
SkaObserver* observer = SKA_MEM_ALLOCATE(SkaObserver);
observer->on_notify = onNotifyFunc;
return observer;
}

void ska_observer_delete(SkaObserver* observer) {
SKA_MEM_FREE(observer);
}

//--- Event ---//
SkaEvent* ska_event_new() {
SkaEvent* event = SKA_MEM_ALLOCATE(SkaEvent);
event->observerCount = 0;
return event;
}

void ska_event_delete(SkaEvent* event) {
SKA_MEM_FREE(event);
}

bool ska_event_register_observer(SkaEvent* event, SkaObserver* observer) {
SKA_ASSERT(event != NULL);
SKA_ASSERT(observer != NULL);
SKA_ASSERT_FMT(event->observerCount + 1 < SKA_MAX_OBSERVERS, "Reached max observer count, consider increasing 'SKA_MAX_OBSERVERS'!");
event->observers[event->observerCount++] = observer;
return true;
}

bool ska_event_unregister_observer(SkaEvent* event, SkaObserver* observer) {
SKA_ARRAY_UTILS_REMOVE_ARRAY_ITEM(event->observers, event->observerCount, observer, NULL);
return true;
}

void ska_event_notify_observers(SkaEvent* event, SkaSubjectNotifyPayload* payload) {
for (size_t i = 0; i < event->observerCount; i++) {
event->observers[i]->on_notify(payload);
}
}
32 changes: 32 additions & 0 deletions seika/event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include <stddef.h>
#include <stdbool.h>

#define SKA_MAX_OBSERVERS 8

typedef struct SkaSubjectNotifyPayload {
void* data; // Primary data, be sure to cast properly
} SkaSubjectNotifyPayload;

typedef void (*SkaObserverOnNotify)(SkaSubjectNotifyPayload*);

// An observer that can subscribe to a subject
typedef struct SkaObserver {
SkaObserverOnNotify on_notify;
} SkaObserver;

SkaObserver* ska_observer_new(SkaObserverOnNotify onNotifyFunc);
void ska_observer_delete(SkaObserver* observer);

// A subscribable event
typedef struct SkaEvent {
size_t observerCount;
SkaObserver* observers[SKA_MAX_OBSERVERS];
} SkaEvent;

SkaEvent* ska_event_new();
void ska_event_delete(SkaEvent* event);
bool ska_event_register_observer(SkaEvent* event, SkaObserver* observer);
bool ska_event_unregister_observer(SkaEvent* event, SkaObserver* observer);
void ska_event_notify_observers(SkaEvent* event, SkaSubjectNotifyPayload* payload);
83 changes: 42 additions & 41 deletions test/test.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <unity.h>

#include "seika/memory.h"
#include "seika/event.h"
#include "seika/input/input.h"
#include "seika/data_structures/hash_map.h"
#include "seika/data_structures/spatial_hash_map.h"
Expand Down Expand Up @@ -38,7 +39,7 @@ int32 main(int32 argv, char** args) {
RUN_TEST(seika_linked_list_test);
RUN_TEST(seika_array2d_test);
RUN_TEST(seika_asset_file_loader_test);
// RUN_TEST(seika_observer_test);
RUN_TEST(seika_observer_test);
RUN_TEST(seika_curve_float_test);
// RUN_TEST(seika_shader_instance_test);
// RUN_TEST(seika_shader_file_parser_test);
Expand Down Expand Up @@ -338,46 +339,46 @@ void seika_asset_file_loader_test(void) {
ska_asset_file_loader_finalize();
}

//// Observer Test
//static bool hasObserved = false;
//
//void observer_func1(SESubjectNotifyPayload* payload) {
// hasObserved = true;
//}
//
//void observer_func2(SESubjectNotifyPayload* payload) {
// const int dataValue = *(int*) payload->data;
// if (dataValue == 3) {
// hasObserved = true;
// }
//}
//
//void seika_observer_test(void) {
// SEEvent* event = se_event_new();
// // Test 1 - Simple test with passing a NULL payload
// SEObserver* observer = se_observer_new(observer_func1);
// se_event_register_observer(event, observer);
// TEST_ASSERT_EQUAL_INT(1, event->observerCount);
// se_event_notify_observers(event, NULL);
// TEST_ASSERT(hasObserved);
// se_event_unregister_observer(event, observer);
// TEST_ASSERT_EQUAL_INT(0, event->observerCount);
// hasObserved = false;
//
// // Test 2 - A slightly more complicated example filling out the payload
// se_observer_delete(observer);
// observer = se_observer_new(observer_func2);
// se_event_register_observer(event, observer);
// int dataValue = 3;
// se_event_notify_observers(event, &(SESubjectNotifyPayload) {
// .data = &dataValue
// });
// TEST_ASSERT(hasObserved);
//
// // Clean up
// se_event_delete(event);
// se_observer_delete(observer);
//}
// Observer Test
static bool hasObserved = false;

void observer_func1(SkaSubjectNotifyPayload* payload) {
hasObserved = true;
}

void observer_func2(SkaSubjectNotifyPayload* payload) {
const int dataValue = *(int*) payload->data;
if (dataValue == 3) {
hasObserved = true;
}
}

void seika_observer_test(void) {
SkaEvent* event = ska_event_new();
// Test 1 - Simple test with passing a NULL payload
SkaObserver* observer = ska_observer_new(observer_func1);
ska_event_register_observer(event, observer);
TEST_ASSERT_EQUAL_INT(1, event->observerCount);
ska_event_notify_observers(event, NULL);
TEST_ASSERT(hasObserved);
ska_event_unregister_observer(event, observer);
TEST_ASSERT_EQUAL_INT(0, event->observerCount);
hasObserved = false;

// Test 2 - A slightly more complicated example filling out the payload
ska_observer_delete(observer);
observer = ska_observer_new(observer_func2);
ska_event_register_observer(event, observer);
int dataValue = 3;
ska_event_notify_observers(event, &(SkaSubjectNotifyPayload) {
.data = &dataValue
});
TEST_ASSERT(hasObserved);

// Clean up
ska_event_delete(event);
ska_observer_delete(observer);
}

void seika_curve_float_test(void) {
SkaCurveFloat curve = { .controlPointCount = 0 };
Expand Down

0 comments on commit 6f0fe23

Please sign in to comment.