- events tested and implemented multithreading support through mpscq

This commit is contained in:
2025-12-23 12:24:23 -05:00
parent 1f6637408d
commit 184bc7fcdf
12 changed files with 281 additions and 31 deletions

View File

@@ -39,6 +39,11 @@ public:
/// \brief event handler callback
/// \param event the event to handle
virtual void handle_event(event* event) = 0;
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE() {
}
#endif
};
///
@@ -46,36 +51,38 @@ public:
struct event {
virtual ~event() = default;
static void handle_events();
///
/// \brief Registers a listener for the event type
/// \tparam EventT the event type
/// \param listener the listener to register
template<typename EventT>
static void add_listener(event_listener* listener) {
event::add_listener(listener, typeuuid<EventT, event>());
event::_add_listener(listener, type::get<EventT>().id());
}
///
/// \brief Add a listener for an event type of \f$type\f$
/// \param listener the listener to add
/// \param type the event type to listen for
static void add_listener(event_listener* listener, uint64_t type);
///
/// \brief removes a listener from the event system
/// \param listener the listener to remove
static void remove_listener(event_listener* listener);
template<typename EventT, typename...ArgsT>
static void dispatch_immediate(ArgsT&&...args) {
static void dispatch(ArgsT&&...args) {
event::_dispatch(fennec::make_unique<EventT>(fennec::forward<ArgsT>(args)...));
}
template<typename EventT, typename...ArgsT>
static void dispatch_next_tick(ArgsT&&...args) {
static void dispatch_immediate(ArgsT&&...args) {
event::_dispatch_immediate(fennec::make_unique<EventT>(fennec::forward<ArgsT>(args)...));
}
private:
static void _add_listener(event_listener* listener, uint64_t type);
static void _handle_event(unique_ptr<event>& event);
static void _dispatch(unique_ptr<event>&& event);
static void _dispatch_immediate(unique_ptr<event>&& event);
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE() {
}

View File

@@ -31,6 +31,8 @@
#ifndef FENNEC_LANG_ASSERT_H
#define FENNEC_LANG_ASSERT_H
#include <fennec/lang/types.h>
///
/// \page fennec_lang_assert Assertions
///
@@ -69,7 +71,19 @@
#endif
#ifndef FENNEC_DOXYGEN
void _assert_impl(const char* expression, const char* file, int line, const char* function, const char* desc, bool halt);
void _assert_impl(const char* expr, size_t expr_l,
const char* file, size_t file_l, int line,
const char* func, size_t func_l,
const char* desc, bool halt);
template<size_t ExprL, size_t FileL, size_t FuncL>
void _assert(const char (&expr)[ExprL],
const char (&file)[FileL], int line,
const char (&func)[FuncL],
const char* desc,
bool halt) {
::_assert_impl(expr, ExprL, file, FileL, line, func, FuncL, desc, halt);
}
#endif
///
@@ -78,7 +92,7 @@ void _assert_impl(const char* expression, const char* file, int line, const char
/// \param description the description of the assertion
#define assert(expression, description) \
if(not(expression)) [[unlikely]] { \
_assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, not FENNEC_RELEASE); \
_assert(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, not FENNEC_RELEASE); \
}
///
@@ -87,7 +101,7 @@ void _assert_impl(const char* expression, const char* file, int line, const char
/// \param description the description of the assertion
#define assertf(expression, description) \
if(not(expression)) [[unlikely]] { \
_assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, true); \
_assert(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, true); \
}
///

View File

@@ -117,13 +117,20 @@ public:
}
///
/// \brief Move Constructor, transfers ownership from \f$other\f$
/// \param other The unique_ptr to take ownership from
constexpr unique_ptr(unique_ptr&& other)
: _handle(other._handle) {
other._handle = nullptr;
}
///
/// \brief Move Constructor, transfers ownership from \f$other\f$
/// \param other The unique_ptr to take ownership from
template<typename DerivedT> requires(is_base_of_v<TypeT, DerivedT>)
constexpr unique_ptr(unique_ptr<DerivedT>&& other)
: _handle(other.release()) {
}
// Delete copy constructor
constexpr unique_ptr(const unique_ptr&) = delete;
@@ -225,6 +232,11 @@ unique_ptr<TypeT> make_unique(ArgsT&&...args) {
return unique_ptr<TypeT>(new TypeT(fennec::forward<ArgsT>(args)...));
}
template<typename TypeT>
unique_ptr<TypeT> make_unique(TypeT* ptr) {
return unique_ptr<TypeT>(ptr);
}
}
#endif // FENNEC_MEMORY_POINTERS_H

View File

@@ -81,9 +81,10 @@ public:
}
///
/// \brief Buffer Constructor, wraps the provided C-Style string
/// \param str the buffer to wrap
/// \param n the number of characters in the buffer plus the null terminator
///
/// \note If used with `::strlen`, the result should be incremented by 1 to include the null terminator
constexpr cstring(char* str, size_t n)
: _str(str)
, _size(n - 1)
@@ -94,7 +95,6 @@ public:
}
///
/// \brief Buffer Constructor, wraps the provided C-Style string
/// \param str the buffer to wrap
/// \tparam n the number of characters in the buffer plus the null terminator
template<size_t n>
@@ -108,9 +108,10 @@ public:
}
///
/// \brief Const Buffer Constructor, wraps the provided C-Style string
/// \param str the buffer to wrap
/// \param n the number of characters in the buffer plus the null terminator
///
/// \note If used with `::strlen`, the result should be incremented by 1 to include the null terminator
constexpr cstring(const char* str, size_t n)
: _cstr(str)
, _size(n - 1)