Add foundation event dispatcher tests
This commit is contained in:
97
src/foundation/event.cpp
Normal file
97
src/foundation/event.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "foundation/event.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace pp::foundation {
|
||||
|
||||
EventDispatcher::EventDispatcher(std::size_t max_subscriptions) noexcept
|
||||
: max_subscriptions_(max_subscriptions)
|
||||
{
|
||||
subscriptions_.reserve(std::min(max_subscriptions_, max_event_subscriptions));
|
||||
}
|
||||
|
||||
std::size_t EventDispatcher::size() const noexcept
|
||||
{
|
||||
return subscriptions_.size();
|
||||
}
|
||||
|
||||
bool EventDispatcher::empty() const noexcept
|
||||
{
|
||||
return subscriptions_.empty();
|
||||
}
|
||||
|
||||
std::size_t EventDispatcher::max_subscriptions() const noexcept
|
||||
{
|
||||
return max_subscriptions_;
|
||||
}
|
||||
|
||||
Result<std::uint64_t> EventDispatcher::subscribe(std::uint32_t type, EventCallback callback, void* user_data)
|
||||
{
|
||||
if (max_subscriptions_ == 0U || max_subscriptions_ > max_event_subscriptions) {
|
||||
return Result<std::uint64_t>::failure(
|
||||
Status::out_of_range("event dispatcher capacity is outside the configured range"));
|
||||
}
|
||||
|
||||
if (type == 0U) {
|
||||
return Result<std::uint64_t>::failure(Status::invalid_argument("event type must not be zero"));
|
||||
}
|
||||
|
||||
if (callback == nullptr) {
|
||||
return Result<std::uint64_t>::failure(Status::invalid_argument("event callback must not be null"));
|
||||
}
|
||||
|
||||
if (subscriptions_.size() >= max_subscriptions_) {
|
||||
return Result<std::uint64_t>::failure(Status::out_of_range("event dispatcher is full"));
|
||||
}
|
||||
|
||||
const auto id = next_subscription_id_++;
|
||||
subscriptions_.push_back(EventSubscription {
|
||||
.id = id,
|
||||
.type = type,
|
||||
.callback = callback,
|
||||
.user_data = user_data,
|
||||
});
|
||||
|
||||
return Result<std::uint64_t>::success(id);
|
||||
}
|
||||
|
||||
Status EventDispatcher::unsubscribe(std::uint64_t subscription_id) noexcept
|
||||
{
|
||||
const auto found = std::find_if(
|
||||
subscriptions_.begin(),
|
||||
subscriptions_.end(),
|
||||
[subscription_id](const EventSubscription& subscription) {
|
||||
return subscription.id == subscription_id;
|
||||
});
|
||||
|
||||
if (found == subscriptions_.end()) {
|
||||
return Status::out_of_range("event subscription id was not found");
|
||||
}
|
||||
|
||||
subscriptions_.erase(found);
|
||||
return Status::success();
|
||||
}
|
||||
|
||||
std::size_t EventDispatcher::publish(const Event& event) const noexcept
|
||||
{
|
||||
if (event.type == 0U) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t delivered = 0;
|
||||
for (const auto& subscription : subscriptions_) {
|
||||
if (subscription.type == event.type) {
|
||||
subscription.callback(event, subscription.user_data);
|
||||
++delivered;
|
||||
}
|
||||
}
|
||||
|
||||
return delivered;
|
||||
}
|
||||
|
||||
void EventDispatcher::clear() noexcept
|
||||
{
|
||||
subscriptions_.clear();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user