// Copyright 2023 Embedded Artistry LLC
// SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License
#ifndef EVENT_QUEUE_INTERFACE_HPP_
#define EVENT_QUEUE_INTERFACE_HPP_

#include <event_base_types.hpp>
#include "CallbackDispatcher.hpp"

/// These events must be implemented as desired for your application.
/// In common implementations, you will:
/// - declare a single event queue
/// - implement the operations below by interacting with the event queue
/// - add any locks or other protection (e.g., disabling interrupts) to make it
/// 	safe to work with the queue from interrupts or other threads
namespace CentralEventQueue {

/// Add an event to the queue
/// This should be implemented by calling emplace() on the
/// specific event queue type for your application
void enqueue(const event_t& event);

/// Add a function (e.g., a callback) to the event queue
/// This should be implemented by calling emplace() on the
/// specific event queue type for your application
void enqueue(std::function<void(void)> func);

/// Convenience alias for registering a callback
inline void callback(std::function<void(void)> func)
{
	enqueue(func);
}

/// Get a reference to the next event in the system
/// This should be implemented by calling front() on the
/// specific event queue type for your application
const event_t& front();

/// Remove the front element from the queue
/// This should be implemented by calling pop() on the specific
/// event queue type for your application.
void pop();

/// Returns true if the queue is empty
/// This should be implemented by calling empty() on the specific
/// event queue type for your application.
bool empty();

/// Process all callbacks in the queue, stopping when the first non-Callable
/// event is found.
void processCallbacks();

} // CentralEventQueue

#endif // EVENT_API_HPP_
