Nebula
Loading...
Searching...
No Matches
delegate.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
32#include "core/types.h"
33
34//------------------------------------------------------------------------------
35namespace Util
36{
37
38template<typename T>
39class Delegate; // This is soooo dirty.
40
41//------------------------------------------------------------------------------
45template<typename RETTYPE, typename ... ARGTYPES>
46class Delegate<RETTYPE(ARGTYPES...)>
47{
48public:
52 Delegate(Delegate<RETTYPE(ARGTYPES...)> const& rhs);
54 Delegate(Delegate<RETTYPE(ARGTYPES...)>&& rhs);
56 template <typename LAMBDA>
57 Delegate(LAMBDA const& lambda);
58
60 void operator=(Delegate<RETTYPE(ARGTYPES...)> const& rhs);
62 void operator=(Delegate<RETTYPE(ARGTYPES...)>&& rhs);
64 bool operator==(std::nullptr_t);
66 bool operator!();
67
69 template <typename LAMBDA>
70 Delegate<RETTYPE(ARGTYPES ...)>& operator=(LAMBDA const& instance);
71
73 RETTYPE operator()(ARGTYPES ... args) const;
74
76 template<class CLASS, RETTYPE (CLASS::*METHOD)(ARGTYPES ...)> static Delegate<RETTYPE(ARGTYPES ...)> FromMethod(CLASS* objPtr);
78 template<RETTYPE(*FUNCTION)(ARGTYPES ...)> static Delegate<RETTYPE(ARGTYPES ...)> FromFunction();
80 template <typename LAMBDA> static Delegate<RETTYPE(ARGTYPES ...)> FromLambda(const LAMBDA & instance);
81
83 template<class CLASS> const CLASS* GetObject() const;
84
86 bool IsValid();
87
88private:
90 using StubType = RETTYPE(*)(void*, ARGTYPES...);
91
93 template<class CLASS, RETTYPE(CLASS::*METHOD)(ARGTYPES ...)> static RETTYPE MethodStub(void* objPtr, ARGTYPES ... args);
95 template<RETTYPE(*FUNCTION)(ARGTYPES ... )> static RETTYPE FunctionStub(void* dummyPtr, ARGTYPES ... args);
97 template <typename LAMBDA> static RETTYPE LambdaStub(void* objPtr, ARGTYPES... arg);
98
100 void Assign(void* obj, typename Delegate<RETTYPE(ARGTYPES...)>::StubType stub);
101
102 void* objPtr;
104};
105
106//------------------------------------------------------------------------------
109template<typename RETTYPE, typename ... ARGTYPES>
110Delegate<RETTYPE(ARGTYPES ...)>::Delegate() :
111 objPtr(nullptr),
112 stubPtr(nullptr)
113{
114 // empty
115}
116
117//------------------------------------------------------------------------------
120template<typename RETTYPE, typename ... ARGTYPES>
121Delegate<RETTYPE(ARGTYPES ...)>::Delegate(Delegate<RETTYPE(ARGTYPES...)> const& rhs) :
122 objPtr(rhs.objPtr),
123 stubPtr(rhs.stubPtr)
124{
125
126}
127
128//------------------------------------------------------------------------------
131template<typename RETTYPE, typename ... ARGTYPES>
132Delegate<RETTYPE(ARGTYPES ...)>::Delegate(Delegate<RETTYPE(ARGTYPES...)>&& rhs) :
133 objPtr(rhs.objPtr),
134 stubPtr(rhs.stubPtr)
135{
136 rhs.objPtr = nullptr;
137 rhs.stubPtr = nullptr;
138}
139
140//------------------------------------------------------------------------------
143template<typename RETTYPE, typename ... ARGTYPES>
144template <typename LAMBDA>
145Delegate<RETTYPE(ARGTYPES...)>::Delegate(LAMBDA const& lambda)
146{
147 static_assert(sizeof(LAMBDA) == 1ULL, "Util::Delegate does accept lambdas carrying capture variables! Read the description of at the top of util/delegate.h");
148 Assign((void*)(&lambda), LambdaStub<LAMBDA>);
149}
150
151//------------------------------------------------------------------------------
154template<typename RETTYPE, typename ... ARGTYPES>
155void
156Delegate<RETTYPE(ARGTYPES...)>::operator=(Delegate<RETTYPE(ARGTYPES...)> const& rhs)
157{
158 if (this != &rhs)
159 {
160 this->objPtr = rhs.objPtr;
161 this->stubPtr = rhs.stubPtr;
162 }
163}
164
165//------------------------------------------------------------------------------
168template<typename RETTYPE, typename ... ARGTYPES>
169void
170Delegate<RETTYPE(ARGTYPES...)>::operator=(Delegate<RETTYPE(ARGTYPES...)>&& rhs)
171{
172 if (this != &rhs)
173 {
174 this->objPtr = rhs.objPtr;
175 this->stubPtr = rhs.stubPtr;
176 rhs.objPtr = nullptr;
177 rhs.stubPtr = nullptr;
178 }
179}
180
181//------------------------------------------------------------------------------
184template<typename RETTYPE, typename ... ARGTYPES>
185template <typename LAMBDA>
186Delegate<RETTYPE(ARGTYPES...)>&
187Delegate<RETTYPE(ARGTYPES...)>::operator=(LAMBDA const& instance)
188{
189 static_assert(sizeof(LAMBDA) == 1ULL, "Util::Delegate does accept lambdas carrying capture variables! Read the description of at the top of util/delegate.h");
190 Assign((void*)(&instance), LambdaStub<LAMBDA>);
191 return *this;
192}
193
194//------------------------------------------------------------------------------
197template<typename RETTYPE, typename ... ARGTYPES>
198bool
199Delegate<RETTYPE(ARGTYPES...)>::operator==(std::nullptr_t)
200{
201 return this->stubPtr == nullptr;
202}
203
204//------------------------------------------------------------------------------
207template<typename RETTYPE, typename ... ARGTYPES>
208bool
209Delegate<RETTYPE(ARGTYPES...)>::operator!()
210{
211 return this->stubPtr == nullptr;
212}
213
214//------------------------------------------------------------------------------
217template<typename RETTYPE, typename ... ARGTYPES> RETTYPE
218Delegate<RETTYPE(ARGTYPES...)>::operator()(ARGTYPES ... args) const
219{
220 return (*this->stubPtr)(this->objPtr, args...);
221}
222
223//------------------------------------------------------------------------------
226template<typename RETTYPE, typename ... ARGTYPES>
227template<class CLASS, RETTYPE (CLASS::*METHOD)(ARGTYPES ...)>
228Delegate<RETTYPE(ARGTYPES...)>
229Delegate<RETTYPE(ARGTYPES...)>::FromMethod(CLASS* objPtr_)
230{
231 Delegate<RETTYPE(ARGTYPES...)> del;
232 del.objPtr = objPtr_;
233 del.stubPtr = &MethodStub<CLASS,METHOD>;
234 return del;
235}
236
237//------------------------------------------------------------------------------
240template<typename RETTYPE, typename ... ARGTYPES>
241template<RETTYPE(*FUNCTION)(ARGTYPES ...)>
242Delegate<RETTYPE(ARGTYPES...)>
243Delegate<RETTYPE(ARGTYPES...)>::FromFunction()
244{
245 Delegate<RETTYPE(ARGTYPES...)> del;
246 del.objPtr = 0;
247 del.stubPtr = &FunctionStub<FUNCTION>;
248 return del;
249}
250
251//------------------------------------------------------------------------------
254template<typename RETTYPE, typename ... ARGTYPES>
255template<typename LAMBDA>
256Delegate<RETTYPE(ARGTYPES...)>
257Delegate<RETTYPE(ARGTYPES...)>::FromLambda(const LAMBDA & instance)
258{
259 static_assert(sizeof(LAMBDA) == 1ULL, "Util::Delegate does accept lambdas carrying capture variables! Read the description of at the top of util/delegate.h");
260 return ((void*)(&instance), LambdaStub<LAMBDA>);
261}
262
263//------------------------------------------------------------------------------
266template<typename RETTYPE, typename ... ARGTYPES>
267template<class CLASS, RETTYPE (CLASS::*METHOD)(ARGTYPES ...)>
268RETTYPE
269Delegate<RETTYPE(ARGTYPES...)>::MethodStub(void* objPtr_, ARGTYPES ... arg_)
270{
271 CLASS* obj = static_cast<CLASS*>(objPtr_);
272 return (obj->*METHOD)(arg_...);
273}
274
275//------------------------------------------------------------------------------
278template<typename RETTYPE, typename ... ARGTYPES>
279template<RETTYPE(*FUNCTION)(ARGTYPES ...)>
280RETTYPE
281Delegate<RETTYPE(ARGTYPES...)>::FunctionStub(void* dummyPtr, ARGTYPES ... arg_)
282{
283 return (*FUNCTION)(arg_...);
284}
285
286//------------------------------------------------------------------------------
289template<typename RETTYPE, typename ... ARGTYPES>
290template<typename LAMBDA>
291RETTYPE
292Delegate<RETTYPE(ARGTYPES...)>::LambdaStub(void* objPtr, ARGTYPES ... arg_)
293{
294 LAMBDA* p = static_cast<LAMBDA*>(objPtr);
295 return (p->operator())(arg_...);
296}
297
298//------------------------------------------------------------------------------
301template<typename RETTYPE, typename ... ARGTYPES>
302template<class CLASS>
303inline const CLASS*
304Delegate<RETTYPE(ARGTYPES...)>::GetObject() const
305{
306 return (CLASS*)this->objPtr;
307}
308
309//------------------------------------------------------------------------------
312template<typename RETTYPE, typename ... ARGTYPES>
313bool
314Util::Delegate<RETTYPE(ARGTYPES...)>::IsValid()
315{
316 return (0 != this->stubPtr);
317}
318
319//------------------------------------------------------------------------------
322template<typename RETTYPE, typename ... ARGTYPES>
323void
324Delegate<RETTYPE(ARGTYPES...)>::Assign(void* obj, typename Delegate<RETTYPE(ARGTYPES...)>::StubType stub)
325{
326 this->objPtr = obj;
327 this->stubPtr = stub;
328}
329
330} // namespace Util
331//------------------------------------------------------------------------------
bool IsValid()
returns true if delegate is valid
static Delegate< RETTYPE(ARGTYPES ...)> FromMethod(CLASS *objPtr)
setup a new delegate from a method call
static RETTYPE MethodStub(void *objPtr, ARGTYPES ... args)
static method-call stub
void operator=(Delegate< RETTYPE(ARGTYPES...)> &&rhs)
move operator
RETTYPE operator()(ARGTYPES ... args) const
invokation operator
Delegate(Delegate< RETTYPE(ARGTYPES...)> &&rhs)
move constructor
static Delegate< RETTYPE(ARGTYPES ...)> FromFunction()
setup a new delegate from a function call
Delegate(Delegate< RETTYPE(ARGTYPES...)> const &rhs)
copy constructor
const CLASS * GetObject() const
get object pointer
Delegate(LAMBDA const &lambda)
lambda constructor
Delegate< RETTYPE(ARGTYPES ...)> & operator=(LAMBDA const &instance)
lambda assignment operator
static Delegate< RETTYPE(ARGTYPES ...)> FromLambda(const LAMBDA &instance)
setup a new delegate from lambda
void Assign(void *obj, typename Delegate< RETTYPE(ARGTYPES...)>::StubType stub)
assignment method
RETTYPE(*)(void *, ARGTYPES...) StubType
method pointer typedef
Definition delegate.h:90
StubType stubPtr
Definition delegate.h:103
void operator=(Delegate< RETTYPE(ARGTYPES...)> const &rhs)
assignment operator
static RETTYPE LambdaStub(void *objPtr, ARGTYPES... arg)
static lambda-call stub
bool operator==(std::nullptr_t)
check if null
static RETTYPE FunctionStub(void *dummyPtr, ARGTYPES ... args)
static function-call stub
void * objPtr
Definition delegate.h:102
Nebula delegate class, allows to store a function, method or lambda call into a C++ object for later ...
Definition delegate.h:39
A pinned array is an array which manages its own virtual memory.
Definition String.cs:6