#ifndef VAPI_TASK_TIMER_H #define VAPI_TASK_TIMER_H #include "../interfaces/timer.h" #include "interface_ptr.h" #include "local_service_access.h" #include namespace sdv { namespace core { /** * @brief Task timer class. */ class CTaskTimer { public: /** * @brief Dfault constructor */ CTaskTimer() = default; /** * @brief Constructor * @param[in] uiPeriod The period to create a timer for. * @param[in] fnCallback Callback function to be called on task execution. */ CTaskTimer(uint32_t uiPeriod, std::function fnCallback) : m_ptrCallback(std::make_unique(fnCallback)) { if (!m_ptrCallback) return; if (!uiPeriod) return; // Get the task timer service. sdv::core::ITaskTimer* pTaskTimer = sdv::core::GetObject("TaskTimerService"); if (!pTaskTimer) { pTaskTimer = sdv::core::GetObject("SimulationTaskTimerService"); if (!pTaskTimer) return; } // Create the timer m_pTimer = pTaskTimer->CreateTimer(uiPeriod, m_ptrCallback.get()); } /** * @brief Constructor * @param[in] uiPeriod The period to create a timer for. * @param[in] pTask Pointer to the interface of the task object to be called. The object must expose * sdv::core::ITastExecute. */ CTaskTimer(uint32_t uiPeriod, sdv::IInterfaceAccess* pTask) { if (!uiPeriod) return; // Get the task timer service. sdv::core::ITaskTimer* pTaskTimer = sdv::core::GetObject("TaskTimerService"); if (!pTaskTimer) { pTaskTimer = sdv::core::GetObject("SimulationTaskTimerService"); if (!pTaskTimer) return; } // Create the timer m_pTimer = pTaskTimer->CreateTimer(uiPeriod, pTask); } /** * @brief Copy constructor is deleted. */ CTaskTimer(const CTaskTimer&) = delete; /** * @brief Move constructor * @param[in] rtimer Reference to the timer to move from. */ CTaskTimer(CTaskTimer&& rtimer) noexcept : m_pTimer(rtimer.m_pTimer), m_uiPeriod(rtimer.m_uiPeriod), m_ptrCallback(std::move(rtimer.m_ptrCallback)) { rtimer.m_pTimer = nullptr; rtimer.m_uiPeriod = 0; } /** * @brief Destructor */ ~CTaskTimer() { Reset(); } /** * @brief Assignment operator is deleted. */ CTaskTimer& operator=(const CTaskTimer&) = delete; /** * @brief Move operator * @param[in] rtimer Reference to the timer to move from. * @return Reference to this timer object. */ CTaskTimer& operator=(CTaskTimer&& rtimer) noexcept { Reset(); m_pTimer = rtimer.m_pTimer; m_ptrCallback = std::move(rtimer.m_ptrCallback); m_uiPeriod = rtimer.m_uiPeriod; rtimer.m_pTimer = nullptr; rtimer.m_uiPeriod = 0; return *this; } /** * @brief Returns whether the timer is valid. */ operator bool() const { return m_pTimer; } /** * @brief Reset the timer. Releases the timer object. */ void Reset() { if (m_pTimer) { IObjectDestroy* pDestroy = m_pTimer->GetInterface(); if (pDestroy) pDestroy->DestroyObject(); m_pTimer = nullptr; } m_ptrCallback.reset(); m_uiPeriod = 0ul; } /** * @brief Get the task timer period. * @return The period of the timer in ms. */ uint32_t GetPeriod() const { return m_uiPeriod; } private: /** * @brief Timer callback wrapper object. */ struct STimerCallback : public IInterfaceAccess, public core::ITaskExecute { STimerCallback(std::function fnCallback) : m_fnCallback(fnCallback) {} protected: // Interface map BEGIN_SDV_INTERFACE_MAP() SDV_INTERFACE_ENTRY(core::ITaskExecute) END_SDV_INTERFACE_MAP() /** * @brief Execute the trigger. Overload of ITxTriggerCallback::Execute. */ virtual void Execute() override { if (m_fnCallback) m_fnCallback(); } private: std::function m_fnCallback; ///< Callback function }; sdv::IInterfaceAccess* m_pTimer = nullptr; ///< Timer object uint32_t m_uiPeriod = 0ul; ///< Task timer period std::unique_ptr m_ptrCallback; ///< Callback object }; } } #endif // !defined VAPI_TASK_TIMER_H