2021-08-04 09:53:57 +02:00
|
|
|
#pragma once
|
|
|
|
/*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* Copyright 2021 Dominik Meyer <dmeyer@federationhq.de>
|
|
|
|
* This file is part of the EventManager distribution hosted at https://gitea.federationhq.de/byterazor/EventManager.git
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @file */
|
|
|
|
#include <memory>
|
|
|
|
#include <atomic>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <string>
|
|
|
|
#include <mutex>
|
|
|
|
#include <queue>
|
|
|
|
#include <condition_variable>
|
|
|
|
|
|
|
|
#include <EventManager/Event.hpp>
|
|
|
|
|
|
|
|
namespace EventManager
|
|
|
|
{
|
|
|
|
|
|
|
|
// forward declaration for the EventManager::Manager
|
|
|
|
class Manager;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The entity participating in the event system.
|
2022-09-22 13:39:33 +02:00
|
|
|
*
|
|
|
|
* If you want the participant to be scheduled from the manager call
|
|
|
|
* _enableScheduling class function.
|
2021-08-04 09:53:57 +02:00
|
|
|
*/
|
|
|
|
class Participant : public std::enable_shared_from_this<Participant>
|
|
|
|
{
|
|
|
|
private:
|
2022-02-19 12:26:19 +01:00
|
|
|
/// a unique id for this participant, helpful for debugging
|
|
|
|
std::uint32_t id_;
|
2021-08-04 09:53:57 +02:00
|
|
|
|
|
|
|
/// pointer to the event manager
|
|
|
|
std::shared_ptr<EventManager::Manager> manager_;
|
|
|
|
|
|
|
|
/// is the participant scheduled by the EventManager::Manager
|
|
|
|
std::atomic<bool> isScheduledByManager_;
|
|
|
|
|
|
|
|
/// queue for incomng events
|
|
|
|
std::queue<std::shared_ptr<EventManager::Event>> eventQueue_;
|
|
|
|
|
|
|
|
/// mutex to protect the event queue
|
|
|
|
std::mutex mutexEventQueue_;
|
|
|
|
|
|
|
|
/// condition variable to wake of thread on new trigger
|
|
|
|
std::condition_variable newEventInQueue_;
|
|
|
|
|
|
|
|
/// has the participant locked the queue itself already
|
|
|
|
std::atomic<bool> isQueueLocked_;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* all private methods
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Method called if the participant is scheduled by EventManager::Manager
|
|
|
|
*
|
|
|
|
* This method needs to be implemented by the child class.
|
|
|
|
* Please make sure this method returns as fast as possible!
|
|
|
|
* No endless loops are supported.
|
|
|
|
* Just process some incoming events and then return!
|
|
|
|
*/
|
|
|
|
virtual void schedule_() { throw std::runtime_error(std::string(__PRETTY_FUNCTION__) + " not implemented");}
|
|
|
|
|
2021-08-04 12:04:30 +02:00
|
|
|
/**
|
|
|
|
* @brief method called by the EventManager::Manager on connecting this particpant
|
|
|
|
*
|
|
|
|
* This method need to be implemented by each child class of EventManager::Participant
|
|
|
|
* Its the best location for subscribing to events and enable scheduling if required.
|
|
|
|
*/
|
|
|
|
virtual void init_() {throw std::runtime_error(std::string(__PRETTY_FUNCTION__) + " not implemented");}
|
|
|
|
|
2021-08-04 09:53:57 +02:00
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief check if events are available
|
|
|
|
*/
|
|
|
|
bool _hasEvents();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Lock the queue to process all events
|
|
|
|
*/
|
|
|
|
void _lockQueue();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief UnLock the queue to process all events
|
|
|
|
*/
|
|
|
|
void _unlockQueue();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief fetch one event from the queue
|
|
|
|
*/
|
|
|
|
std::shared_ptr<EventManager::Event> _fetchEvent();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief wait for a new event
|
|
|
|
*/
|
|
|
|
void _waitForEvent();
|
|
|
|
|
2021-08-16 20:07:07 +02:00
|
|
|
/**
|
|
|
|
* @brief wait for a new event with timeout
|
2021-08-16 20:12:05 +02:00
|
|
|
*
|
|
|
|
* @return true - new event available and queue locked
|
|
|
|
* @return false - no new event, queue not locked, timeout reached
|
2021-08-16 20:07:07 +02:00
|
|
|
*/
|
2021-08-16 20:12:05 +02:00
|
|
|
bool _waitForEvent(std::uint32_t timeoutMS);
|
2021-08-04 09:53:57 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This method subscribes the participant to an event type
|
|
|
|
*
|
|
|
|
* @param type - the event type to subscribe this participant to
|
|
|
|
*/
|
|
|
|
void _subscribe(std::uint32_t type);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief unsubscribe the participant from the given event type
|
|
|
|
*/
|
|
|
|
void _unsubscribe(std::uint32_t type);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief unsubscribe the participant from the all event types
|
|
|
|
*/
|
|
|
|
void _unsubscribe();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Method to emit an event to the event manager
|
|
|
|
*
|
|
|
|
* @param event - the event to emit
|
|
|
|
*/
|
|
|
|
void _emit(std::shared_ptr<EventManager::Event> event);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief enable scheduling of this particpant through the EventManager::Manager
|
|
|
|
*/
|
|
|
|
void _enableScheduling();
|
|
|
|
|
2022-02-19 12:32:25 +01:00
|
|
|
/**
|
|
|
|
* @brief disable scheduling of this particpant through the EventManager::Manager
|
|
|
|
*/
|
|
|
|
void _disableScheduling();
|
|
|
|
|
2021-08-04 09:53:57 +02:00
|
|
|
/**
|
|
|
|
* @brief check if the participant is scheduled by event manager
|
|
|
|
*/
|
|
|
|
bool isScheduledByManager() const {return isScheduledByManager_;}
|
|
|
|
|
2021-08-15 20:53:45 +02:00
|
|
|
/**
|
|
|
|
* @brief connect a new participant through another participant
|
|
|
|
*/
|
|
|
|
void connect(std::shared_ptr<EventManager::Participant> participant);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief disconnect a participant through another participant
|
|
|
|
*/
|
|
|
|
void disconnect(std::shared_ptr<EventManager::Participant> participant);
|
|
|
|
|
2022-11-01 20:03:31 +01:00
|
|
|
/**
|
|
|
|
* @brief disconnect this participant from the event manager
|
|
|
|
*/
|
|
|
|
void disconnect();
|
|
|
|
|
2021-08-04 09:53:57 +02:00
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* @brief Constructor setting the participant up for use
|
|
|
|
*/
|
|
|
|
Participant();
|
|
|
|
|
2022-02-19 12:28:19 +01:00
|
|
|
/**
|
|
|
|
* @brief Method to set the Manager object
|
|
|
|
*
|
|
|
|
* This method is in general only used by the EventManager::Manager!
|
|
|
|
* Only use this method if you really know what you are doing!
|
|
|
|
*
|
|
|
|
* @param manager - the manager to set
|
|
|
|
*/
|
2021-08-04 09:53:57 +02:00
|
|
|
void setManager(std::shared_ptr<EventManager::Manager> manager) { manager_=manager;_subscribe(EVENT_TYPE_SHUTDOWN);}
|
|
|
|
|
2022-02-19 12:26:19 +01:00
|
|
|
/**
|
|
|
|
* @brief Method to set the unique id of the participant
|
|
|
|
*
|
|
|
|
* This method is in general only used by the EventManager::Manager!
|
|
|
|
* Only use this method if you really know what you are doing!
|
|
|
|
*
|
|
|
|
* @param id - the id to set
|
|
|
|
*/
|
|
|
|
void setID(const std::uint32_t id) { id_=id;}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Method to return the unique id of the participant
|
|
|
|
*
|
|
|
|
* @return std::uint32_t
|
|
|
|
*/
|
|
|
|
std::uint32_t getID() const { return id_;}
|
|
|
|
|
2021-08-04 09:53:57 +02:00
|
|
|
/**
|
|
|
|
* @brief Method called by the EventManager::Manager to schedule the particpant
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void schedule() {schedule_();};
|
|
|
|
|
2021-08-04 12:04:30 +02:00
|
|
|
/**
|
|
|
|
* @brief method called by the EventManager::Manager when connecting the particpant
|
|
|
|
*
|
|
|
|
* method calls virtual _init method which has to be implemented by each particpants child class
|
|
|
|
*/
|
|
|
|
void init() {init_();}
|
2021-08-04 09:53:57 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief emit an event to this participant
|
|
|
|
*/
|
|
|
|
void emit(std::shared_ptr<EventManager::Event> event);
|
|
|
|
|
|
|
|
};//
|
|
|
|
|
|
|
|
}; // namespace EventManager
|