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;
36 const invoke_function_t& m_InvokeFunction;
39 template<
class return_t,
class function_t,
class invoke_function_t>
42 return m_InvokeFunction(
function);
45 template<
class derived_t,
class return_t,
class... args_t>
46 base_delegate<derived_t, return_t, args_t...>::base_delegate(base_delegate&& other) noexcept
48 std::swap(m_optFunctions, other.m_optFunctions);
49 std::swap(m_pDelegateAliveMarker, other.m_pDelegateAliveMarker);
52 template<
class derived_t,
class return_t,
class... args_t>
53 typename base_delegate<derived_t, return_t, args_t...>::base_delegate& base_delegate<derived_t, return_t, args_t...>::
54 operator=(base_delegate&& other) noexcept
56 std::swap(m_optFunctions, other.m_optFunctions);
57 std::swap(m_pDelegateAliveMarker, other.m_pDelegateAliveMarker);
61 template<
class derived_t,
class return_t,
class... args_t>
62 template<
class... creation_args_t>
66 if constexpr (
requires(derived_t d) { d.add_weak(args...); })
68 if constexpr (
requires(derived_t d) { d.add_token(args...); })
76 template<
class derived_t,
class return_t,
class... args_t>
77 template<callable_c<return_t, args_t...> callable_t>
84 add_function(key, std::move(callable));
88 template<
class derived_t,
class return_t,
class... args_t>
89 template<
class object_t>
92 return_t (object_t::*pMethod)(args_t...),
97 [pMethod, &
object](args_t... args)
99 return (object.*pMethod)(std::forward<args_t>(args)...);
104 template<
class derived_t,
class return_t,
class... args_t>
105 template<callable_c<return_t, args_t...> callable_t>
114 template<
class derived_t,
class return_t,
class... args_t>
115 template<
class object_t>
118 return_t (object_t::*pMethod)(args_t...),
121 return add_destruction_callback(
124 [&
object, pMethod](args_t... args)
126 return (object.*pMethod)(std::forward<args_t>(args)...);
130 template<
class derived_t,
class return_t,
class... args_t>
131 template<
class object_t, callable_c<return_t, args_t...> callable_t>
133 std::weak_ptr<object_t> pWeakObject,
140 std::move(pWeakObject),
142 [callable_ = std::move(callable)](object_t*, args_t... args)
144 return callable_(std::forward<args_t>(args)...);
149 template<
class derived_t,
class return_t,
class... args_t>
150 template<
class object_t>
152 std::weak_ptr<object_t> pWeakObject,
153 return_t (object_t::*pMethod)(args_t...),
159 std::move(pWeakObject),
161 [pMethod](object_t* pObject, args_t... args)
163 return (pObject->*pMethod)(std::forward<args_t>(args)...);
168 template<
class derived_t,
class return_t,
class... args_t>
171 return m_optFunctions
173 [
this, token]<
class T>(T& value)
175 if constexpr (std::is_same_v<T, single_value_type>)
177 if (value.first == token)
179 m_optFunctions.reset();
187 else if constexpr (std::is_same_v<T, container_type>)
189 return value.erase(token) == 1;
200 template<
class derived_t,
class return_t,
class... args_t>
203 m_optFunctions.reset();
206 template<
class derived_t,
class return_t,
class... args_t>
213 []<
class T>(
const T& value) ->
size_t
215 if constexpr (std::is_same_v<T, single_value_type>)
219 else if constexpr (std::is_same_v<T, container_type>)
232 template<
class derived_t,
class return_t,
class... args_t>
238 template<
class derived_t,
class return_t,
class... args_t>
239 template<
class invoke_single_t,
class invoke_multiple_t>
241 const invoke_single_t& invokeSingle,
242 const invoke_multiple_t& invokeMultiple)
const noexcept
246 if constexpr (std::is_void_v<return_t>)
253 thread_local variant_type tempFunctions;
254 tempFunctions = *m_optFunctions;
256 if (std::holds_alternative<single_value_type>(tempFunctions))
258 const auto& [_,
function] = std::get<single_value_type>(tempFunctions);
259 return invokeSingle(
function);
263 const container_type& container = std::get<container_type>(tempFunctions);
268 if (container.size() == 1)
273 if constexpr (std::is_void_v<return_t>)
275 for (
const auto& [_,
function] : container)
280 else if constexpr (delegate_pipe_c<return_t>)
283 for (
const auto& [_,
function] : container)
284 result = result |
invoker->invoke(
function);
291 for (
const auto& [_,
function] : container)
292 result =
invoker->invoke(
function);
299 template<
class derived_t,
class return_t,
class... args_t>
300 template<
class object_t, callable_c<return_t, object_t*, args_t...> callable_t>
303 std::weak_ptr<object_t> pWeakObject,
304 callable_t callable) noexcept
308 [
this, key, pWeakObject, callable_ = std::move(callable)](args_t... args)
310 if (std::shared_ptr<object_t> pObject = pWeakObject.lock())
312 return callable_(pObject.get(), std::forward<args_t>(args)...);
322 template<
class derived_t,
class return_t,
class... args_t>
323 destruction_callback base_delegate<derived_t, return_t, args_t...>::add_destruction_callback(
324 time_ordered_priority_key key,
325 function_type value) noexcept
327 add_function(key, std::move(value));
329 if (!m_pDelegateAliveMarker)
330 m_pDelegateAliveMarker = std::make_shared<bool>(
true);
332 return [
this, key, pDelegateAliveMarker = std::weak_ptr(m_pDelegateAliveMarker)]()
334 if (!pDelegateAliveMarker.expired())
339 template<
class derived_t,
class return_t,
class... args_t>
340 void base_delegate<derived_t, return_t, args_t...>::add_function(
341 time_ordered_priority_key key,
342 function_type
function) noexcept
346 m_optFunctions = variant_type(single_value_type(key, std::move(
function)));
348 else if (std::holds_alternative<single_value_type>(*m_optFunctions))
350 single_value_type first = std::get<single_value_type>(std::move(*m_optFunctions));
351 container_type container;
352 container.try_emplace(first.first, std::move(first.second));
353 container.try_emplace(key, std::move(
function));
354 m_optFunctions = std::move(container);
358 std::get<container_type>(*m_optFunctions).try_emplace(key, std::move(
function));
364 template<
class return_t,
class... args_t>
365 requires(
sizeof...(args_t) > 0 && (!std::is_void_v<args_t> && ...))
366 return_t delegate<return_t(args_t...)>::execute(args_t... args) const noexcept
368 return this->execute_internal(
369 [&args...](
const typename super_type::function_type&
function)
371 return function(std::forward<args_t>(args)...);
373 [&args...](
const typename super_type::function_type&
function)
375 return function(args...);
379 template<
class return_t>
380 return_t delegate<return_t(
void)>::execute() const noexcept
382 return this->execute_internal(
383 [](
const typename super_type::function_type&
function)
387 [](
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.