16 template<
class return_t,
class function_t>
21 virtual return_t invoke(
const function_t&
function) noexcept = 0;
24 template<
class return_t,
class function_t,
class invoke_function_t>
28 invoker(
const invoke_function_t& invoke) noexcept : m_InvokeFunction(invoke)
33 virtual return_t invoke(
const function_t&
function) noexcept
override
35 return m_InvokeFunction(
function);
39 const invoke_function_t& m_InvokeFunction;
44 template<
class derived_t, delegate_return_c return_t,
class... args_t>
47 std::swap(m_Functions, other.m_Functions);
48 std::swap(m_pDelegateAliveMarker, other.m_pDelegateAliveMarker);
51 template<
class derived_t, delegate_return_c return_t,
class... args_t>
52 typename base_delegate<derived_t, return_t, args_t...>::base_delegate& base_delegate<derived_t, return_t, args_t...>::
53 operator=(base_delegate&& other) noexcept
55 std::swap(m_Functions, other.m_Functions);
56 std::swap(m_pDelegateAliveMarker, other.m_pDelegateAliveMarker);
60 template<
class derived_t, delegate_return_c return_t,
class... args_t>
61 template<
class... creation_args_t>
65 if constexpr (requires(derived_t d) { d.add_weak(args...); })
67 if constexpr (requires(derived_t d) { d.add_free(args...); })
70 QX_STATIC_ASSERT_NO_INSTANTIATION(
"No overload that takes these args");
75 template<
class derived_t, delegate_return_c return_t,
class... args_t>
76 template<callable_c<return_t, args_t...> callable_t>
82 m_Functions.emplace(key, std::move(callable));
86 template<
class derived_t, delegate_return_c return_t,
class... args_t>
87 template<callable_c<return_t, args_t...> callable_t>
95 template<
class derived_t, delegate_return_c return_t,
class... args_t>
96 template<
class object_t>
99 return_t (object_t::*pMethod)(args_t...),
104 [&
object, pMethod](args_t... args)
106 return (object.*pMethod)(std::forward<args_t>(args)...);
110 template<
class derived_t, delegate_return_c return_t,
class... args_t>
111 template<
class object_t>
113 std::weak_ptr<object_t> pWeakObject,
114 return_t (object_t::*pMethod)(args_t...),
120 std::move(pWeakObject),
121 [pMethod](object_t* pObject, args_t... args)
123 return (pObject->*pMethod)(std::forward<args_t>(args)...);
128 template<
class derived_t, delegate_return_c return_t,
class... args_t>
129 template<
class object_t, callable_c<return_t, args_t...> callable_t>
131 std::weak_ptr<object_t> pWeakObject,
138 std::move(pWeakObject),
139 [callable_ = std::move(callable)](object_t*, args_t... args)
141 return callable_(std::forward<args_t>(args)...);
146 template<
class derived_t, delegate_return_c return_t,
class... args_t>
149 return m_Functions.erase(token) == 1;
152 template<
class derived_t, delegate_return_c return_t,
class... args_t>
158 template<
class derived_t, delegate_return_c return_t,
class... args_t>
159 template<
class invoke_single_t,
class invoke_multiple_t>
161 const invoke_single_t& invokeSingle,
162 const invoke_multiple_t& invokeMultiple)
const noexcept
164 if (m_Functions.empty())
166 if constexpr (std::is_void_v<return_t>)
173 thread_local container_type tempFunctions;
174 tempFunctions = m_Functions;
179 if (tempFunctions.size() == 1)
180 invoker = &invokerSingle;
182 invoker = &invokerMultiple;
184 if constexpr (std::is_void_v<return_t>)
186 for (
const auto& [_,
function] : tempFunctions)
187 invoker->invoke(
function);
194 for (
const auto& [_,
function] : tempFunctions)
195 result = result | invoker->invoke(
function);
201 template<
class derived_t, delegate_return_c return_t,
class... args_t>
202 template<
class object_t, callable_c<return_t, object_t*, args_t...> callable_t>
204 time_ordered_priority_key key,
205 std::weak_ptr<object_t> pWeakObject,
206 callable_t callable) noexcept
210 [
this, key, pWeakObject, callable_ = std::move(callable)](args_t... args)
212 if (std::shared_ptr<object_t> pObject = pWeakObject.lock())
214 return callable_(pObject.get(), std::forward<args_t>(args)...);
224 template<
class derived_t, delegate_return_c return_t,
class... args_t>
225 destruction_callback base_delegate<derived_t, return_t, args_t...>::add_destruction_callback(
226 time_ordered_priority_key key,
227 function_type value) noexcept
229 m_Functions.emplace(key, std::move(value));
230 return [
this, key, pDelegateAliveMarker = std::weak_ptr(m_pDelegateAliveMarker)]()
232 if (!pDelegateAliveMarker.expired())
237 template<delegate_return_c return_t,
class... args_t>
238 requires(
sizeof...(args_t) > 0 && (!std::is_void_v<args_t> && ...))
239 return_t delegate<return_t, args_t...>::execute(args_t... args) const noexcept
241 return this->execute_internal(
242 [&args...](
const typename super_type::function_type&
function)
244 return function(std::move(args)...);
246 [&args...](
const typename super_type::function_type&
function)
248 return function(args...);
252 template<delegate_return_c return_t>
255 return this->execute_internal(
256 [](
const typename super_type::function_type&
function)
260 [](
const typename super_type::function_type&
function)
Single or multicast delegate. Use the qx::delegate<> class in your code.
bool remove(delegate_token_type token) noexcept
Remove a callable using its token.
return_t execute_internal(const invoke_single_t &invokeSingle, const invoke_multiple_t &invokeMultiple) const noexcept
Execute all callables.
static derived_t create_singlecast(creation_args_t... args) noexcept
Create a singlecast delegate.
destruction_callback add_destruction_callback(callable_t callable, priority ePriority=priority::normal) noexcept
Add a callable that will be removed from the delegate when its destruction callback is destroyed.
void clear() noexcept
Clear all the callables in this delegate.
delegate_token_type add_weak(std::weak_ptr< object_t > pWeakObject, callable_t callable, priority ePriority=priority::normal) noexcept
Add a callable that will be executed only if the appropriate weak object is valid.
delegate_token_type add_free(callable_t callable, priority ePriority=priority::normal) noexcept
Add a callable without any protection.
Class for RAII: functor passed in constructor will be called in destructor.
priority
User may use the predefined values or the custom ones, for ex. "normal - 1", this type is supposed to...
A structure that can be used as a key in ordered containers so that items are ordered in descending o...