Changeset View
Changeset View
Standalone View
Standalone View
src/eventemitter/lagerstoreeventemitter.hpp
| /* | /* | ||||
| * This file is part of libkazv. | * This file is part of libkazv. | ||||
| * SPDX-FileCopyrightText: 2020 Tusooa Zhu | * SPDX-FileCopyrightText: 2020-2026 tusooa <tusooa@kazv.moe> | ||||
| * SPDX-License-Identifier: AGPL-3.0-or-later | * SPDX-License-Identifier: AGPL-3.0-or-later | ||||
| */ | */ | ||||
| #pragma once | #pragma once | ||||
| #include <libkazv-config.hpp> | #include <libkazv-config.hpp> | ||||
| #include <vector> | #include <vector> | ||||
| #include <memory> | #include <memory> | ||||
| #include <algorithm> | #include <algorithm> | ||||
| #include <lager/store.hpp> | #include <lager/store.hpp> | ||||
| #include <lager/reader.hpp> | #include <lager/reader.hpp> | ||||
| #include <lager/event_loop/manual.hpp> | #include <lager/event_loop/manual.hpp> | ||||
| #include "types.hpp" | #include "types.hpp" | ||||
| #include "eventinterface.hpp" | #include "eventinterface.hpp" | ||||
| namespace Kazv | namespace Kazv | ||||
| { | { | ||||
| class LagerStoreEventEmitter : public EventInterface | class LagerStoreEventEmitter : public EventInterface | ||||
| { | { | ||||
| struct Model { KazvEvent curEvent; }; | struct Model { KazvTrigger curEvent; }; | ||||
| struct Action { KazvEvent nextEvent; }; | struct Action { KazvTrigger nextEvent; }; | ||||
| struct ListenerHolder; | struct ListenerHolder; | ||||
| using Result = std::pair<Model, | using Result = std::pair<Model, | ||||
| lager::effect<Action, lager::deps<ListenerHolder &>>>; | lager::effect<Action, lager::deps<ListenerHolder &>>>; | ||||
| using SlotT = std::function<void(KazvEvent)>; | using SlotT = std::function<void(KazvTrigger)>; | ||||
| struct Listener | struct Listener | ||||
| { | { | ||||
| void emit(KazvEvent e) { | void emit(KazvTrigger e) { | ||||
| for (const auto &slot: m_slots) { | for (const auto &slot: m_slots) { | ||||
| slot(e); | slot(e); | ||||
| } | } | ||||
| } | } | ||||
| void connect(SlotT slot) { | void connect(SlotT slot) { | ||||
| m_slots.push_back(std::move(slot)); | m_slots.push_back(std::move(slot)); | ||||
| } | } | ||||
| std::vector<SlotT> m_slots; | std::vector<SlotT> m_slots; | ||||
| }; | }; | ||||
| using ListenerSP = std::shared_ptr<Listener>; | using ListenerSP = std::shared_ptr<Listener>; | ||||
| using ListenerWSP = std::weak_ptr<Listener>; | using ListenerWSP = std::weak_ptr<Listener>; | ||||
| struct ListenerHolder | struct ListenerHolder | ||||
| { | { | ||||
| void sendToListeners(KazvEvent e) { | void sendToListeners(KazvTrigger e) { | ||||
| bool needsCleanup = false; | bool needsCleanup = false; | ||||
| for (auto listener : m_listeners) { | for (auto listener : m_listeners) { | ||||
| auto strongListener = listener.lock(); | auto strongListener = listener.lock(); | ||||
| if (strongListener) { | if (strongListener) { | ||||
| strongListener->emit(e); | strongListener->emit(e); | ||||
| } else { | } else { | ||||
| needsCleanup = true; | needsCleanup = true; | ||||
| } | } | ||||
| Show All 33 Lines | public: | ||||
| lager::with_reducer(&update), | lager::with_reducer(&update), | ||||
| lager::with_deps(std::ref(m_holder)))) | lager::with_deps(std::ref(m_holder)))) | ||||
| , m_postingFunc( | , m_postingFunc( | ||||
| [loop=loop](auto &&func) mutable { | [loop=loop](auto &&func) mutable { | ||||
| loop.post(std::forward<decltype(func)>(func)); | loop.post(std::forward<decltype(func)>(func)); | ||||
| }) {} | }) {} | ||||
| ~LagerStoreEventEmitter() override = default; | ~LagerStoreEventEmitter() override = default; | ||||
| void emit(KazvEvent e) override { | void emit(KazvTrigger e) override { | ||||
| m_store.dispatch(Action{e}); | m_store.dispatch(Action{e}); | ||||
| } | } | ||||
| class Watchable | class Watchable | ||||
| { | { | ||||
| public: | public: | ||||
| Watchable(LagerStoreEventEmitter &ee) | Watchable(LagerStoreEventEmitter &ee) | ||||
| : m_listener(std::make_shared<Listener>()) { | : m_listener(std::make_shared<Listener>()) { | ||||
| ee.addListener(m_listener); | ee.addListener(m_listener); | ||||
| } | } | ||||
| template<class EventType, class Func> | template<class EventType, class Func> | ||||
| void after(Func &&func) { | void after(Func &&func) { | ||||
| m_listener->connect( | m_listener->connect( | ||||
| [f=std::forward<Func>(func)](KazvEvent e) { | [f=std::forward<Func>(func)](KazvTrigger e) { | ||||
| if (std::holds_alternative<EventType>(e)) { | if (std::holds_alternative<EventType>(e)) { | ||||
| f(std::get<EventType>(e)); | f(std::get<EventType>(e)); | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| template<class Func> | template<class Func> | ||||
| void afterAll(Func &&func) { | void afterAll(Func &&func) { | ||||
| m_listener->connect( | m_listener->connect( | ||||
| [f=std::forward<Func>(func)](KazvEvent e) { | [f=std::forward<Func>(func)](KazvTrigger e) { | ||||
| f(e); | f(e); | ||||
| }); | }); | ||||
| } | } | ||||
| private: | private: | ||||
| ListenerSP m_listener; | ListenerSP m_listener; | ||||
| }; | }; | ||||
| Show All 35 Lines | |||||