omni/kit/EventSubscribers.h
File members: omni/kit/EventSubscribers.h
// Copyright (c) 2019-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#include "../../carb/Defines.h"
#include <vector>
namespace carb
{
template <class FuncT, typename SubIdT>
class EventSubscribers
{
public:
SubIdT subscribe(FuncT fn, void* userData)
{
// Search for free slot
size_t index;
bool found = false;
for (size_t i = 0; i < m_subscribers.size(); i++)
{
if (!m_subscribers[i].fn)
{
index = i;
found = true;
break;
}
}
// Add new slot if haven't found a free one
if (!found)
{
m_subscribers.push_back({});
index = m_subscribers.size() - 1;
}
m_subscribers[index] = { fn, userData };
return (SubIdT)index;
}
void unsubscribe(SubIdT id)
{
CARB_ASSERT(id < m_subscribers.size());
m_subscribers[id] = {};
}
template <typename... Ts>
void send(Ts... args)
{
// Iterate by index because subscribers can actually change during iteration (vector can grow)
const size_t kCount = m_subscribers.size();
for (size_t i = 0; i < kCount; i++)
{
auto& subsribers = m_subscribers[i];
if (subsribers.fn)
subsribers.fn(args..., subsribers.userData);
}
}
template <typename... Ts>
void sendForId(uint64_t id, Ts... args)
{
CARB_ASSERT(id < m_subscribers.size());
if (m_subscribers[id].fn)
m_subscribers[id].fn(args..., m_subscribers[id].userData);
}
private:
struct EventData
{
FuncT fn;
void* userData;
};
std::vector<EventData> m_subscribers;
};
} // namespace carb