2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2019-09-14 15:22:54 -05:00
|
|
|
|
2021-06-13 16:38:05 -07:00
|
|
|
#include "wpi/sendable/SendableRegistry.h"
|
2019-09-14 15:22:54 -05:00
|
|
|
|
2019-10-17 22:01:31 -07:00
|
|
|
#include <memory>
|
2024-09-20 17:43:39 -07:00
|
|
|
#include <string>
|
|
|
|
|
#include <utility>
|
2019-10-17 22:01:31 -07:00
|
|
|
|
2023-08-28 15:13:34 -07:00
|
|
|
#include <fmt/format.h>
|
|
|
|
|
|
2021-06-13 16:38:05 -07:00
|
|
|
#include "wpi/DenseMap.h"
|
|
|
|
|
#include "wpi/SmallVector.h"
|
|
|
|
|
#include "wpi/UidVector.h"
|
|
|
|
|
#include "wpi/mutex.h"
|
|
|
|
|
#include "wpi/sendable/Sendable.h"
|
|
|
|
|
#include "wpi/sendable/SendableBuilder.h"
|
2019-09-14 15:22:54 -05:00
|
|
|
|
2021-06-13 16:38:05 -07:00
|
|
|
using namespace wpi;
|
2019-09-14 15:22:54 -05:00
|
|
|
|
2021-06-15 23:06:03 -07:00
|
|
|
namespace {
|
|
|
|
|
struct Component {
|
|
|
|
|
Sendable* sendable = nullptr;
|
|
|
|
|
std::unique_ptr<SendableBuilder> builder;
|
|
|
|
|
std::string name;
|
|
|
|
|
std::string subsystem = "Ungrouped";
|
|
|
|
|
Sendable* parent = nullptr;
|
|
|
|
|
bool liveWindow = false;
|
|
|
|
|
wpi::SmallVector<std::shared_ptr<void>, 2> data;
|
2019-09-14 15:22:54 -05:00
|
|
|
|
2021-06-15 23:06:03 -07:00
|
|
|
void SetName(std::string_view moduleType, int channel) {
|
|
|
|
|
name = fmt::format("{}[{}]", moduleType, channel);
|
|
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
|
2021-06-15 23:06:03 -07:00
|
|
|
void SetName(std::string_view moduleType, int moduleNumber, int channel) {
|
|
|
|
|
name = fmt::format("{}[{},{}]", moduleType, moduleNumber, channel);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct SendableRegistryInst {
|
2019-11-25 21:47:06 -08:00
|
|
|
wpi::recursive_mutex mutex;
|
2019-09-14 15:22:54 -05:00
|
|
|
|
2021-06-13 16:38:05 -07:00
|
|
|
std::function<std::unique_ptr<SendableBuilder>()> liveWindowFactory;
|
2019-10-17 22:01:31 -07:00
|
|
|
wpi::UidVector<std::unique_ptr<Component>, 32> components;
|
2021-06-15 23:06:03 -07:00
|
|
|
wpi::DenseMap<void*, SendableRegistry::UID> componentMap;
|
2019-09-14 15:22:54 -05:00
|
|
|
int nextDataHandle = 0;
|
|
|
|
|
|
2021-06-15 23:06:03 -07:00
|
|
|
Component& GetOrAdd(void* sendable, SendableRegistry::UID* uid = nullptr);
|
2019-09-14 15:22:54 -05:00
|
|
|
};
|
2021-06-15 23:06:03 -07:00
|
|
|
} // namespace
|
2019-09-14 15:22:54 -05:00
|
|
|
|
2021-06-15 23:06:03 -07:00
|
|
|
Component& SendableRegistryInst::GetOrAdd(void* sendable,
|
|
|
|
|
SendableRegistry::UID* uid) {
|
|
|
|
|
SendableRegistry::UID& compUid = componentMap[sendable];
|
2020-12-28 12:58:06 -08:00
|
|
|
if (compUid == 0) {
|
2019-10-17 22:01:31 -07:00
|
|
|
compUid = components.emplace_back(std::make_unique<Component>()) + 1;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
|
|
|
|
if (uid) {
|
|
|
|
|
*uid = compUid;
|
|
|
|
|
}
|
2019-10-17 22:01:31 -07:00
|
|
|
|
|
|
|
|
return *components[compUid - 1];
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2022-02-10 01:14:12 -05:00
|
|
|
static std::unique_ptr<SendableRegistryInst>& GetInstanceHolder() {
|
|
|
|
|
static std::unique_ptr<SendableRegistryInst> instance =
|
|
|
|
|
std::make_unique<SendableRegistryInst>();
|
2019-09-14 15:22:54 -05:00
|
|
|
return instance;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-10 01:14:12 -05:00
|
|
|
static SendableRegistryInst& GetInstance() {
|
|
|
|
|
return *GetInstanceHolder();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef __FRC_ROBORIO__
|
|
|
|
|
namespace wpi::impl {
|
|
|
|
|
void ResetSendableRegistry() {
|
|
|
|
|
std::make_unique<SendableRegistryInst>().swap(GetInstanceHolder());
|
|
|
|
|
}
|
|
|
|
|
} // namespace wpi::impl
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-06-13 16:38:05 -07:00
|
|
|
void SendableRegistry::SetLiveWindowBuilderFactory(
|
|
|
|
|
std::function<std::unique_ptr<SendableBuilder>()> factory) {
|
2021-06-15 23:06:03 -07:00
|
|
|
GetInstance().liveWindowFactory = std::move(factory);
|
2021-06-13 16:38:05 -07:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::Add(Sendable* sendable, std::string_view name) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(sendable);
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = sendable;
|
2021-05-26 17:44:18 -07:00
|
|
|
comp.name = name;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::Add(Sendable* sendable, std::string_view moduleType,
|
2019-09-14 15:22:54 -05:00
|
|
|
int channel) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(sendable);
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = sendable;
|
2019-09-14 15:22:54 -05:00
|
|
|
comp.SetName(moduleType, channel);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::Add(Sendable* sendable, std::string_view moduleType,
|
2019-09-14 15:22:54 -05:00
|
|
|
int moduleNumber, int channel) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(sendable);
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = sendable;
|
2019-09-14 15:22:54 -05:00
|
|
|
comp.SetName(moduleType, moduleNumber, channel);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::Add(Sendable* sendable, std::string_view subsystem,
|
|
|
|
|
std::string_view name) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(sendable);
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = sendable;
|
2021-05-26 17:44:18 -07:00
|
|
|
comp.name = name;
|
|
|
|
|
comp.subsystem = subsystem;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::AddLW(Sendable* sendable, std::string_view name) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(sendable);
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = sendable;
|
2021-06-15 23:06:03 -07:00
|
|
|
if (inst.liveWindowFactory) {
|
|
|
|
|
comp.builder = inst.liveWindowFactory();
|
2021-06-13 16:38:05 -07:00
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
comp.liveWindow = true;
|
2021-05-26 17:44:18 -07:00
|
|
|
comp.name = name;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::AddLW(Sendable* sendable, std::string_view moduleType,
|
2019-09-14 15:22:54 -05:00
|
|
|
int channel) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(sendable);
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = sendable;
|
2021-06-15 23:06:03 -07:00
|
|
|
if (inst.liveWindowFactory) {
|
|
|
|
|
comp.builder = inst.liveWindowFactory();
|
2021-06-13 16:38:05 -07:00
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
comp.liveWindow = true;
|
|
|
|
|
comp.SetName(moduleType, channel);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::AddLW(Sendable* sendable, std::string_view moduleType,
|
2019-09-14 15:22:54 -05:00
|
|
|
int moduleNumber, int channel) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(sendable);
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = sendable;
|
2021-06-15 23:06:03 -07:00
|
|
|
if (inst.liveWindowFactory) {
|
|
|
|
|
comp.builder = inst.liveWindowFactory();
|
2021-06-13 16:38:05 -07:00
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
comp.liveWindow = true;
|
|
|
|
|
comp.SetName(moduleType, moduleNumber, channel);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::AddLW(Sendable* sendable, std::string_view subsystem,
|
|
|
|
|
std::string_view name) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(sendable);
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = sendable;
|
2021-06-15 23:06:03 -07:00
|
|
|
if (inst.liveWindowFactory) {
|
|
|
|
|
comp.builder = inst.liveWindowFactory();
|
2021-06-13 16:38:05 -07:00
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
comp.liveWindow = true;
|
2021-05-26 17:44:18 -07:00
|
|
|
comp.name = name;
|
|
|
|
|
comp.subsystem = subsystem;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2019-12-29 23:37:14 -06:00
|
|
|
void SendableRegistry::AddChild(Sendable* parent, Sendable* child) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(child);
|
2019-12-29 23:37:14 -06:00
|
|
|
comp.parent = parent;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-14 15:22:54 -05:00
|
|
|
void SendableRegistry::AddChild(Sendable* parent, void* child) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto& comp = inst.GetOrAdd(child);
|
2019-09-14 15:22:54 -05:00
|
|
|
comp.parent = parent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SendableRegistry::Remove(Sendable* sendable) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end()) {
|
2020-12-28 12:58:06 -08:00
|
|
|
return false;
|
|
|
|
|
}
|
2019-10-17 22:01:31 -07:00
|
|
|
UID compUid = it->getSecond();
|
2021-06-15 23:06:03 -07:00
|
|
|
inst.components.erase(compUid - 1);
|
|
|
|
|
inst.componentMap.erase(it);
|
2019-12-29 23:37:14 -06:00
|
|
|
// update any parent pointers
|
2021-06-15 23:06:03 -07:00
|
|
|
for (auto&& comp : inst.components) {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (comp->parent == sendable) {
|
|
|
|
|
comp->parent = nullptr;
|
|
|
|
|
}
|
2019-12-29 23:37:14 -06:00
|
|
|
}
|
2019-10-17 22:01:31 -07:00
|
|
|
return true;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendableRegistry::Move(Sendable* to, Sendable* from) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(from);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2019-10-17 22:01:31 -07:00
|
|
|
UID compUid = it->getSecond();
|
2021-06-15 23:06:03 -07:00
|
|
|
inst.componentMap.erase(it);
|
|
|
|
|
inst.componentMap[to] = compUid;
|
|
|
|
|
auto& comp = *inst.components[compUid - 1];
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = to;
|
2021-06-13 16:38:05 -07:00
|
|
|
if (comp.builder && comp.builder->IsPublished()) {
|
2019-10-17 22:01:31 -07:00
|
|
|
// rebuild builder, as lambda captures can point to "from"
|
2021-06-13 16:38:05 -07:00
|
|
|
comp.builder->ClearProperties();
|
|
|
|
|
to->InitSendable(*comp.builder);
|
2019-10-17 22:01:31 -07:00
|
|
|
}
|
2019-12-29 23:37:14 -06:00
|
|
|
// update any parent pointers
|
2021-06-15 23:06:03 -07:00
|
|
|
for (auto&& comp : inst.components) {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (comp->parent == from) {
|
|
|
|
|
comp->parent = to;
|
|
|
|
|
}
|
2019-12-29 23:37:14 -06:00
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-06-15 23:06:03 -07:00
|
|
|
bool SendableRegistry::Contains(const Sendable* sendable) {
|
|
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
return inst.componentMap.count(sendable) != 0;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-06-15 23:06:03 -07:00
|
|
|
std::string SendableRegistry::GetName(const Sendable* sendable) {
|
|
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-12-28 12:58:06 -08:00
|
|
|
return {};
|
|
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
return inst.components[it->getSecond() - 1]->name;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::SetName(Sendable* sendable, std::string_view name) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
inst.components[it->getSecond() - 1]->name = name;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::SetName(Sendable* sendable, std::string_view moduleType,
|
2019-09-14 15:22:54 -05:00
|
|
|
int channel) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
inst.components[it->getSecond() - 1]->SetName(moduleType, channel);
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::SetName(Sendable* sendable, std::string_view moduleType,
|
2019-09-14 15:22:54 -05:00
|
|
|
int moduleNumber, int channel) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
inst.components[it->getSecond() - 1]->SetName(moduleType, moduleNumber,
|
|
|
|
|
channel);
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void SendableRegistry::SetName(Sendable* sendable, std::string_view subsystem,
|
|
|
|
|
std::string_view name) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& comp = *inst.components[it->getSecond() - 1];
|
2021-05-26 17:44:18 -07:00
|
|
|
comp.name = name;
|
|
|
|
|
comp.subsystem = subsystem;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
2021-06-15 23:06:03 -07:00
|
|
|
std::string SendableRegistry::GetSubsystem(const Sendable* sendable) {
|
|
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-12-28 12:58:06 -08:00
|
|
|
return {};
|
|
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
return inst.components[it->getSecond() - 1]->subsystem;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendableRegistry::SetSubsystem(Sendable* sendable,
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view subsystem) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
inst.components[it->getSecond() - 1]->subsystem = subsystem;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int SendableRegistry::GetDataHandle() {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
return inst.nextDataHandle++;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<void> SendableRegistry::SetData(Sendable* sendable, int handle,
|
|
|
|
|
std::shared_ptr<void> data) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
2019-09-14 15:22:54 -05:00
|
|
|
assert(handle >= 0);
|
2021-06-15 23:06:03 -07:00
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return nullptr;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& comp = *inst.components[it->getSecond() - 1];
|
2019-09-14 15:22:54 -05:00
|
|
|
std::shared_ptr<void> rv;
|
2020-12-28 12:58:06 -08:00
|
|
|
if (static_cast<size_t>(handle) < comp.data.size()) {
|
2019-09-14 15:22:54 -05:00
|
|
|
rv = std::move(comp.data[handle]);
|
2020-12-28 12:58:06 -08:00
|
|
|
} else {
|
2019-09-14 15:22:54 -05:00
|
|
|
comp.data.resize(handle + 1);
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
comp.data[handle] = std::move(data);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<void> SendableRegistry::GetData(Sendable* sendable,
|
|
|
|
|
int handle) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
2019-09-14 15:22:54 -05:00
|
|
|
assert(handle >= 0);
|
2021-06-15 23:06:03 -07:00
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return nullptr;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& comp = *inst.components[it->getSecond() - 1];
|
2020-12-28 12:58:06 -08:00
|
|
|
if (static_cast<size_t>(handle) >= comp.data.size()) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
return comp.data[handle];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendableRegistry::EnableLiveWindow(Sendable* sendable) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
inst.components[it->getSecond() - 1]->liveWindow = true;
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendableRegistry::DisableLiveWindow(Sendable* sendable) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
auto it = inst.componentMap.find(sendable);
|
|
|
|
|
if (it == inst.componentMap.end() || !inst.components[it->getSecond() - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
inst.components[it->getSecond() - 1]->liveWindow = false;
|
2019-10-17 22:01:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SendableRegistry::UID SendableRegistry::GetUniqueId(Sendable* sendable) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
2019-10-17 22:01:31 -07:00
|
|
|
UID uid;
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& comp = inst.GetOrAdd(sendable, &uid);
|
2019-10-17 22:01:31 -07:00
|
|
|
comp.sendable = sendable;
|
|
|
|
|
return uid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Sendable* SendableRegistry::GetSendable(UID uid) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
2020-12-28 12:58:06 -08:00
|
|
|
if (uid == 0) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
if ((uid - 1) >= inst.components.size() || !inst.components[uid - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return nullptr;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
return inst.components[uid - 1]->sendable;
|
2019-10-17 22:01:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendableRegistry::Publish(UID sendableUid,
|
2021-06-13 16:38:05 -07:00
|
|
|
std::unique_ptr<SendableBuilder> builder) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
|
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
if (sendableUid == 0 || (sendableUid - 1) >= inst.components.size() ||
|
|
|
|
|
!inst.components[sendableUid - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& comp = *inst.components[sendableUid - 1];
|
2021-06-13 16:38:05 -07:00
|
|
|
comp.builder = std::move(builder); // clear any current builder
|
|
|
|
|
comp.sendable->InitSendable(*comp.builder);
|
|
|
|
|
comp.builder->Update();
|
2019-10-17 22:01:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendableRegistry::Update(UID sendableUid) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto& inst = GetInstance();
|
2020-12-28 12:58:06 -08:00
|
|
|
if (sendableUid == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
if ((sendableUid - 1) >= inst.components.size() ||
|
|
|
|
|
!inst.components[sendableUid - 1]) {
|
2020-11-02 18:12:40 -08:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2021-06-15 23:06:03 -07:00
|
|
|
if (inst.components[sendableUid - 1]->builder) {
|
|
|
|
|
inst.components[sendableUid - 1]->builder->Update();
|
2021-06-13 16:38:05 -07:00
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendableRegistry::ForeachLiveWindow(
|
2021-06-15 23:06:03 -07:00
|
|
|
int dataHandle, wpi::function_ref<void(CallbackData& data)> callback) {
|
|
|
|
|
auto& inst = GetInstance();
|
2019-09-14 15:22:54 -05:00
|
|
|
assert(dataHandle >= 0);
|
2021-06-15 23:06:03 -07:00
|
|
|
std::scoped_lock lock(inst.mutex);
|
|
|
|
|
wpi::SmallVector<Component*, 128> components;
|
|
|
|
|
for (auto&& comp : inst.components) {
|
2020-12-28 12:58:06 -08:00
|
|
|
components.emplace_back(comp.get());
|
|
|
|
|
}
|
2019-11-25 21:47:06 -08:00
|
|
|
for (auto comp : components) {
|
2021-06-13 16:38:05 -07:00
|
|
|
if (comp && comp->builder && comp->sendable && comp->liveWindow) {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (static_cast<size_t>(dataHandle) >= comp->data.size()) {
|
2019-10-17 22:01:31 -07:00
|
|
|
comp->data.resize(dataHandle + 1);
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2019-10-17 22:01:31 -07:00
|
|
|
CallbackData cbdata{comp->sendable, comp->name,
|
|
|
|
|
comp->subsystem, comp->parent,
|
2021-06-13 16:38:05 -07:00
|
|
|
comp->data[dataHandle], *comp->builder};
|
2019-10-17 22:01:31 -07:00
|
|
|
callback(cbdata);
|
2019-09-14 15:22:54 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|