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.
|
2016-09-05 12:00:36 -07:00
|
|
|
|
2025-11-07 19:56:21 -05:00
|
|
|
#include "Instance.hpp"
|
2016-09-05 12:00:36 -07:00
|
|
|
|
2024-09-20 17:43:39 -07:00
|
|
|
#include <memory>
|
2021-06-06 16:13:58 -07:00
|
|
|
#include <string_view>
|
2024-09-20 17:43:39 -07:00
|
|
|
#include <utility>
|
2021-06-06 16:13:58 -07:00
|
|
|
|
|
|
|
|
#include <fmt/format.h>
|
2025-11-07 19:56:21 -05:00
|
|
|
#include "wpi/util/fs.hpp"
|
|
|
|
|
#include "wpi/util/print.hpp"
|
2016-09-05 12:00:36 -07:00
|
|
|
|
|
|
|
|
using namespace cs;
|
|
|
|
|
|
|
|
|
|
static void def_log_func(unsigned int level, const char* file,
|
|
|
|
|
unsigned int line, const char* msg) {
|
|
|
|
|
if (level == 20) {
|
2024-05-12 06:25:42 -07:00
|
|
|
wpi::print(stderr, "CS: {}\n", msg);
|
2016-09-05 12:00:36 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
std::string_view levelmsg;
|
2020-12-28 12:58:06 -08:00
|
|
|
if (level >= 50) {
|
2021-06-06 16:13:58 -07:00
|
|
|
levelmsg = "CRITICAL";
|
2020-12-28 12:58:06 -08:00
|
|
|
} else if (level >= 40) {
|
2021-06-06 16:13:58 -07:00
|
|
|
levelmsg = "ERROR";
|
2020-12-28 12:58:06 -08:00
|
|
|
} else if (level >= 30) {
|
2021-06-06 16:13:58 -07:00
|
|
|
levelmsg = "WARNING";
|
2020-12-28 12:58:06 -08:00
|
|
|
} else {
|
2016-09-05 12:00:36 -07:00
|
|
|
return;
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2024-05-12 06:25:42 -07:00
|
|
|
wpi::print(stderr, "CS: {}: {} ({}:{})\n", levelmsg, msg,
|
2024-09-20 17:43:39 -07:00
|
|
|
// NOLINTNEXTLINE(build/include_what_you_use)
|
2021-06-06 16:13:58 -07:00
|
|
|
fs::path{file}.filename().string(), line);
|
2016-09-05 12:00:36 -07:00
|
|
|
}
|
|
|
|
|
|
2021-01-31 18:52:48 -08:00
|
|
|
Instance::Instance()
|
|
|
|
|
: telemetry(notifier),
|
|
|
|
|
networkListener(logger, notifier),
|
|
|
|
|
usbCameraListener(logger, notifier) {
|
2018-10-31 20:22:58 -07:00
|
|
|
SetDefaultLogger();
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-28 00:37:33 -08:00
|
|
|
Instance::~Instance() = default;
|
2018-10-31 20:22:58 -07:00
|
|
|
|
|
|
|
|
Instance& Instance::GetInstance() {
|
2018-11-07 00:01:27 -08:00
|
|
|
static Instance* inst = new Instance;
|
|
|
|
|
return *inst;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Instance::Shutdown() {
|
|
|
|
|
eventLoop.Stop();
|
|
|
|
|
m_sinks.FreeAll();
|
|
|
|
|
m_sources.FreeAll();
|
|
|
|
|
networkListener.Stop();
|
2021-01-31 18:52:48 -08:00
|
|
|
usbCameraListener.Stop();
|
2018-11-07 00:01:27 -08:00
|
|
|
telemetry.Stop();
|
|
|
|
|
notifier.Stop();
|
2018-10-31 20:22:58 -07:00
|
|
|
}
|
2016-09-05 12:00:36 -07:00
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
void Instance::SetDefaultLogger() {
|
|
|
|
|
logger.SetLogger(def_log_func);
|
|
|
|
|
}
|
2017-02-17 01:12:16 -05:00
|
|
|
|
2018-10-31 20:22:58 -07:00
|
|
|
std::pair<CS_Source, std::shared_ptr<SourceData>> Instance::FindSource(
|
|
|
|
|
const SourceImpl& source) {
|
2018-11-06 19:42:39 -08:00
|
|
|
return m_sources.FindIf(
|
2018-10-31 20:22:58 -07:00
|
|
|
[&](const SourceData& data) { return data.source.get() == &source; });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::pair<CS_Sink, std::shared_ptr<SinkData>> Instance::FindSink(
|
|
|
|
|
const SinkImpl& sink) {
|
2018-11-06 19:42:39 -08:00
|
|
|
return m_sinks.FindIf(
|
2018-10-31 20:22:58 -07:00
|
|
|
[&](const SinkData& data) { return data.sink.get() == &sink; });
|
|
|
|
|
}
|
2018-11-06 19:42:39 -08:00
|
|
|
|
|
|
|
|
CS_Source Instance::CreateSource(CS_SourceKind kind,
|
|
|
|
|
std::shared_ptr<SourceImpl> source) {
|
|
|
|
|
auto handle = m_sources.Allocate(kind, source);
|
|
|
|
|
notifier.NotifySource(source->GetName(), handle, CS_SOURCE_CREATED);
|
|
|
|
|
source->Start();
|
|
|
|
|
return handle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CS_Sink Instance::CreateSink(CS_SinkKind kind, std::shared_ptr<SinkImpl> sink) {
|
|
|
|
|
auto handle = m_sinks.Allocate(kind, sink);
|
|
|
|
|
notifier.NotifySink(sink->GetName(), handle, CS_SINK_CREATED);
|
|
|
|
|
return handle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Instance::DestroySource(CS_Source handle) {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (auto data = m_sources.Free(handle)) {
|
2018-11-06 19:42:39 -08:00
|
|
|
notifier.NotifySource(data->source->GetName(), handle, CS_SOURCE_DESTROYED);
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2018-11-06 19:42:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Instance::DestroySink(CS_Sink handle) {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (auto data = m_sinks.Free(handle)) {
|
2024-10-22 08:02:20 -06:00
|
|
|
if (auto source = data->sink->GetSource()) {
|
|
|
|
|
source->Wakeup();
|
|
|
|
|
}
|
2018-11-06 19:42:39 -08:00
|
|
|
notifier.NotifySink(data->sink->GetName(), handle, CS_SINK_DESTROYED);
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2018-11-06 19:42:39 -08:00
|
|
|
}
|