56 std::function<void()> callback;
65 template <
typename... Args>
69 auto&
event = aSlot.
event();
70 std::tuple<Args...> args{ aArgs... };
71 auto callback = [&, args]()
73 std::apply([&](Args... aArgs) { aSlot.call(aArgs...); }, args);
77 auto existing = std::find_if(iQueue.begin(), iQueue.end(), [&](
auto const& e) { return e.event == &event && e.slot == &aSlot; });
78 if (existing != iQueue.end())
80 existing->callback = callback;
84 iQueue.emplace_back(&
event,
event, &aSlot, aSlot, callback);
95 template <typename... Args>
98 typedef event<Args...> self_type;
107 bool accepted =
false;
123 iTriggerType = aTriggerType;
130 thread_local std::size_t stack;
132 thread_local std::vector<std::unique_ptr<work_list>> workLists;
133 if (workLists.size() < stack)
134 workLists.push_back(std::make_unique<work_list>());
135 auto& workList = *workLists[stack - 1];
137 workList.slots = iSlots;
139 for (
auto slot : workList.slots)
147 if (workList.accepted)
150 workList.slots.clear();
151 workList.accepted =
false;
157 for (
auto slot : iSlots)
164 iActiveWorkList->accepted =
true;
170 return !iSlots.empty();
175 iSlots.push_back(&aSlot);
180 auto existing = std::find_if(iSlots.begin(), iSlots.end(), [&](
auto const& s) { return &aSlot == s.ptr(); });
181 if (existing != iSlots.end())
182 iSlots.erase(existing);
187 aQueue.
enqueue<Args...>(aSlot, aNoDuplicates, aArgs...);
191 mutable slot_list iSlots;
192 mutable work_list* iActiveWorkList =
nullptr;
195 #define define_declared_event( name, declName, ... ) \
196 neolib::event<__VA_ARGS__> name; \
197 const neolib::i_event<__VA_ARGS__>& ev_##declName() const final { return name; };\
198 neolib::i_event<__VA_ARGS__>& ev_##declName() final { return name; };
200 #define define_event( name, declName, ... ) \
201 neolib::event<__VA_ARGS__> name; \
202 const neolib::i_event<__VA_ARGS__>& ev_##declName() const { return name; };\
203 neolib::i_event<__VA_ARGS__>& ev_##declName() { return name; };\
204 const neolib::i_event<__VA_ARGS__>& declName() const { return ev_##declName(); }\
205 neolib::i_event<__VA_ARGS__>& declName() { return ev_##declName(); }\
206 detail_event_subscribe(declName, __VA_ARGS__)
void register_with_task(i_async_task &aTask) final
static async_event_queue & instance()
static async_event_queue & instance(std::thread::id aThreadId)
void enqueue(i_slot< Args... > &aSlot, bool aNoDuplicates, Args... aArgs)
void remove_slot(i_slot< Args... > &aSlot) const final
void set_trigger_type(neolib::trigger_type aTriggerType) final
neolib::trigger_type trigger_type() const final
void async_trigger(Args... aArgs) const final
bool has_slots() const final
void accept() const final
void add_slot(i_slot< Args... > &aSlot) const final
trigger_result sync_trigger(Args... aArgs) const final
virtual i_event< Args... > const & event() const =0
virtual bool stateless() const =0
void call(Args... aArgs) const final
bool call_in_emitter_thread() const final
std::thread::id call_thread() const final
switchable_mutex & event_mutex()
auto destroyed(Object &aObject, const Handler aHandler)