mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
cscore: Change impl to only one singleton (#1398)
This avoids a number of shutdown use-after-free races by controlling the destruction order. It also is a prerequisite to making the internal interfaces mockable for unit testing.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <wpi/SmallString.h>
|
||||
|
||||
#include "Handle.h"
|
||||
#include "Instance.h"
|
||||
#include "Log.h"
|
||||
#include "Notifier.h"
|
||||
#include "c_util.h"
|
||||
@@ -20,14 +21,17 @@
|
||||
|
||||
using namespace cs;
|
||||
|
||||
CvSinkImpl::CvSinkImpl(const wpi::Twine& name) : SinkImpl{name} {
|
||||
CvSinkImpl::CvSinkImpl(const wpi::Twine& name, wpi::Logger& logger,
|
||||
Notifier& notifier, Telemetry& telemetry)
|
||||
: SinkImpl{name, logger, notifier, telemetry} {
|
||||
m_active = true;
|
||||
// m_thread = std::thread(&CvSinkImpl::ThreadMain, this);
|
||||
}
|
||||
|
||||
CvSinkImpl::CvSinkImpl(const wpi::Twine& name,
|
||||
CvSinkImpl::CvSinkImpl(const wpi::Twine& name, wpi::Logger& logger,
|
||||
Notifier& notifier, Telemetry& telemetry,
|
||||
std::function<void(uint64_t time)> processFrame)
|
||||
: SinkImpl{name} {}
|
||||
: SinkImpl{name, logger, notifier, telemetry} {}
|
||||
|
||||
CvSinkImpl::~CvSinkImpl() { Stop(); }
|
||||
|
||||
@@ -119,24 +123,28 @@ void CvSinkImpl::ThreadMain() {
|
||||
namespace cs {
|
||||
|
||||
CS_Sink CreateCvSink(const wpi::Twine& name, CS_Status* status) {
|
||||
auto sink = std::make_shared<CvSinkImpl>(name);
|
||||
auto handle = Sinks::GetInstance().Allocate(CS_SINK_CV, sink);
|
||||
Notifier::GetInstance().NotifySink(name, handle, CS_SINK_CREATED);
|
||||
auto& inst = Instance::GetInstance();
|
||||
auto sink = std::make_shared<CvSinkImpl>(name, inst.logger, inst.notifier,
|
||||
inst.telemetry);
|
||||
auto handle = inst.sinks.Allocate(CS_SINK_CV, sink);
|
||||
inst.notifier.NotifySink(name, handle, CS_SINK_CREATED);
|
||||
return handle;
|
||||
}
|
||||
|
||||
CS_Sink CreateCvSinkCallback(const wpi::Twine& name,
|
||||
std::function<void(uint64_t time)> processFrame,
|
||||
CS_Status* status) {
|
||||
auto sink = std::make_shared<CvSinkImpl>(name, processFrame);
|
||||
auto handle = Sinks::GetInstance().Allocate(CS_SINK_CV, sink);
|
||||
Notifier::GetInstance().NotifySink(name, handle, CS_SINK_CREATED);
|
||||
auto& inst = Instance::GetInstance();
|
||||
auto sink = std::make_shared<CvSinkImpl>(name, inst.logger, inst.notifier,
|
||||
inst.telemetry, processFrame);
|
||||
auto handle = inst.sinks.Allocate(CS_SINK_CV, sink);
|
||||
inst.notifier.NotifySink(name, handle, CS_SINK_CREATED);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void SetSinkDescription(CS_Sink sink, const wpi::Twine& description,
|
||||
CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
auto data = Instance::GetInstance().sinks.Get(sink);
|
||||
if (!data || data->kind != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return;
|
||||
@@ -145,7 +153,7 @@ void SetSinkDescription(CS_Sink sink, const wpi::Twine& description,
|
||||
}
|
||||
|
||||
uint64_t GrabSinkFrame(CS_Sink sink, cv::Mat& image, CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
auto data = Instance::GetInstance().sinks.Get(sink);
|
||||
if (!data || data->kind != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return 0;
|
||||
@@ -155,7 +163,7 @@ uint64_t GrabSinkFrame(CS_Sink sink, cv::Mat& image, CS_Status* status) {
|
||||
|
||||
uint64_t GrabSinkFrameTimeout(CS_Sink sink, cv::Mat& image, double timeout,
|
||||
CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
auto data = Instance::GetInstance().sinks.Get(sink);
|
||||
if (!data || data->kind != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return 0;
|
||||
@@ -164,7 +172,7 @@ uint64_t GrabSinkFrameTimeout(CS_Sink sink, cv::Mat& image, double timeout,
|
||||
}
|
||||
|
||||
std::string GetSinkError(CS_Sink sink, CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
auto data = Instance::GetInstance().sinks.Get(sink);
|
||||
if (!data || data->kind != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return std::string{};
|
||||
@@ -174,7 +182,7 @@ std::string GetSinkError(CS_Sink sink, CS_Status* status) {
|
||||
|
||||
wpi::StringRef GetSinkError(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
|
||||
CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
auto data = Instance::GetInstance().sinks.Get(sink);
|
||||
if (!data || data->kind != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return wpi::StringRef{};
|
||||
@@ -183,7 +191,7 @@ wpi::StringRef GetSinkError(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
|
||||
}
|
||||
|
||||
void SetSinkEnabled(CS_Sink sink, bool enabled, CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
auto data = Instance::GetInstance().sinks.Get(sink);
|
||||
if (!data || data->kind != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user