Implement event handler
Added event handler implementation. Moved enginge specific implementation outside graphics module Signed-off-by: Piotr Krygier <piotrkrygier@everyonecancode@xyz>
This commit is contained in:
+2
-1
@@ -1,4 +1,5 @@
|
||||
rse_events_sources = [
|
||||
'src/events_manager.c'
|
||||
]
|
||||
|
||||
sdl3_dep = dependency('sdl3',
|
||||
@@ -10,7 +11,7 @@ rse_events_lib = shared_library(
|
||||
include_directories : [
|
||||
'../'
|
||||
],
|
||||
dependencies : [
|
||||
dependencies : [sdl3_dep,
|
||||
],
|
||||
link_with: rse_utilities_lib,
|
||||
install : true
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @file events_manager.h
|
||||
* @author Piotr Krygier (piotrkrygier@everyonencancode.xyz)
|
||||
* @brief Events manager for Red Scarf Engine
|
||||
* @version 0.1
|
||||
* @date 2026-03-02
|
||||
*
|
||||
* @copyright Copyright (c) 2026
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RSE_EVENTS_MANAGER_H_
|
||||
#define RSE_EVENTS_MANAGER_H_
|
||||
|
||||
#include "src/events_context.h"
|
||||
#include "utilities/commons.h"
|
||||
|
||||
rse_err_t rse_events_init(struct events_context_t* events_context);
|
||||
|
||||
rse_err_t rse_events_set_event_handler(struct events_context_t* events_context,
|
||||
enum EVENT_HANDLER event_type,
|
||||
rse_event_handler_t event_handler);
|
||||
|
||||
rse_err_t rse_events_main_loop(struct events_context_t* context);
|
||||
|
||||
#endif /* RSE_EVENTS_MANAGER_H_ */
|
||||
@@ -15,6 +15,17 @@
|
||||
#include "SDL3/SDL_mouse.h"
|
||||
#include "utilities/commons.h"
|
||||
|
||||
enum EVENT_HANDLER {
|
||||
EVENT_HANDLER_QUIT,
|
||||
EVENT_HANDLER_MOUSE,
|
||||
EVENT_HANDLER_LAST
|
||||
};
|
||||
|
||||
enum EVENT_SHOULD_STOP_ENGINE {
|
||||
EVENT_SHOULD_STOP_ENGINE_FALSE,
|
||||
EVENT_SHOULD_STOP_ENGINE_TRUE
|
||||
};
|
||||
|
||||
struct mouse_event_data_t
|
||||
{
|
||||
float x_pos;
|
||||
@@ -24,14 +35,10 @@ struct mouse_event_data_t
|
||||
|
||||
typedef rse_err_t (*rse_event_handler_t)(void*);
|
||||
|
||||
struct event_handlers
|
||||
struct events_context_t
|
||||
{
|
||||
rse_event_handler_t mouse_event;
|
||||
};
|
||||
|
||||
struct events_context
|
||||
{
|
||||
struct event_handlers event_handlers;
|
||||
enum EVENT_SHOULD_STOP_ENGINE should_stop;
|
||||
rse_event_handler_t event_handlers[EVENT_HANDLER_LAST];
|
||||
};
|
||||
|
||||
#endif /* EVENT_CONTEXT_H_ */
|
||||
|
||||
+36
-18
@@ -9,11 +9,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "events_manager.h"
|
||||
|
||||
#include "SDL3/SDL_events.h"
|
||||
#include "SDL3/SDL_log.h"
|
||||
#include "SDL3/SDL_mouse.h"
|
||||
#include "events_context.h"
|
||||
#include "rse_events_manager.h"
|
||||
#include "utilities/commons.h"
|
||||
#include "utilities/errors_common.h"
|
||||
|
||||
@@ -24,44 +24,62 @@ static rse_err_t default_event(void* args)
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
static rse_err_t quit_event(void)
|
||||
static rse_err_t run_custom_event_handler(struct events_context_t* context,
|
||||
enum EVENT_HANDLER event_handler,
|
||||
void* args)
|
||||
{
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
return context->event_handlers[event_handler](args);
|
||||
}
|
||||
|
||||
static rse_err_t mouse_event(struct events_context* events_context)
|
||||
static rse_err_t quit_event(struct events_context_t* context)
|
||||
{
|
||||
context->should_stop = EVENT_SHOULD_STOP_ENGINE_TRUE;
|
||||
|
||||
return run_custom_event_handler(context, EVENT_HANDLER_QUIT, NULL);
|
||||
}
|
||||
|
||||
static rse_err_t mouse_event(struct events_context_t* context)
|
||||
{
|
||||
struct mouse_event_data_t mouse_data = {0};
|
||||
|
||||
mouse_data.mouse_buttons = SDL_GetMouseState(&mouse_data.x_pos, &mouse_data.y_pos);
|
||||
|
||||
return events_context->event_handlers.mouse_event((void*)&mouse_data);
|
||||
return run_custom_event_handler(context, EVENT_HANDLER_MOUSE, (void*)&mouse_data);
|
||||
}
|
||||
|
||||
rse_err_t events_init(struct events_context* events_context)
|
||||
rse_err_t rse_events_init(struct events_context_t* events_context)
|
||||
{
|
||||
events_context->event_handlers.mouse_event = default_event;
|
||||
size_t i = 0U;
|
||||
|
||||
for (i = 0U; i < EVENT_HANDLER_LAST; ++i) {
|
||||
events_context->event_handlers[i] = default_event;
|
||||
}
|
||||
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
rse_err_t events_set_event_handler(struct events_context* events_context,
|
||||
enum RSE_EVENT_TYPE event_type,
|
||||
rse_err_t rse_events_set_event_handler(struct events_context_t* events_context,
|
||||
enum EVENT_HANDLER event_type,
|
||||
rse_event_handler_t event_handler)
|
||||
{
|
||||
switch (event_type) {
|
||||
case RSE_EVENT_TYPE_MOUSE:
|
||||
events_context->event_handlers.mouse_event = event_handler;
|
||||
break;
|
||||
default:
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Invalid event type provided");
|
||||
if (event_type >= EVENT_HANDLER_LAST) {
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Invalid event type selected");
|
||||
|
||||
return RSE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (event_handler == NULL) {
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Provided NULL event handler");
|
||||
|
||||
return RSE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
events_context->event_handlers[event_type] = event_handler;
|
||||
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
rse_err_t events_run(struct events_context* context)
|
||||
rse_err_t rse_events_main_loop(struct events_context_t* context)
|
||||
{
|
||||
SDL_Event event;
|
||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||
@@ -69,7 +87,7 @@ rse_err_t events_run(struct events_context* context)
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
STATUS_CHECK(quit_event());
|
||||
STATUS_CHECK(quit_event(context));
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
STATUS_CHECK(mouse_event(context));
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* @file events_manager.h
|
||||
* @author Piotr Krygier (piotrkrygier@everyonencancode.xyz)
|
||||
* @brief Events manager for Red Scarf Engine
|
||||
* @version 0.1
|
||||
* @date 2026-03-02
|
||||
*
|
||||
* @copyright Copyright (c) 2026
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EVENTS_MANAGER_H_
|
||||
#define EVENTS_MANAGER_H_
|
||||
|
||||
enum RSE_EVENT_TYPE {
|
||||
RSE_EVENT_TYPE_MOUSE,
|
||||
};
|
||||
|
||||
|
||||
#endif /* EVENTS_MANAGER_H_ */
|
||||
@@ -9,7 +9,6 @@ rse_graphics_sources = [
|
||||
'src/vulkan_base.c',
|
||||
'src/vulkan_buffers.c',
|
||||
'src/vulkan_commands.c',
|
||||
'src/vulkan_commons.c',
|
||||
'src/vulkan_image.c',
|
||||
'src/vulkan_render_pass.c',
|
||||
'src/vulkan_swapchain.c',
|
||||
|
||||
@@ -18,13 +18,17 @@ rse_err_t rse_graphics_init(struct graphics_context_t* context);
|
||||
*
|
||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success
|
||||
*/
|
||||
rse_err_t rse_graphics_main_loop(struct graphics_context_t* context);
|
||||
rse_err_t rse_graphics_run(struct graphics_context_t* context);
|
||||
|
||||
|
||||
rse_err_t rse_graphics_main_loop(struct graphics_context_t* context);
|
||||
|
||||
/**
|
||||
* @brief Custom function for testing engine. TODO: Remove it whe releasing
|
||||
*
|
||||
*/
|
||||
rse_err_t rse_graphics_test_function(struct graphics_context_t* context);
|
||||
|
||||
void rse_graphics_deinit(struct graphics_context_t* context);
|
||||
|
||||
#endif /* RSE_GRAPHICS_H */
|
||||
|
||||
@@ -245,17 +245,28 @@ rse_err_t rse_graphics_test_function(struct graphics_context_t* context)
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
rse_err_t rse_graphics_main_loop(struct graphics_context_t* context)
|
||||
rse_err_t rse_graphics_run(struct graphics_context_t* context)
|
||||
{
|
||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||
|
||||
STATUS_CHECK(vulkan_run(context));
|
||||
STATUS_CHECK(window_loop(context));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
rse_err_t rse_graphics_main_loop(struct graphics_context_t* context)
|
||||
{
|
||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||
|
||||
STATUS_CHECK(vulkan_draw_frame(context));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void rse_graphics_deinit(struct graphics_context_t* context)
|
||||
{
|
||||
vulkan_deinit(context);
|
||||
|
||||
window_terminate(context->window_handle);
|
||||
rse_free(context->debug_overlay.pixels);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -559,12 +559,10 @@ rse_err_t vulkan_run(struct graphics_context_t* context)
|
||||
|
||||
STATUS_CHECK(create_sync_objects(context));
|
||||
|
||||
init_time();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
rse_err_t draw_frame(struct graphics_context_t* context)
|
||||
rse_err_t vulkan_draw_frame(struct graphics_context_t* context)
|
||||
{
|
||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||
uint32_t image_index = 0U;
|
||||
@@ -580,8 +578,6 @@ rse_err_t draw_frame(struct graphics_context_t* context)
|
||||
|
||||
STATUS_CHECK(buffers_update(context));
|
||||
|
||||
update_time();
|
||||
|
||||
result = vkAcquireNextImageKHR(context->vulkan_handles.device, context->swapchain_data.swapchain, UINT64_MAX, context->vulkan_handles.image_available_semaphores[context->current_frame],
|
||||
VK_NULL_HANDLE, &image_index);
|
||||
|
||||
@@ -649,6 +645,7 @@ rse_err_t draw_frame(struct graphics_context_t* context)
|
||||
|
||||
void vulkan_deinit(struct graphics_context_t* context)
|
||||
{
|
||||
vkDeviceWaitIdle(context->vulkan_handles.device);
|
||||
destroy_buffers(context);
|
||||
for (size_t i = 0; i < SWAP_BUFFER_COUNT; ++i) {
|
||||
vkDestroySemaphore(context->vulkan_handles.device, context->vulkan_handles.image_available_semaphores[i], NULL);
|
||||
|
||||
@@ -46,6 +46,6 @@ void vulkan_deinit(struct graphics_context_t* context);
|
||||
* @param context Graphics context
|
||||
* @return rse_err_t
|
||||
*/
|
||||
rse_err_t draw_frame(struct graphics_context_t* context);
|
||||
rse_err_t vulkan_draw_frame(struct graphics_context_t* context);
|
||||
|
||||
#endif /* GRAPHICS_VULKANBASE_H */
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#include "vulkan_commons.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
time_t g_last_frame_time;
|
||||
time_t g_this_frame_time;
|
||||
float g_float_delta_time;
|
||||
|
||||
void init_time(void)
|
||||
{
|
||||
time(&g_last_frame_time);
|
||||
}
|
||||
|
||||
void update_time(void)
|
||||
{
|
||||
g_last_frame_time = g_this_frame_time;
|
||||
time(&g_this_frame_time);
|
||||
g_float_delta_time = (float)difftime(g_this_frame_time, g_last_frame_time);
|
||||
}
|
||||
|
||||
float get_time_diff(void)
|
||||
{
|
||||
return g_float_delta_time;
|
||||
}
|
||||
@@ -58,8 +58,4 @@ struct instance_data_t {
|
||||
alignas(4) uint32_t texture_id;
|
||||
};
|
||||
|
||||
void init_time(void);
|
||||
void update_time(void);
|
||||
float get_time_diff(void);
|
||||
|
||||
#endif /* VULKAN_GLOBAL_H */
|
||||
|
||||
@@ -21,29 +21,9 @@
|
||||
#include "SDL3/SDL_log.h"
|
||||
#include "utilities/commons.h"
|
||||
#include "utilities/errors_common.h"
|
||||
#include "utilities/time_utils.h"
|
||||
#include "vulkan/vulkan_core.h"
|
||||
#include "vulkan_base.h"
|
||||
|
||||
static void fps_print(double* start_time)
|
||||
{
|
||||
static uint32_t frame_counts = 0U;
|
||||
|
||||
double now = time_get_sec_from_start();
|
||||
|
||||
frame_counts++;
|
||||
if ((now - *start_time) > 1.0) {
|
||||
printf("\rFPS: %u", frame_counts);
|
||||
fflush(stdout);
|
||||
frame_counts = 0;
|
||||
*start_time += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
rse_err_t window_init(SDL_Window** window_handle, bool* is_framebuffer_resized)
|
||||
{
|
||||
SDL_Init(SDL_INIT_VIDEO); // TODO: Move to initial phase of RSE initialization
|
||||
|
||||
(void)is_framebuffer_resized;
|
||||
// TODO: Actually use this parameter?
|
||||
|
||||
@@ -57,34 +37,6 @@ rse_err_t window_init(SDL_Window** window_handle, bool* is_framebuffer_resized)
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
rse_err_t window_loop(struct graphics_context_t* context)
|
||||
{
|
||||
uint8_t done = 0;
|
||||
SDL_Event event;
|
||||
double start_time;
|
||||
|
||||
start_time = time_get_sec_from_start();
|
||||
|
||||
while (0 == done) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
done = 1;
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
time_update();
|
||||
draw_frame(context);
|
||||
fps_print(&start_time);
|
||||
}
|
||||
|
||||
vkDeviceWaitIdle(context->vulkan_handles.device);
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
void window_terminate(SDL_Window* window_handle)
|
||||
{
|
||||
SDL_DestroyWindow(window_handle);
|
||||
|
||||
@@ -32,14 +32,6 @@
|
||||
*/
|
||||
rse_err_t window_init(SDL_Window **window_handle, bool *is_framebuffer_resized);
|
||||
|
||||
/**
|
||||
* @brief Main window loop
|
||||
*
|
||||
* @param context Graphics context
|
||||
* @return rse_err_t WINDOW_SUCCESS or error code
|
||||
*/
|
||||
rse_err_t window_loop(struct graphics_context_t* context);
|
||||
|
||||
/**
|
||||
* @brief Closes window and terminates GLFW
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@ executable(
|
||||
],
|
||||
link_with: [
|
||||
rse_graphics_lib,
|
||||
rse_events_lib,
|
||||
rse_utilities_lib,
|
||||
],
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#define RED_SCARF_ENGINE_H_
|
||||
|
||||
#include "utilities/commons.h"
|
||||
#include "utilities/errors_common.h"
|
||||
|
||||
typedef struct rse_context_t* rse_context;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "red_scarf_engine.h"
|
||||
#include "utilities/errors_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
#include "red_scarf_engine.h"
|
||||
#include "graphics/rse_graphics.h"
|
||||
#include "graphics/src/graphics_context.h"
|
||||
#include "utilities/commons.h"
|
||||
#include "utilities/errors_common.h"
|
||||
#include "utilities/time_utils.h"
|
||||
#include "events/rse_events_manager.h"
|
||||
|
||||
struct rse_context_t {
|
||||
struct graphics_context_t graphics_context;
|
||||
struct events_context_t events_context;
|
||||
};
|
||||
|
||||
static void fps_print(double* start_time)
|
||||
{
|
||||
static uint32_t frame_counts = 0U;
|
||||
|
||||
double now = time_get_sec_from_start();
|
||||
|
||||
frame_counts++;
|
||||
if ((now - *start_time) > 1.0) {
|
||||
printf("\rFPS: %u", frame_counts);
|
||||
fflush(stdout);
|
||||
frame_counts = 0;
|
||||
*start_time += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
rse_err_t rse_init(rse_context* context)
|
||||
{
|
||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||
@@ -18,10 +34,12 @@ rse_err_t rse_init(rse_context* context)
|
||||
|
||||
rse_context = *context;
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE);
|
||||
|
||||
STATUS_CHECK(time_init());
|
||||
rse_graphics_init(&(rse_context->graphics_context));
|
||||
STATUS_CHECK(rse_events_init(&rse_context->events_context));
|
||||
STATUS_CHECK(rse_graphics_init(&rse_context->graphics_context));
|
||||
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
}
|
||||
@@ -29,11 +47,24 @@ rse_err_t rse_init(rse_context* context)
|
||||
rse_err_t rse_run(rse_context context)
|
||||
{
|
||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||
double start_time;
|
||||
|
||||
start_time = time_get_sec_from_start();
|
||||
|
||||
STATUS_CHECK(rse_graphics_test_function(&context->graphics_context));
|
||||
|
||||
STATUS_CHECK(rse_graphics_main_loop(&context->graphics_context));
|
||||
STATUS_CHECK(rse_graphics_run(&context->graphics_context));
|
||||
while(true) {
|
||||
time_update();
|
||||
rse_events_main_loop(&context->events_context);
|
||||
if (context->events_context.should_stop == EVENT_SHOULD_STOP_ENGINE_TRUE) {
|
||||
break;
|
||||
}
|
||||
rse_graphics_main_loop(&context->graphics_context);
|
||||
fps_print(&start_time);
|
||||
}
|
||||
|
||||
rse_graphics_deinit(&context->graphics_context);
|
||||
rse_free(context);
|
||||
|
||||
return status;
|
||||
|
||||
Reference in New Issue
Block a user