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;
42 template<
class derived_t,
class return_t,
class... args_t>
45 std::swap(m_optFunctions, other.m_optFunctions);
46 std::swap(m_pDelegateAliveMarker, other.m_pDelegateAliveMarker);
49 template<
class derived_t,
class return_t,
class... args_t>
50 typename base_delegate<derived_t, return_t, args_t...>::base_delegate& base_delegate<derived_t, return_t, args_t...>::
51 operator=(base_delegate&& other) noexcept
53 std::swap(m_optFunctions, other.m_optFunctions);
54 std::swap(m_pDelegateAliveMarker, other.m_pDelegateAliveMarker);
58 template<
class derived_t,
class return_t,
class... args_t>
59 template<
class... creation_args_t>
63 if constexpr (
requires(derived_t d) { d.add_weak(args...); })
65 if constexpr (
requires(derived_t d) { d.add_token(args...); })
73 template<
class derived_t,
class return_t,
class... args_t>
74 template<callable_c<return_t, args_t...> callable_t>
81 add_function(key, std::move(callable));
85 template<
class derived_t,
class return_t,
class... args_t>
86 template<
class object_t>
89 return_t (object_t::*pMethod)(args_t...),
94 [pMethod, &
object](args_t... args)
96 return (object.*pMethod)(std::forward<args_t>(args)...);
101 template<
class derived_t,
class return_t,
class... args_t>
102 template<callable_c<return_t, args_t...> callable_t>
111 template<
class derived_t,
class return_t,
class... args_t>
112 template<
class object_t>
115 return_t (object_t::*pMethod)(args_t...),
118 return add_destruction_callback(
121 [&
object, pMethod](args_t... args)
123 return (object.*pMethod)(std::forward<args_t>(args)...);
127 template<
class derived_t,
class return_t,
class... args_t>
128 template<
class object_t, callable_c<return_t, args_t...> callable_t>
130 std::weak_ptr<object_t> pWeakObject,
137 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,
class return_t,
class... args_t>
147 template<
class object_t>
149 std::weak_ptr<object_t> pWeakObject,
150 return_t (object_t::*pMethod)(args_t...),
156 std::move(pWeakObject),
158 [pMethod](object_t* pObject, args_t... args)
160 return (pObject->*pMethod)(std::forward<args_t>(args)...);
165 template<
class derived_t,
class return_t,
class... args_t>
168 return m_optFunctions
170 [
this, token]<
class T>(T& value)
172 if constexpr (std::is_same_v<T, single_value_type>)
174 if (value.first == token)
176 m_optFunctions.reset();
184 else if constexpr (std::is_same_v<T, container_type>)
186 return value.erase(token) == 1;
197 template<
class derived_t,
class return_t,
class... args_t>
200 m_optFunctions.reset();
203 template<
class derived_t,
class return_t,
class... args_t>
210 []<
class T>(
const T& value) ->
size_t
212 if constexpr (std::is_same_v<T, single_value_type>)
216 else if constexpr (std::is_same_v<T, container_type>)
229 template<
class derived_t,
class return_t,
class... args_t>
235 template<
class derived_t,
class return_t,
class... args_t>
236 template<
class invoke_single_t,
class invoke_multiple_t>
238 const invoke_single_t& invokeSingle,
239 const invoke_multiple_t& invokeMultiple)
const noexcept
243 if constexpr (std::is_void_v<return_t>)
250 thread_local variant_type tempFunctions;
251 tempFunctions = *m_optFunctions;
253 if (std::holds_alternative<single_value_type>(tempFunctions))
255 const auto& [_,
function] = std::get<single_value_type>(tempFunctions);
256 return invokeSingle(
function);
260 const container_type& container = std::get<container_type>(tempFunctions);
265 if (container.size() == 1)
270 if constexpr (std::is_void_v<return_t>)
272 for (
const auto& [_,
function] : container)
277 else if constexpr (delegate_pipe_c<return_t>)
280 for (
const auto& [_,
function] : container)
281 result = result |
invoker->invoke(
function);
288 for (
const auto& [_,
function] : container)
289 result =
invoker->invoke(
function);
296 template<
class derived_t,
class return_t,
class... args_t>
297 template<
class object_t, callable_c<return_t, object_t*, args_t...> callable_t>
300 std::weak_ptr<object_t> pWeakObject,
301 callable_t callable) noexcept
305 [
this, key, pWeakObject, callable_ = std::move(callable)](args_t... args)
307 if (std::shared_ptr<object_t> pObject = pWeakObject.lock())
309 return callable_(pObject.get(), std::forward<args_t>(args)...);
319 template<
class derived_t,
class return_t,
class... args_t>
320 destruction_callback base_delegate<derived_t, return_t, args_t...>::add_destruction_callback(
321 time_ordered_priority_key key,
322 function_type value) noexcept
324 add_function(key, std::move(value));
326 if (!m_pDelegateAliveMarker)
327 m_pDelegateAliveMarker = std::make_shared<bool>(
true);
329 return [
this, key, pDelegateAliveMarker = std::weak_ptr(m_pDelegateAliveMarker)]()
331 if (!pDelegateAliveMarker.expired())
336 template<
class derived_t,
class return_t,
class... args_t>
337 void base_delegate<derived_t, return_t, args_t...>::add_function(
338 time_ordered_priority_key key,
339 function_type
function) noexcept
343 m_optFunctions = variant_type(single_value_type(key, std::move(
function)));
345 else if (std::holds_alternative<single_value_type>(*m_optFunctions))
347 single_value_type first = std::get<single_value_type>(std::move(*m_optFunctions));
348 container_type container;
349 container.emplace(first.first, std::move(first.second));
350 container.emplace(key, std::move(
function));
351 m_optFunctions = std::move(container);
355 std::get<container_type>(*m_optFunctions).emplace(key, std::move(
function));
361 template<
class return_t,
class... args_t>
362 requires(
sizeof...(args_t) > 0 && (!std::is_void_v<args_t> && ...))
363 return_t delegate<return_t(args_t...)>::execute(args_t... args) const noexcept
365 return this->execute_internal(
366 [&args...](
const typename super_type::function_type&
function)
368 return function(std::forward<args_t>(args)...);
370 [&args...](
const typename super_type::function_type&
function)
372 return function(args...);
376 template<
class return_t>
377 return_t delegate<return_t(
void)>::execute() const noexcept
379 return this->execute_internal(
380 [](
const typename super_type::function_type&
function)
384 [](
const typename super_type::function_type&
function)
Single or multicast delegate.
Class for RAII: functor passed in constructor will be called in destructor.
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.
return_t execute_internal(const invoke_single_t &invokeSingle, const invoke_multiple_t &invokeMultiple) const noexcept
Execute all callables.
void clear() noexcept
Clear all the callables in this 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.
bool empty() const noexcept
Check if this delegate is empty.
size_t size() const noexcept
Get the number of functions bound to this delegate.
static derived_t create_singlecast(creation_args_t... args) noexcept
Create a singlecast delegate.
bool remove(delegate_token_type token) noexcept
Remove a callable using its token.
delegate_token_type add_token(callable_t callable, priority ePriority=priority::normal) noexcept
Add a callable using a token with manual unsubscribing.
A class that can be used as a key in ordered containers so that items are ordered in descending order...
requires(same_variadic_args_v< args_t... >) const expr auto coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.
priority
User may use the predefined values or the custom ones, for ex. "normal - 1", this type is supposed to...
#define QX_STATIC_ASSERT_NO_INSTANTIATION(Message)
This static assert will fail if block it placed in must not be instantiated.