Program Listing for File HsmEventDispatcherBase.hpp

Return to documentation for file (include/hsmcpp/HsmEventDispatcherBase.hpp)

// Copyright (C) 2021 Igor Krechetov
// Distributed under MIT license. See file LICENSE for details

#ifndef HSMCPP_HSMEVENTDISPATCHERBASE_HPP
#define HSMCPP_HSMEVENTDISPATCHERBASE_HPP

#include <list>
#include <map>
#include <memory>
#include <vector>

#include "IHsmEventDispatcher.hpp"
#include "os/Mutex.hpp"

#define DISPATCHER_DEFAULT_EVENTS_CACHESIZE (10)

namespace hsmcpp {

class HsmEventDispatcherBase : public IHsmEventDispatcher {
protected:
    struct TimerInfo {
        HandlerID_t handlerID = INVALID_HSM_DISPATCHER_HANDLER_ID;
        unsigned int intervalMs = 0;
        bool isSingleShot = false;
    };

    struct EnqueuedEventInfo {
        HandlerID_t handlerID = INVALID_HSM_DISPATCHER_HANDLER_ID;
        EventID_t eventID = INVALID_HSM_EVENT_ID;

        EnqueuedEventInfo(const HandlerID_t newHandlerID, const EventID_t newEventID);
    };

public:
    void stop() override;

    HandlerID_t registerEventHandler(const EventHandlerFunc_t& handler) override;

    void unregisterEventHandler(const HandlerID_t handlerID) override;

    void emitEvent(const HandlerID_t handlerID) override = 0;

    bool enqueueEvent(const HandlerID_t handlerID, const EventID_t event) override;

    void enqueueAction(ActionHandlerFunc_t actionCallback) override;

    HandlerID_t registerEnqueuedEventHandler(const EnqueuedEventHandlerFunc_t& handler) override;

    void unregisterEnqueuedEventHandler(const HandlerID_t handlerID) override;

    HandlerID_t registerTimerHandler(const TimerHandlerFunc_t& handler) override;

    void unregisterTimerHandler(const HandlerID_t handlerID) override;

    void startTimer(const HandlerID_t handlerID,
                    const TimerID_t timerID,
                    const unsigned int intervalMs,
                    const bool isSingleShot) override;

    void restartTimer(const TimerID_t timerID) override;

    void stopTimer(const TimerID_t timerID) override;

    bool isTimerRunning(const TimerID_t timerID) override;

protected:
    // cppcheck-suppress misra-c2012-17.8 ; false positive. setting default parameter value is not parameter modification
    explicit HsmEventDispatcherBase(const size_t eventsCacheSize = DISPATCHER_DEFAULT_EVENTS_CACHESIZE);

    virtual ~HsmEventDispatcherBase() = default;

    static void handleDelete(HsmEventDispatcherBase* dispatcher);

    virtual bool deleteSafe() = 0;

    virtual HandlerID_t getNextHandlerID();

    void unregisterAllEventHandlers();

    EnqueuedEventHandlerFunc_t getEnqueuedEventHandlerFunc(const HandlerID_t handlerID) const;

    TimerHandlerFunc_t getTimerHandlerFunc(const HandlerID_t handlerID) const;

    virtual void startTimerImpl(const TimerID_t timerID, const unsigned int intervalMs, const bool isSingleShot);

    virtual void stopTimerImpl(const TimerID_t timerID);

    unsigned int handleTimerEvent(const TimerID_t timerID);

    virtual void notifyDispatcherAboutEvent() = 0;

    void dispatchEnqueuedEvents();

    void dispatchPendingActions();

    void dispatchPendingEvents();

    void dispatchPendingEventsImpl(const std::list<HandlerID_t>& events);

protected:
    HandlerID_t mNextHandlerId = 1;
    std::map<TimerID_t, TimerInfo> mActiveTimers;                              // protected by mHandlersSync
    std::map<HandlerID_t, EventHandlerFunc_t> mEventHandlers;                  // protected by mHandlersSync
    std::map<HandlerID_t, EnqueuedEventHandlerFunc_t> mEnqueuedEventHandlers;  // protected by mHandlersSync
    std::map<HandlerID_t, TimerHandlerFunc_t> mTimerHandlers;                  // protected by mHandlersSync
    std::list<ActionHandlerFunc_t> mPendingActions;                            // protected by mEmitSync
    std::list<HandlerID_t> mPendingEvents;                                     // protected by mEmitSync
    std::vector<EnqueuedEventInfo> mEnqueuedEvents;                            // protected by mEnqueuedEventsSync
    Mutex mEmitSync;
    Mutex mHandlersSync;
    Mutex mEnqueuedEventsSync;
    Mutex mRunningTimersSync;
    bool mStopDispatcher = false;
};

}  // namespace hsmcpp
#endif  // HSMCPP_HSMEVENTDISPATCHERBASE_HPP