SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
Delegate.hpp
Go to the documentation of this file.
1#ifndef _DELEGATE_H_
2#define _DELEGATE_H_
3
4#include <functional>
5#include <vector>
6#include <memory>
7#include <tuple>
8#include <utility>
9
10#include <random>
11#include <sstream>
13
14namespace Sleak {
15 /// Type-erased callable interface storable in a homogeneous handler list.
16 /// @ingroup events
17 class IDelegate {
18 public:
19 virtual ~IDelegate() = default;
20 virtual void Execute() = 0;
21 virtual std::string GetID() = 0;
22 };
23
24 // Standard delegate for non-event parameters
25 /// Callable wrapper that stashes its arguments via SetArgs and invokes them later via Execute.
26 /// @ingroup events
27 template<typename... Args>
28 class Delegate : public IDelegate {
29 public:
30 using FunctionType = std::function<void(Args...)>;
31
32 Delegate(FunctionType func) : function(func) {}
33
34 void SetArgs(Args... args) {
35 // Use perfect forwarding to handle the arguments
36 storedArgs = std::forward_as_tuple(args...);
37 }
38
39 void Execute() override {
40 if (function) {
41 std::apply(function, storedArgs);
42 }
43 }
44
45 std::string GetID() override { return ""; };
46
47 private:
48 FunctionType function;
49 std::tuple<Args...> storedArgs; // Store by reference using forward_as_tuple
50 };
51
52 // Specialized delegate for Event types
53 /// Common base for EventDelegate<T> instantiations, so they can share a handler list.
54 /// @ingroup events
56 public:
57 virtual ~EventDelegateBase() = default;
58 virtual std::string GetID() = 0;
59 };
60
61 /// Delegate bound to a single EventT callback; holds a non-owning pointer
62 /// to the event set just before Execute() runs.
63 /// @ingroup events
64 template<typename EventT>
66 public:
67 using FunctionType = std::function<void(const EventT&)>;
68
69 EventDelegate(FunctionType func) : function(func) {
70 GenerateID();
71 }
72
73 void SetEvent(const EventT& event) {
74 eventPtr = &event;
75 }
76
77 void Execute() override {
78 if (function && eventPtr) {
79 function(*eventPtr);
80 }
81 }
82
83 /// Assigns a fresh random 32-character ID, used to identify this delegate for unregistration.
84 std::string GenerateID() {
85 uuid = "";
86 std::string str =
87 "0123456789!^#%&=*?+-_/"
88 "[]{}()"
89 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
90 std::random_device dev;
91 std::mt19937 rand(dev());
92 std::uniform_int_distribution<> dist(0,str.size() - 1);
93
94 for(int i = 0; i < 32; i++)
95 uuid += str[dist(rand)];
96
97 return uuid;
98 }
99
100 std::string GetID() override { return uuid; }
101
102 private:
103 FunctionType function;
104 const EventT* eventPtr = nullptr; // Store a pointer to avoid copying
105 std::string uuid;
106 };
107
108 /// Fan-out list of Delegate<Args...> instances, all invoked together via Broadcast.
109 /// @ingroup events
110 template<typename... Args>
112 public:
113 void AddDelegate(std::shared_ptr<IDelegate> delegate) {
114 delegates.push_back(delegate);
115 }
116
117 /// Sets args on and executes every registered delegate that matches Args.
118 void Broadcast(Args... args) {
119 for (auto& delegate : delegates) {
120 auto typedDelegate = std::dynamic_pointer_cast<Delegate<Args...>>(delegate);
121 if (typedDelegate) {
122 typedDelegate->SetArgs(std::forward<Args>(args)...);
123 typedDelegate->Execute();
124 }
125 }
126 }
127
128 private:
129 std::vector<std::shared_ptr<IDelegate>> delegates;
130 };
131
132 // Helper function for member functions
133 /// Wraps a member function bound to obj into a shared Delegate.
134 template<typename T, typename... Args>
135 std::shared_ptr<Delegate<Args...>> CreateDelegate(T* obj, void (T::*func)(Args...)) {
136 return std::make_shared<Delegate<Args...>>([obj, func](Args... args) {
137 (obj->*func)(std::forward<Args>(args)...);
138 });
139 }
140 };
141
142#endif // _DELEGATE_H_
std::function< void(Args...)> FunctionType
Definition Delegate.hpp:30
void Execute() override
Definition Delegate.hpp:39
std::string GetID() override
Definition Delegate.hpp:45
void SetArgs(Args... args)
Definition Delegate.hpp:34
Delegate(FunctionType func)
Definition Delegate.hpp:32
virtual ~EventDelegateBase()=default
virtual std::string GetID()=0
std::string GenerateID()
Assigns a fresh random 32-character ID, used to identify this delegate for unregistration.
Definition Delegate.hpp:84
void SetEvent(const EventT &event)
Definition Delegate.hpp:73
std::function< void(const EventT &)> FunctionType
Definition Delegate.hpp:67
EventDelegate(FunctionType func)
Definition Delegate.hpp:69
std::string GetID() override
Definition Delegate.hpp:100
void Execute() override
Definition Delegate.hpp:77
virtual ~IDelegate()=default
virtual void Execute()=0
virtual std::string GetID()=0
void AddDelegate(std::shared_ptr< IDelegate > delegate)
Definition Delegate.hpp:113
void Broadcast(Args... args)
Sets args on and executes every registered delegate that matches Args.
Definition Delegate.hpp:118
Root namespace for everything the engine exposes.
Definition Camera.hpp:10
std::shared_ptr< Delegate< Args... > > CreateDelegate(T *obj, void(T::*func)(Args...))
Wraps a member function bound to obj into a shared Delegate.
Definition Delegate.hpp:135