Skip to main content

EventPool

Overview​

The EventPool class is responsible for managing a queue of Event objects, providing functionalities to add, retrieve, and delete events. It serves as a centralized storage and dispatcher for game events, ensuring thread safety through the use of mutexes and condition variables. This class is a singleton, ensuring that only one instance is used throughout the application.

Table of Contents​

  1. Class Overview
  2. Public Methods
  3. Private Methods
  4. Usage Examples
  5. Thread Safety

Class Overview​

class EventPool {
public:
static EventPool& getInstance();
void addEvent(const Event& event);
Event getNextEvent();
std::vector<Event> getAllEvents();
void deleteEvent(Event& event);

private:
std::deque<Event> eventQueue; ///< Queue to store events.
mutable std::mutex eventMutex; ///< Mutex to ensure thread-safety.
std::condition_variable condition; ///< Condition variable to notify when events are added.
std::optional<std::function<void(Event)>> _handler;

void handler(const GDTPHeader &header, const std::vector<uint8_t> &payload, const asio::ip::udp::endpoint &client_endpoint);
};

Public Methods​

getInstance()​

static EventPool& getInstance();
  • Description: Returns a reference to the singleton instance of EventPool. Ensures that only one instance of EventPool exists.

  • Returns:

    • EventPool&: A reference to the singleton instance.
  • Example:

// Access the singleton instance of EventPool
EventPool& eventPool = EventPool::getInstance();

addEvent()​

void addEvent(const Event& event);
  • Description: Adds a new Event to the eventQueue. Notifies any threads waiting for new events.

  • Parameters:

    • event: The Event object to be added to the queue.
  • Example:

Event newEvent(EventType::PlayerMovement, playerMovement);
eventPool.addEvent(newEvent);

getNextEvent()​

Event getNextEvent();
  • Description: Retrieves the next Event from the eventQueue. If the queue is empty, it waits until an event is added.

  • Returns:

    • Event: The next Event in the queue.
  • Example:

// Get the next event from the event pool
Event nextEvent = eventPool.getNextEvent();

getAllEvents()​

std::vector<Event> getAllEvents();
  • Description: Retrieves all Event objects currently in the eventQueue and clears the queue.

  • Returns:

    • std::vector<Event>: A vector containing all events from the queue.
  • Example:

// Retrieve all events from the queue
std::vector<Event> events = eventPool.getAllEvents();
for (const Event& event : events) {
// Process each event
}

deleteEvent()​

void deleteEvent(Event& event);
  • Description: Removes a specified Event from the eventQueue. If the event is not found, no action is taken.

  • Parameters:

    • event: A reference to the Event object to be deleted.
  • Example:

Event eventToDelete = ...;
eventPool.deleteEvent(eventToDelete);

Private Methods​

handler()​

void handler(const GDTPHeader &header, const std::vector<uint8_t> &payload, const asio::ip::udp::endpoint &client_endpoint);
  • Description: Handles incoming events from the network. Parses the GDTPHeader and payload to create the appropriate Event object and adds it to the eventQueue.

  • Parameters:

    • header: The GDTPHeader containing metadata about the event.
    • payload: The raw binary data of the event.
    • client_endpoint: The network endpoint of the client sending the event.
  • Note: This method is intended to be used internally and is not directly accessible outside the class.

Usage Examples​

Adding and Retrieving Events​

// Access the singleton instance
EventPool& eventPool = EventPool::getInstance();

// Create an event and add it to the queue
PlayerMovement playerMovement = {1, 100.0f, 200.0f, 0.0f};
Event event(EventType::PlayerMovement, playerMovement);
eventPool.addEvent(event);

// Retrieve the next event from the queue
Event nextEvent = eventPool.getNextEvent();

Handling Multiple Events​

// Retrieve all events and process them
std::vector<Event> events = eventPool.getAllEvents();
for (const Event& event : events) {
// Process each event based on its type
if (event.getType() == EventType::PlayerMovement) {
// Handle player movement
} else if (event.getType() == EventType::PlayerShoot) {
// Handle player shoot
}
}

Using Custom Event Handlers​

// Define a custom event handler
auto customHandler = [](const Event& event) {
std::cout << "Custom event handler called for event type: " << static_cast<int>(event.getType()) << std::endl;
};

// Assign the custom handler to the EventPool
EventPool& eventPool = EventPool::getInstance();
eventPool.setHandler(customHandler);

// Events will now be processed by the custom handler when added

Thread Safety​

  • The EventPool class is designed to be thread-safe, utilizing std::mutex for synchronization.
  • The std::condition_variable ensures that threads waiting for events can be efficiently notified when new events are added.
  • This makes EventPool suitable for use in multi-threaded environments where different threads may produce and consume events.