#ifndef __MSC_ENGINE_BUS_HPP__ #define __MSC_ENGINE_BUS_HPP__ #include #include #include #include #include #include /// @brief Event base class class MscEvent { public: virtual ~MscEvent() = default; /// @brief Get event name virtual std::string getName() const = 0; /// @brief Is current event is canceled bool isCanceled() const { return canceled; } /// @brief Cancel current event void cancel() { canceled = true; } private: bool canceled = false; }; /// @brief Engine event bus class MscEventBus { public: /// @brief Event handler alias using Listener = std::function; /// @brief Subscription identifier alias using SubscriptionId = std::uint64_t; /// @brief Emit event /// @param event event context void publish(MscEvent &event); /// @brief Subscribe to specified event /// @param name event name /// @param listener event handler /// @returns subscription identifier to make it possitble to remove listener SubscriptionId subscribe(const std::string &name, Listener listener); /// @brief Subscribe to specified event and execute once on publish /// @param name event name /// @param listener event handler SubscriptionId subscribeOnce(const std::string &name, Listener listener); /// @brief Unsubscribe listener by its own id /// @param id subscription id /// @return `true` if listener has been deleted, otherwise `false` bool unsubscribe(SubscriptionId id); private: using ListenerWithId = struct { SubscriptionId id; Listener listener; bool once; }; std::unordered_map> _listeners; std::unordered_map _listenersPaths; std::uint64_t _lastId = 0; std::mutex _listenersMutex; SubscriptionId _subscribe(const std::string &name, Listener listener, bool once); }; #endif // __MSC_ENGINE_BUS_HPP__