diff --git a/CMakeLists.txt b/CMakeLists.txt index db6b628..c88f33d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,16 +14,14 @@ if (WIN32) set(CMAKE_CXX_FLAGS "-municode") endif() + file(GLOB_RECURSE SOURCES "src/*.cpp") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -include_directories("include") +include_directories(${PROJECT_SOURCE_DIR}/include) -add_library(Event SHARED ${SOURCES} - src/Event.cpp - include/EventConnection.h - src/EventConnection.cpp) +add_library(Event SHARED ${SOURCES}) set_target_properties(Event PROPERTIES LINKER_LANGUAGE CXX) diff --git a/include/Event.h b/include/Event.h index 86355a5..01b521e 100644 --- a/include/Event.h +++ b/include/Event.h @@ -1,5 +1,5 @@ -/// @file Event.hpp -/// @description Templated Event Hook Class modeled after C# events +/// @file BasicEvent.hpp +/// @description Templated BasicEvent Hook Class modeled after C# events /// @author Josh O'Leary - Redacted Software /// @revision 3 /// @lastedit 2024-02-21 @@ -10,18 +10,21 @@ #include #include -// TODO: Document & Explain this +// TODO: ThreadSafeEvent / AsyncEvent version of the class. +// TODO: ConsumableEvent - a version that can be "consumed" by a callback by returning true. It will be sunk and not passed to further callbacks. -#include +/// +template +class Connection; -template -class EventConnection; - -template -class Event { +/// BasicEvent is a templated class that can be used to raise events that can be listened in on +/// at other points in a codebase without having to tightly couple the two pieces of code. +/// @param delegate A type that can be invoked via operator() 'Call operator'. +/// @param Args... The arguments that will be expected by this event and passed to it's delegate. +template +class BasicEvent { public: - using delegate = std::function; - using connection = EventConnection; + using connection = Connection; using event_ptr = std::shared_ptr; public: void Await(Args& ... arg); @@ -35,28 +38,32 @@ private: uint64_t listenerCounter = 0; }; -template -EventConnection Event::operator+=(Event::delegate callback) { return Connect(callback); } +template +Connection BasicEvent::operator+=(delegate callback) { return Connect(callback); } -template -void Event::operator()(Args... args) { Invoke(args...);} +template +void BasicEvent::operator()(Args... args) { Invoke(args...);} -template -void Event::Invoke(Args... args) { +template +void BasicEvent::Invoke(Args... args) { for (event_ptr &connection_ptr: this->listeners) { connection_ptr->Invoke(args...); } } -template -EventConnection Event::Connect(delegate callback) +template +Connection BasicEvent::Connect(delegate callback) { event_ptr retval(new connection(this, callback)); this->listeners.push_back(retval); return *retval; } -template -void Event::Disconnect(connection &conn) { +template +void BasicEvent::Disconnect(connection &conn) { listeners.erase(std::remove(listeners.begin(), listeners.end(), 99), listeners.end()); -} \ No newline at end of file +} + +template +using Event = BasicEvent, Args...>; + diff --git a/include/EventConnection.h b/include/EventConnection.h index 195d22c..5c74acf 100644 --- a/include/EventConnection.h +++ b/include/EventConnection.h @@ -1,4 +1,4 @@ -/// @file EventConnection.hpp +/// @file Connection.hpp /// @description Callback handler for event connections /// @author Josh O'Leary - Redacted Software /// @revision 3 @@ -10,32 +10,32 @@ #include #include -template -class Event; +template +class BasicEvent; -template -class EventConnection { +/// A type that represents a handle to an active event connection. +template +class Connection { private: - using delegate = std::function; public: - EventConnection(Event *creator, delegate cb); + Connection(BasicEvent *creator, delegate cb); bool Disconnect(); // Breaks the event connection, but does not destroy the instance void Invoke(Args... e); private: - Event * owner; + BasicEvent * owner; delegate callback; bool active = true; }; -template -EventConnection::EventConnection(Event *creator, EventConnection::delegate cb) : owner(creator), callback(std::move(cb)) {} +template +Connection::Connection(BasicEvent *creator, delegate cb) : owner(creator), callback(std::move(cb)) {} -template -void EventConnection::Invoke(Args... e) { callback(e...); } +template +void Connection::Invoke(Args... e) { callback(e...); } -template -bool EventConnection::Disconnect() { +template +bool Connection::Disconnect() { if (active) { owner->Disconnect(this); active = false; diff --git a/main.cpp b/main.cpp index a85b2ea..7759f01 100644 --- a/main.cpp +++ b/main.cpp @@ -1,15 +1,25 @@ #include - +#include #include +#include void ProcessMessage(const std::string& message) { std::cout << "Received: " << message << std::endl; } +// TODO: Event tests here. + int main() { - Event OnMessage; + Event cum; + + cum += [] (int i) { std::cout << i+5 << std::endl; }; + + cum.Invoke(69); + + BasicEvent, std::string> OnMessage; + BasicEvent> VoidDelegate; bool run = true; @@ -24,7 +34,11 @@ int main() { std::string input; std::cin >> input; OnMessage.Invoke(input); + VoidDelegate.Invoke(); + OnMessage(input); + VoidDelegate(); } + return 0; } diff --git a/src/Event.cpp b/src/Event.cpp index b070ff3..e2ce964 100644 --- a/src/Event.cpp +++ b/src/Event.cpp @@ -1 +1,3 @@ -#include \ No newline at end of file +#include + +