diff --git a/cscore/src/main/native/cpp/CvSinkImpl.cpp b/cscore/src/main/native/cpp/CvSinkImpl.cpp index 3f2d902f23..7b422f7332 100644 --- a/cscore/src/main/native/cpp/CvSinkImpl.cpp +++ b/cscore/src/main/native/cpp/CvSinkImpl.cpp @@ -13,6 +13,7 @@ #include #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 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(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(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 processFrame, CS_Status* status) { - auto sink = std::make_shared(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(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& 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& 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; diff --git a/cscore/src/main/native/cpp/CvSinkImpl.h b/cscore/src/main/native/cpp/CvSinkImpl.h index 36452dbe85..9b7820f4bb 100644 --- a/cscore/src/main/native/cpp/CvSinkImpl.h +++ b/cscore/src/main/native/cpp/CvSinkImpl.h @@ -8,20 +8,17 @@ #ifndef CSCORE_CVSINKIMPL_H_ #define CSCORE_CVSINKIMPL_H_ +#include + #include -#include +#include #include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include +#include +#include "Frame.h" #include "SinkImpl.h" namespace cs { @@ -30,8 +27,10 @@ class SourceImpl; class CvSinkImpl : public SinkImpl { public: - explicit CvSinkImpl(const wpi::Twine& name); - CvSinkImpl(const wpi::Twine& name, + CvSinkImpl(const wpi::Twine& name, wpi::Logger& logger, Notifier& notifier, + Telemetry& telemetry); + CvSinkImpl(const wpi::Twine& name, wpi::Logger& logger, Notifier& notifier, + Telemetry& telemetry, std::function processFrame); ~CvSinkImpl() override; diff --git a/cscore/src/main/native/cpp/CvSourceImpl.cpp b/cscore/src/main/native/cpp/CvSourceImpl.cpp index cf3c845a51..97b56dc565 100644 --- a/cscore/src/main/native/cpp/CvSourceImpl.cpp +++ b/cscore/src/main/native/cpp/CvSourceImpl.cpp @@ -14,6 +14,7 @@ #include #include "Handle.h" +#include "Instance.h" #include "Log.h" #include "Notifier.h" #include "c_util.h" @@ -21,8 +22,10 @@ using namespace cs; -CvSourceImpl::CvSourceImpl(const wpi::Twine& name, const VideoMode& mode) - : SourceImpl{name} { +CvSourceImpl::CvSourceImpl(const wpi::Twine& name, wpi::Logger& logger, + Notifier& notifier, Telemetry& telemetry, + const VideoMode& mode) + : SourceImpl{name, logger, notifier, telemetry} { m_mode = mode; m_videoModes.push_back(m_mode); } @@ -37,7 +40,7 @@ bool CvSourceImpl::SetVideoMode(const VideoMode& mode, CS_Status* status) { m_mode = mode; m_videoModes[0] = mode; } - Notifier::GetInstance().NotifySourceVideoMode(*this, mode); + m_notifier.NotifySourceVideoMode(*this, mode); return true; } @@ -105,8 +108,8 @@ int CvSourceImpl::CreateProperty(const wpi::Twine& name, CS_PropertyKind kind, prop.defaultValue = defaultValue; value = prop.value; }); - Notifier::GetInstance().NotifySourceProperty( - *this, CS_SOURCE_PROPERTY_CREATED, name, ndx, kind, value, wpi::Twine{}); + m_notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_CREATED, name, ndx, + kind, value, wpi::Twine{}); return ndx; } @@ -132,29 +135,30 @@ void CvSourceImpl::SetEnumPropertyChoices(int property, return; } prop->enumChoices = choices; - Notifier::GetInstance().NotifySourceProperty( - *this, CS_SOURCE_PROPERTY_CHOICES_UPDATED, prop->name, property, - CS_PROP_ENUM, prop->value, wpi::Twine{}); + m_notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_CHOICES_UPDATED, + prop->name, property, CS_PROP_ENUM, + prop->value, wpi::Twine{}); } namespace cs { CS_Source CreateCvSource(const wpi::Twine& name, const VideoMode& mode, CS_Status* status) { - auto source = std::make_shared(name, mode); - auto handle = Sources::GetInstance().Allocate(CS_SOURCE_CV, source); - auto& notifier = Notifier::GetInstance(); - notifier.NotifySource(name, handle, CS_SOURCE_CREATED); + auto& inst = Instance::GetInstance(); + auto source = std::make_shared(name, inst.logger, inst.notifier, + inst.telemetry, mode); + auto handle = inst.sources.Allocate(CS_SOURCE_CV, source); + inst.notifier.NotifySource(name, handle, CS_SOURCE_CREATED); // Generate initial events here so they come after the source created event source->Start(); // causes a property event - notifier.NotifySource(name, handle, CS_SOURCE_CONNECTED); - notifier.NotifySource(name, handle, CS_SOURCE_VIDEOMODES_UPDATED); - notifier.NotifySourceVideoMode(*source, mode); + inst.notifier.NotifySource(name, handle, CS_SOURCE_CONNECTED); + inst.notifier.NotifySource(name, handle, CS_SOURCE_VIDEOMODES_UPDATED); + inst.notifier.NotifySourceVideoMode(*source, mode); return handle; } void PutSourceFrame(CS_Source source, cv::Mat& image, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_CV) { *status = CS_INVALID_HANDLE; return; @@ -164,7 +168,7 @@ void PutSourceFrame(CS_Source source, cv::Mat& image, CS_Status* status) { void NotifySourceError(CS_Source source, const wpi::Twine& msg, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_CV) { *status = CS_INVALID_HANDLE; return; @@ -173,7 +177,7 @@ void NotifySourceError(CS_Source source, const wpi::Twine& msg, } void SetSourceConnected(CS_Source source, bool connected, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_CV) { *status = CS_INVALID_HANDLE; return; @@ -183,7 +187,7 @@ void SetSourceConnected(CS_Source source, bool connected, CS_Status* status) { void SetSourceDescription(CS_Source source, const wpi::Twine& description, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_CV) { *status = CS_INVALID_HANDLE; return; @@ -195,7 +199,7 @@ CS_Property CreateSourceProperty(CS_Source source, const wpi::Twine& name, CS_PropertyKind kind, int minimum, int maximum, int step, int defaultValue, int value, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_CV) { *status = CS_INVALID_HANDLE; return -1; @@ -210,7 +214,7 @@ CS_Property CreateSourcePropertyCallback( CS_Source source, const wpi::Twine& name, CS_PropertyKind kind, int minimum, int maximum, int step, int defaultValue, int value, std::function onChange, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_CV) { *status = CS_INVALID_HANDLE; return -1; @@ -224,7 +228,7 @@ CS_Property CreateSourcePropertyCallback( void SetSourceEnumPropertyChoices(CS_Source source, CS_Property property, wpi::ArrayRef choices, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_CV) { *status = CS_INVALID_HANDLE; return; @@ -237,7 +241,7 @@ void SetSourceEnumPropertyChoices(CS_Source source, CS_Property property, *status = CS_INVALID_HANDLE; return; } - auto data2 = Sources::GetInstance().Get(Handle{i, Handle::kSource}); + auto data2 = Instance::GetInstance().sources.Get(Handle{i, Handle::kSource}); if (!data2 || data->source.get() != data2->source.get()) { *status = CS_INVALID_HANDLE; return; diff --git a/cscore/src/main/native/cpp/CvSourceImpl.h b/cscore/src/main/native/cpp/CvSourceImpl.h index 4de1bcb3a4..c5f06d42ac 100644 --- a/cscore/src/main/native/cpp/CvSourceImpl.h +++ b/cscore/src/main/native/cpp/CvSourceImpl.h @@ -14,13 +14,18 @@ #include #include +#include +#include +#include + #include "SourceImpl.h" namespace cs { class CvSourceImpl : public SourceImpl { public: - CvSourceImpl(const wpi::Twine& name, const VideoMode& mode); + CvSourceImpl(const wpi::Twine& name, wpi::Logger& logger, Notifier& notifier, + Telemetry& telemetry, const VideoMode& mode); ~CvSourceImpl() override; void Start(); diff --git a/cscore/src/main/native/cpp/Frame.cpp b/cscore/src/main/native/cpp/Frame.cpp index 68edfe49c3..15f9b2d28e 100644 --- a/cscore/src/main/native/cpp/Frame.cpp +++ b/cscore/src/main/native/cpp/Frame.cpp @@ -13,6 +13,7 @@ #include #include +#include "Instance.h" #include "Log.h" #include "SourceImpl.h" @@ -450,9 +451,11 @@ Image* Frame::GetImageImpl(int width, int height, if (!cur || cur->Is(width, height, pixelFormat, requiredJpegQuality)) return cur; - DEBUG4("converting image from " - << cur->width << "x" << cur->height << " type " << cur->pixelFormat - << " to " << width << "x" << height << " type " << pixelFormat); + WPI_DEBUG4(Instance::GetInstance().logger, + "converting image from " << cur->width << "x" << cur->height + << " type " << cur->pixelFormat << " to " + << width << "x" << height << " type " + << pixelFormat); // If the source image is a JPEG, we need to decode it before we can do // anything else with it. Note that if the destination format is JPEG, we diff --git a/cscore/src/main/native/cpp/Handle.h b/cscore/src/main/native/cpp/Handle.h index a6449029b7..ebb3a5514f 100644 --- a/cscore/src/main/native/cpp/Handle.h +++ b/cscore/src/main/native/cpp/Handle.h @@ -8,20 +8,10 @@ #ifndef CSCORE_HANDLE_H_ #define CSCORE_HANDLE_H_ -#include -#include -#include - -#include - -#include "UnlimitedHandleResource.h" #include "cscore_c.h" namespace cs { -class SinkImpl; -class SourceImpl; - // Handle data layout: // Bits 0-15: Handle index // Bits 16-23: Parent index (property only) @@ -74,59 +64,6 @@ class Handle { CS_Handle m_handle; }; -struct SourceData { - SourceData(CS_SourceKind kind_, std::shared_ptr source_) - : kind{kind_}, refCount{0}, source{source_} {} - - CS_SourceKind kind; - std::atomic_int refCount; - std::shared_ptr source; -}; - -class Sources - : public UnlimitedHandleResource { - public: - static Sources& GetInstance() { - static Sources instance; - return instance; - } - - std::pair> Find( - const SourceImpl& source) { - return FindIf( - [&](const SourceData& data) { return data.source.get() == &source; }); - } - - private: - Sources() = default; -}; - -struct SinkData { - explicit SinkData(CS_SinkKind kind_, std::shared_ptr sink_) - : kind{kind_}, refCount{0}, sourceHandle{0}, sink{sink_} {} - - CS_SinkKind kind; - std::atomic_int refCount; - std::atomic sourceHandle; - std::shared_ptr sink; -}; - -class Sinks : public UnlimitedHandleResource { - public: - static Sinks& GetInstance() { - static Sinks instance; - return instance; - } - - std::pair> Find(const SinkImpl& sink) { - return FindIf( - [&](const SinkData& data) { return data.sink.get() == &sink; }); - } - - private: - Sinks() = default; -}; - } // namespace cs #endif // CSCORE_HANDLE_H_ diff --git a/cscore/src/main/native/cpp/HttpCameraImpl.cpp b/cscore/src/main/native/cpp/HttpCameraImpl.cpp index 464be8dede..143f2c5f5d 100644 --- a/cscore/src/main/native/cpp/HttpCameraImpl.cpp +++ b/cscore/src/main/native/cpp/HttpCameraImpl.cpp @@ -13,6 +13,7 @@ #include #include "Handle.h" +#include "Instance.h" #include "JpegUtil.h" #include "Log.h" #include "Notifier.h" @@ -21,8 +22,10 @@ using namespace cs; -HttpCameraImpl::HttpCameraImpl(const wpi::Twine& name, CS_HttpCameraKind kind) - : SourceImpl{name}, m_kind{kind} {} +HttpCameraImpl::HttpCameraImpl(const wpi::Twine& name, CS_HttpCameraKind kind, + wpi::Logger& logger, Notifier& notifier, + Telemetry& telemetry) + : SourceImpl{name, logger, notifier, telemetry}, m_kind{kind} {} HttpCameraImpl::~HttpCameraImpl() { m_active = false; @@ -106,8 +109,8 @@ wpi::HttpConnection* HttpCameraImpl::DeviceStreamConnect( } // Try to connect - auto stream = wpi::TCPConnector::connect(req.host.c_str(), req.port, - Logger::GetInstance(), 1); + auto stream = + wpi::TCPConnector::connect(req.host.c_str(), req.port, m_logger, 1); if (!m_active || !stream) return nullptr; @@ -268,8 +271,8 @@ void HttpCameraImpl::SettingsThreadMain() { void HttpCameraImpl::DeviceSendSettings(wpi::HttpRequest& req) { // Try to connect - auto stream = wpi::TCPConnector::connect(req.host.c_str(), req.port, - Logger::GetInstance(), 1); + auto stream = + wpi::TCPConnector::connect(req.host.c_str(), req.port, m_logger, 1); if (!m_active || !stream) return; @@ -332,9 +335,9 @@ void HttpCameraImpl::CreateProperty(const wpi::Twine& name, name, httpParam, viaSettings, kind, minimum, maximum, step, defaultValue, value)); - Notifier::GetInstance().NotifySourceProperty( - *this, CS_SOURCE_PROPERTY_CREATED, name, m_propertyData.size() + 1, kind, - value, wpi::Twine{}); + m_notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_CREATED, name, + m_propertyData.size() + 1, kind, value, + wpi::Twine{}); } template @@ -350,12 +353,12 @@ void HttpCameraImpl::CreateEnumProperty( enumChoices.clear(); for (const auto& choice : choices) enumChoices.emplace_back(choice); - Notifier::GetInstance().NotifySourceProperty( - *this, CS_SOURCE_PROPERTY_CREATED, name, m_propertyData.size() + 1, - CS_PROP_ENUM, value, wpi::Twine{}); - Notifier::GetInstance().NotifySourceProperty( - *this, CS_SOURCE_PROPERTY_CHOICES_UPDATED, name, - m_propertyData.size() + 1, CS_PROP_ENUM, value, wpi::Twine{}); + m_notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_CREATED, name, + m_propertyData.size() + 1, CS_PROP_ENUM, + value, wpi::Twine{}); + m_notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_CHOICES_UPDATED, + name, m_propertyData.size() + 1, CS_PROP_ENUM, + value, wpi::Twine{}); } std::unique_ptr HttpCameraImpl::CreateEmptyProperty( @@ -466,19 +469,21 @@ namespace cs { CS_Source CreateHttpCamera(const wpi::Twine& name, const wpi::Twine& url, CS_HttpCameraKind kind, CS_Status* status) { + auto& inst = Instance::GetInstance(); std::shared_ptr source; switch (kind) { case CS_HTTP_AXIS: - source = std::make_shared(name); + source = std::make_shared(name, inst.logger, + inst.notifier, inst.telemetry); break; default: - source = std::make_shared(name, kind); + source = std::make_shared(name, kind, inst.logger, + inst.notifier, inst.telemetry); break; } if (!source->SetUrls(url.str(), status)) return 0; - auto handle = Sources::GetInstance().Allocate(CS_SOURCE_HTTP, source); - auto& notifier = Notifier::GetInstance(); - notifier.NotifySource(name, handle, CS_SOURCE_CREATED); + auto handle = inst.sources.Allocate(CS_SOURCE_HTTP, source); + inst.notifier.NotifySource(name, handle, CS_SOURCE_CREATED); source->Start(); return handle; } @@ -486,21 +491,22 @@ CS_Source CreateHttpCamera(const wpi::Twine& name, const wpi::Twine& url, CS_Source CreateHttpCamera(const wpi::Twine& name, wpi::ArrayRef urls, CS_HttpCameraKind kind, CS_Status* status) { + auto& inst = Instance::GetInstance(); if (urls.empty()) { *status = CS_EMPTY_VALUE; return 0; } - auto source = std::make_shared(name, kind); + auto source = std::make_shared(name, kind, inst.logger, + inst.notifier, inst.telemetry); if (!source->SetUrls(urls, status)) return 0; - auto handle = Sources::GetInstance().Allocate(CS_SOURCE_HTTP, source); - auto& notifier = Notifier::GetInstance(); - notifier.NotifySource(name, handle, CS_SOURCE_CREATED); + auto handle = inst.sources.Allocate(CS_SOURCE_HTTP, source); + inst.notifier.NotifySource(name, handle, CS_SOURCE_CREATED); source->Start(); return handle; } CS_HttpCameraKind GetHttpCameraKind(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_HTTP) { *status = CS_INVALID_HANDLE; return CS_HTTP_UNKNOWN; @@ -514,7 +520,7 @@ void SetHttpCameraUrls(CS_Source source, wpi::ArrayRef urls, *status = CS_EMPTY_VALUE; return; } - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_HTTP) { *status = CS_INVALID_HANDLE; return; @@ -524,7 +530,7 @@ void SetHttpCameraUrls(CS_Source source, wpi::ArrayRef urls, std::vector GetHttpCameraUrls(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_HTTP) { *status = CS_INVALID_HANDLE; return std::vector{}; diff --git a/cscore/src/main/native/cpp/HttpCameraImpl.h b/cscore/src/main/native/cpp/HttpCameraImpl.h index 201aebd855..f39d153cbf 100644 --- a/cscore/src/main/native/cpp/HttpCameraImpl.h +++ b/cscore/src/main/native/cpp/HttpCameraImpl.h @@ -30,7 +30,8 @@ namespace cs { class HttpCameraImpl : public SourceImpl { public: - HttpCameraImpl(const wpi::Twine& name, CS_HttpCameraKind kind); + HttpCameraImpl(const wpi::Twine& name, CS_HttpCameraKind kind, + wpi::Logger& logger, Notifier& notifier, Telemetry& telemetry); ~HttpCameraImpl() override; void Start(); @@ -140,8 +141,9 @@ class HttpCameraImpl : public SourceImpl { class AxisCameraImpl : public HttpCameraImpl { public: - explicit AxisCameraImpl(const wpi::Twine& name) - : HttpCameraImpl{name, CS_HTTP_AXIS} {} + AxisCameraImpl(const wpi::Twine& name, wpi::Logger& logger, + Notifier& notifier, Telemetry& telemetry) + : HttpCameraImpl{name, CS_HTTP_AXIS, logger, notifier, telemetry} {} #if 0 void SetProperty(int property, int value, CS_Status* status) override; void SetStringProperty(int property, const wpi::Twine& value, diff --git a/cscore/src/main/native/cpp/Log.cpp b/cscore/src/main/native/cpp/Instance.cpp similarity index 64% rename from cscore/src/main/native/cpp/Log.cpp rename to cscore/src/main/native/cpp/Instance.cpp index 06bdfbb758..6ee362a5bc 100644 --- a/cscore/src/main/native/cpp/Log.cpp +++ b/cscore/src/main/native/cpp/Instance.cpp @@ -5,7 +5,7 @@ /* the project. */ /*----------------------------------------------------------------------------*/ -#include "Log.h" +#include "Instance.h" #include #include @@ -38,8 +38,27 @@ static void def_log_func(unsigned int level, const char* file, wpi::errs() << oss.str(); } -Logger::Logger() { SetDefaultLogger(); } +Instance::Instance() : telemetry(notifier), network_listener(logger, notifier) { + SetDefaultLogger(); +} -Logger::~Logger() {} +Instance::~Instance() {} -void Logger::SetDefaultLogger() { SetLogger(def_log_func); } +Instance& Instance::GetInstance() { + static Instance inst; + return inst; +} + +void Instance::SetDefaultLogger() { logger.SetLogger(def_log_func); } + +std::pair> Instance::FindSource( + const SourceImpl& source) { + return sources.FindIf( + [&](const SourceData& data) { return data.source.get() == &source; }); +} + +std::pair> Instance::FindSink( + const SinkImpl& sink) { + return sinks.FindIf( + [&](const SinkData& data) { return data.sink.get() == &sink; }); +} diff --git a/cscore/src/main/native/cpp/Instance.h b/cscore/src/main/native/cpp/Instance.h new file mode 100644 index 0000000000..9cb52f65dc --- /dev/null +++ b/cscore/src/main/native/cpp/Instance.h @@ -0,0 +1,75 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2018 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#ifndef CSCORE_INSTANCE_H_ +#define CSCORE_INSTANCE_H_ + +#include +#include + +#include +#include + +#include "Log.h" +#include "NetworkListener.h" +#include "Notifier.h" +#include "SinkImpl.h" +#include "SourceImpl.h" +#include "Telemetry.h" +#include "UnlimitedHandleResource.h" + +namespace cs { + +struct SourceData { + SourceData(CS_SourceKind kind_, std::shared_ptr source_) + : kind{kind_}, refCount{0}, source{source_} {} + + CS_SourceKind kind; + std::atomic_int refCount; + std::shared_ptr source; +}; + +struct SinkData { + explicit SinkData(CS_SinkKind kind_, std::shared_ptr sink_) + : kind{kind_}, refCount{0}, sourceHandle{0}, sink{sink_} {} + + CS_SinkKind kind; + std::atomic_int refCount; + std::atomic sourceHandle; + std::shared_ptr sink; +}; + +class Instance { + public: + Instance(const Instance&) = delete; + Instance& operator=(const Instance&) = delete; + ~Instance(); + + static Instance& GetInstance(); + + UnlimitedHandleResource sources; + UnlimitedHandleResource sinks; + + wpi::Logger logger; + Notifier notifier; + Telemetry telemetry; + NetworkListener network_listener; + wpi::EventLoopRunner event_loop; + + std::pair> FindSink(const SinkImpl& sink); + std::pair> FindSource( + const SourceImpl& source); + + void SetDefaultLogger(); + + private: + Instance(); +}; + +} // namespace cs + +#endif // CSCORE_INSTANCE_H_ diff --git a/cscore/src/main/native/cpp/Log.h b/cscore/src/main/native/cpp/Log.h index 3cf76b403b..9ca0e1bd57 100644 --- a/cscore/src/main/native/cpp/Log.h +++ b/cscore/src/main/native/cpp/Log.h @@ -10,34 +10,18 @@ #include -namespace cs { - -class Logger : public wpi::Logger { - public: - static Logger& GetInstance() { - static Logger instance; - return instance; - } - ~Logger(); - - void SetDefaultLogger(); - - private: - Logger(); -}; - -#define LOG(level, x) WPI_LOG(cs::Logger::GetInstance(), level, x) +#define LOG(level, x) WPI_LOG(m_logger, level, x) #undef ERROR -#define ERROR(x) WPI_ERROR(cs::Logger::GetInstance(), x) -#define WARNING(x) WPI_WARNING(cs::Logger::GetInstance(), x) -#define INFO(x) WPI_INFO(cs::Logger::GetInstance(), x) +#define ERROR(x) WPI_ERROR(m_logger, x) +#define WARNING(x) WPI_WARNING(m_logger, x) +#define INFO(x) WPI_INFO(m_logger, x) -#define DEBUG(x) WPI_DEBUG(cs::Logger::GetInstance(), x) -#define DEBUG1(x) WPI_DEBUG1(cs::Logger::GetInstance(), x) -#define DEBUG2(x) WPI_DEBUG2(cs::Logger::GetInstance(), x) -#define DEBUG3(x) WPI_DEBUG3(cs::Logger::GetInstance(), x) -#define DEBUG4(x) WPI_DEBUG4(cs::Logger::GetInstance(), x) +#define DEBUG(x) WPI_DEBUG(m_logger, x) +#define DEBUG1(x) WPI_DEBUG1(m_logger, x) +#define DEBUG2(x) WPI_DEBUG2(m_logger, x) +#define DEBUG3(x) WPI_DEBUG3(m_logger, x) +#define DEBUG4(x) WPI_DEBUG4(m_logger, x) #define SERROR(x) ERROR(GetName() << ": " << x) #define SWARNING(x) WARNING(GetName() << ": " << x) @@ -49,6 +33,4 @@ class Logger : public wpi::Logger { #define SDEBUG3(x) DEBUG3(GetName() << ": " << x) #define SDEBUG4(x) DEBUG4(GetName() << ": " << x) -} // namespace cs - #endif // CSCORE_LOG_H_ diff --git a/cscore/src/main/native/cpp/MjpegServerImpl.cpp b/cscore/src/main/native/cpp/MjpegServerImpl.cpp index df239220fc..d2dd792123 100644 --- a/cscore/src/main/native/cpp/MjpegServerImpl.cpp +++ b/cscore/src/main/native/cpp/MjpegServerImpl.cpp @@ -16,6 +16,7 @@ #include #include "Handle.h" +#include "Instance.h" #include "JpegUtil.h" #include "Log.h" #include "Notifier.h" @@ -73,7 +74,8 @@ static const char* endRootPage = ""; class MjpegServerImpl::ConnThread : public wpi::SafeThread { public: - explicit ConnThread(const wpi::Twine& name) : m_name(name.str()) {} + explicit ConnThread(const wpi::Twine& name, wpi::Logger& logger) + : m_name(name.str()), m_logger(logger) {} void Main(); @@ -97,6 +99,7 @@ class MjpegServerImpl::ConnThread : public wpi::SafeThread { private: std::string m_name; + wpi::Logger& m_logger; wpi::StringRef GetName() { return m_name; } @@ -548,10 +551,11 @@ void MjpegServerImpl::ConnThread::SendJSON(wpi::raw_ostream& os, os.flush(); } -MjpegServerImpl::MjpegServerImpl(const wpi::Twine& name, +MjpegServerImpl::MjpegServerImpl(const wpi::Twine& name, wpi::Logger& logger, + Notifier& notifier, Telemetry& telemetry, const wpi::Twine& listenAddress, int port, std::unique_ptr acceptor) - : SinkImpl{name}, + : SinkImpl{name, logger, notifier, telemetry}, m_listenAddress(listenAddress.str()), m_port(port), m_acceptor{std::move(acceptor)} { @@ -865,7 +869,7 @@ void MjpegServerImpl::ServerThreadMain() { } // Start it if not already started - it->Start(GetName()); + it->Start(GetName(), m_logger); auto nstreams = std::count_if(m_connThreads.begin(), m_connThreads.end(), @@ -909,20 +913,21 @@ namespace cs { CS_Sink CreateMjpegServer(const wpi::Twine& name, const wpi::Twine& listenAddress, int port, CS_Status* status) { + auto& inst = Instance::GetInstance(); wpi::SmallString<128> listenAddressBuf; auto sink = std::make_shared( - name, listenAddress, port, + name, inst.logger, inst.notifier, inst.telemetry, listenAddress, port, std::unique_ptr(new wpi::TCPAcceptor( port, listenAddress.toNullTerminatedStringRef(listenAddressBuf).data(), - Logger::GetInstance()))); - auto handle = Sinks::GetInstance().Allocate(CS_SINK_MJPEG, sink); - Notifier::GetInstance().NotifySink(name, handle, CS_SINK_CREATED); + inst.logger))); + auto handle = inst.sinks.Allocate(CS_SINK_MJPEG, sink); + inst.notifier.NotifySink(name, handle, CS_SINK_CREATED); return handle; } std::string GetMjpegServerListenAddress(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_MJPEG) { *status = CS_INVALID_HANDLE; return std::string{}; @@ -931,7 +936,7 @@ std::string GetMjpegServerListenAddress(CS_Sink sink, CS_Status* status) { } int GetMjpegServerPort(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_MJPEG) { *status = CS_INVALID_HANDLE; return 0; diff --git a/cscore/src/main/native/cpp/MjpegServerImpl.h b/cscore/src/main/native/cpp/MjpegServerImpl.h index cc16d78cf1..db60b869f8 100644 --- a/cscore/src/main/native/cpp/MjpegServerImpl.h +++ b/cscore/src/main/native/cpp/MjpegServerImpl.h @@ -31,8 +31,10 @@ class SourceImpl; class MjpegServerImpl : public SinkImpl { public: - MjpegServerImpl(const wpi::Twine& name, const wpi::Twine& listenAddress, - int port, std::unique_ptr acceptor); + MjpegServerImpl(const wpi::Twine& name, wpi::Logger& logger, + Notifier& notifier, Telemetry& telemetry, + const wpi::Twine& listenAddress, int port, + std::unique_ptr acceptor); ~MjpegServerImpl() override; void Stop(); diff --git a/cscore/src/main/native/cpp/NetworkListener.h b/cscore/src/main/native/cpp/NetworkListener.h index c6d4c597ea..9457ab0b1e 100644 --- a/cscore/src/main/native/cpp/NetworkListener.h +++ b/cscore/src/main/native/cpp/NetworkListener.h @@ -8,23 +8,25 @@ #ifndef CSCORE_NETWORKLISTENER_H_ #define CSCORE_NETWORKLISTENER_H_ +#include #include namespace cs { +class Notifier; + class NetworkListener { public: - static NetworkListener& GetInstance() { - static NetworkListener instance; - return instance; - } + NetworkListener(wpi::Logger& logger, Notifier& notifier) + : m_logger(logger), m_notifier(notifier) {} ~NetworkListener(); void Start(); void Stop(); private: - NetworkListener() = default; + wpi::Logger& m_logger; + Notifier& m_notifier; class Thread; wpi::SafeThreadOwner m_owner; diff --git a/cscore/src/main/native/cpp/Notifier.cpp b/cscore/src/main/native/cpp/Notifier.cpp index 0e69618fcc..45bd050ca9 100644 --- a/cscore/src/main/native/cpp/Notifier.cpp +++ b/cscore/src/main/native/cpp/Notifier.cpp @@ -11,6 +11,7 @@ #include #include "Handle.h" +#include "Instance.h" #include "SinkImpl.h" #include "SourceImpl.h" @@ -157,7 +158,7 @@ void Notifier::NotifySource(const wpi::Twine& name, CS_Source source, } void Notifier::NotifySource(const SourceImpl& source, CS_EventKind kind) { - auto handleData = Sources::GetInstance().Find(source); + auto handleData = Instance::GetInstance().FindSource(source); NotifySource(source.GetName(), handleData.first, kind); } @@ -166,7 +167,7 @@ void Notifier::NotifySourceVideoMode(const SourceImpl& source, auto thr = m_owner.GetThread(); if (!thr) return; - auto handleData = Sources::GetInstance().Find(source); + auto handleData = Instance::GetInstance().FindSource(source); thr->m_notifications.emplace(source.GetName(), handleData.first, mode); thr->m_cond.notify_one(); @@ -179,7 +180,7 @@ void Notifier::NotifySourceProperty(const SourceImpl& source, CS_EventKind kind, auto thr = m_owner.GetThread(); if (!thr) return; - auto handleData = Sources::GetInstance().Find(source); + auto handleData = Instance::GetInstance().FindSource(source); thr->m_notifications.emplace( propertyName, handleData.first, static_cast(kind), @@ -198,7 +199,7 @@ void Notifier::NotifySink(const wpi::Twine& name, CS_Sink sink, } void Notifier::NotifySink(const SinkImpl& sink, CS_EventKind kind) { - auto handleData = Sinks::GetInstance().Find(sink); + auto handleData = Instance::GetInstance().FindSink(sink); NotifySink(sink.GetName(), handleData.first, kind); } @@ -221,7 +222,7 @@ void Notifier::NotifySinkProperty(const SinkImpl& sink, CS_EventKind kind, auto thr = m_owner.GetThread(); if (!thr) return; - auto handleData = Sinks::GetInstance().Find(sink); + auto handleData = Instance::GetInstance().FindSink(sink); thr->m_notifications.emplace( propertyName, handleData.first, static_cast(kind), diff --git a/cscore/src/main/native/cpp/Notifier.h b/cscore/src/main/native/cpp/Notifier.h index 6c3c48e0f0..526cea818c 100644 --- a/cscore/src/main/native/cpp/Notifier.h +++ b/cscore/src/main/native/cpp/Notifier.h @@ -23,10 +23,7 @@ class Notifier { friend class NotifierTest; public: - static Notifier& GetInstance() { - static Notifier instance; - return instance; - } + Notifier(); ~Notifier(); void Start(); @@ -62,8 +59,6 @@ class Notifier { void NotifyTelemetryUpdated(); private: - Notifier(); - class Thread; wpi::SafeThreadOwner m_owner; diff --git a/cscore/src/main/native/cpp/SinkImpl.cpp b/cscore/src/main/native/cpp/SinkImpl.cpp index 5e00dc0df2..2ee057549a 100644 --- a/cscore/src/main/native/cpp/SinkImpl.cpp +++ b/cscore/src/main/native/cpp/SinkImpl.cpp @@ -7,12 +7,18 @@ #include "SinkImpl.h" +#include "Instance.h" #include "Notifier.h" #include "SourceImpl.h" using namespace cs; -SinkImpl::SinkImpl(const wpi::Twine& name) : m_name{name.str()} {} +SinkImpl::SinkImpl(const wpi::Twine& name, wpi::Logger& logger, + Notifier& notifier, Telemetry& telemetry) + : m_logger(logger), + m_notifier(notifier), + m_telemetry(telemetry), + m_name{name.str()} {} SinkImpl::~SinkImpl() { if (m_source) { @@ -37,7 +43,7 @@ void SinkImpl::Enable() { ++m_enabledCount; if (m_enabledCount == 1) { if (m_source) m_source->EnableSink(); - Notifier::GetInstance().NotifySink(*this, CS_SINK_ENABLED); + m_notifier.NotifySink(*this, CS_SINK_ENABLED); } } @@ -46,7 +52,7 @@ void SinkImpl::Disable() { --m_enabledCount; if (m_enabledCount == 0) { if (m_source) m_source->DisableSink(); - Notifier::GetInstance().NotifySink(*this, CS_SINK_DISABLED); + m_notifier.NotifySink(*this, CS_SINK_DISABLED); } } @@ -55,11 +61,11 @@ void SinkImpl::SetEnabled(bool enabled) { if (enabled && m_enabledCount == 0) { if (m_source) m_source->EnableSink(); m_enabledCount = 1; - Notifier::GetInstance().NotifySink(*this, CS_SINK_ENABLED); + m_notifier.NotifySink(*this, CS_SINK_ENABLED); } else if (!enabled && m_enabledCount > 0) { if (m_source) m_source->DisableSink(); m_enabledCount = 0; - Notifier::GetInstance().NotifySink(*this, CS_SINK_DISABLED); + m_notifier.NotifySink(*this, CS_SINK_DISABLED); } } @@ -97,15 +103,14 @@ wpi::StringRef SinkImpl::GetError(wpi::SmallVectorImpl& buf) const { } void SinkImpl::NotifyPropertyCreated(int propIndex, PropertyImpl& prop) { - auto& notifier = Notifier::GetInstance(); - notifier.NotifySinkProperty(*this, CS_SINK_PROPERTY_CREATED, prop.name, - propIndex, prop.propKind, prop.value, - prop.valueStr); + m_notifier.NotifySinkProperty(*this, CS_SINK_PROPERTY_CREATED, prop.name, + propIndex, prop.propKind, prop.value, + prop.valueStr); // also notify choices updated event for enum types if (prop.propKind == CS_PROP_ENUM) - notifier.NotifySinkProperty(*this, CS_SINK_PROPERTY_CHOICES_UPDATED, - prop.name, propIndex, prop.propKind, prop.value, - wpi::Twine{}); + m_notifier.NotifySinkProperty(*this, CS_SINK_PROPERTY_CHOICES_UPDATED, + prop.name, propIndex, prop.propKind, + prop.value, wpi::Twine{}); } void SinkImpl::UpdatePropertyValue(int property, bool setString, int value, @@ -119,10 +124,11 @@ void SinkImpl::UpdatePropertyValue(int property, bool setString, int value, prop->SetValue(value); // Only notify updates after we've notified created - if (m_properties_cached) - Notifier::GetInstance().NotifySinkProperty( - *this, CS_SINK_PROPERTY_VALUE_UPDATED, prop->name, property, - prop->propKind, prop->value, prop->valueStr); + if (m_properties_cached) { + m_notifier.NotifySinkProperty(*this, CS_SINK_PROPERTY_VALUE_UPDATED, + prop->name, property, prop->propKind, + prop->value, prop->valueStr); + } } void SinkImpl::SetSourceImpl(std::shared_ptr source) {} diff --git a/cscore/src/main/native/cpp/SinkImpl.h b/cscore/src/main/native/cpp/SinkImpl.h index dd4cab7d64..c51a7950b6 100644 --- a/cscore/src/main/native/cpp/SinkImpl.h +++ b/cscore/src/main/native/cpp/SinkImpl.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -20,10 +21,13 @@ namespace cs { class Frame; +class Notifier; +class Telemetry; class SinkImpl : public PropertyContainer { public: - explicit SinkImpl(const wpi::Twine& name); + explicit SinkImpl(const wpi::Twine& name, wpi::Logger& logger, + Notifier& notifier, Telemetry& telemetry); virtual ~SinkImpl(); SinkImpl(const SinkImpl& queue) = delete; SinkImpl& operator=(const SinkImpl& queue) = delete; @@ -55,6 +59,11 @@ class SinkImpl : public PropertyContainer { virtual void SetSourceImpl(std::shared_ptr source); + protected: + wpi::Logger& m_logger; + Notifier& m_notifier; + Telemetry& m_telemetry; + private: std::string m_name; std::string m_description; diff --git a/cscore/src/main/native/cpp/SourceImpl.cpp b/cscore/src/main/native/cpp/SourceImpl.cpp index 4333e9147f..cf8ef0dcfa 100644 --- a/cscore/src/main/native/cpp/SourceImpl.cpp +++ b/cscore/src/main/native/cpp/SourceImpl.cpp @@ -21,7 +21,12 @@ using namespace cs; static constexpr size_t kMaxImagesAvail = 32; -SourceImpl::SourceImpl(const wpi::Twine& name) : m_name{name.str()} { +SourceImpl::SourceImpl(const wpi::Twine& name, wpi::Logger& logger, + Notifier& notifier, Telemetry& telemetry) + : m_logger(logger), + m_notifier(notifier), + m_telemetry(telemetry), + m_name{name.str()} { m_frame = Frame{*this, wpi::StringRef{}, 0}; } @@ -53,9 +58,9 @@ wpi::StringRef SourceImpl::GetDescription( void SourceImpl::SetConnected(bool connected) { bool wasConnected = m_connected.exchange(connected); if (wasConnected && !connected) - Notifier::GetInstance().NotifySource(*this, CS_SOURCE_DISCONNECTED); + m_notifier.NotifySource(*this, CS_SOURCE_DISCONNECTED); else if (!wasConnected && connected) - Notifier::GetInstance().NotifySource(*this, CS_SOURCE_CONNECTED); + m_notifier.NotifySource(*this, CS_SOURCE_CONNECTED); } uint64_t SourceImpl::GetCurFrameTime() { @@ -215,9 +220,8 @@ void SourceImpl::PutFrame(VideoMode::PixelFormat pixelFormat, int width, void SourceImpl::PutFrame(std::unique_ptr image, Frame::Time time) { // Update telemetry - Telemetry::GetInstance().RecordSourceFrames(*this, 1); - Telemetry::GetInstance().RecordSourceBytes(*this, - static_cast(image->size())); + m_telemetry.RecordSourceFrames(*this, 1); + m_telemetry.RecordSourceBytes(*this, static_cast(image->size())); // Update frame { @@ -241,15 +245,14 @@ void SourceImpl::PutError(const wpi::Twine& msg, Frame::Time time) { } void SourceImpl::NotifyPropertyCreated(int propIndex, PropertyImpl& prop) { - auto& notifier = Notifier::GetInstance(); - notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_CREATED, prop.name, - propIndex, prop.propKind, prop.value, - prop.valueStr); + m_notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_CREATED, prop.name, + propIndex, prop.propKind, prop.value, + prop.valueStr); // also notify choices updated event for enum types if (prop.propKind == CS_PROP_ENUM) - notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_CHOICES_UPDATED, - prop.name, propIndex, prop.propKind, - prop.value, wpi::Twine{}); + m_notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_CHOICES_UPDATED, + prop.name, propIndex, prop.propKind, + prop.value, wpi::Twine{}); } void SourceImpl::UpdatePropertyValue(int property, bool setString, int value, @@ -263,10 +266,11 @@ void SourceImpl::UpdatePropertyValue(int property, bool setString, int value, prop->SetValue(value); // Only notify updates after we've notified created - if (m_properties_cached) - Notifier::GetInstance().NotifySourceProperty( - *this, CS_SOURCE_PROPERTY_VALUE_UPDATED, prop->name, property, - prop->propKind, prop->value, prop->valueStr); + if (m_properties_cached) { + m_notifier.NotifySourceProperty(*this, CS_SOURCE_PROPERTY_VALUE_UPDATED, + prop->name, property, prop->propKind, + prop->value, prop->valueStr); + } } void SourceImpl::ReleaseImage(std::unique_ptr image) { diff --git a/cscore/src/main/native/cpp/SourceImpl.h b/cscore/src/main/native/cpp/SourceImpl.h index 0eef6c2ca7..09c84a783e 100644 --- a/cscore/src/main/native/cpp/SourceImpl.h +++ b/cscore/src/main/native/cpp/SourceImpl.h @@ -15,23 +15,29 @@ #include #include +#include #include #include #include #include #include "Frame.h" +#include "Handle.h" #include "Image.h" #include "PropertyContainer.h" #include "cscore_cpp.h" namespace cs { +class Notifier; +class Telemetry; + class SourceImpl : public PropertyContainer { friend class Frame; public: - explicit SourceImpl(const wpi::Twine& name); + SourceImpl(const wpi::Twine& name, wpi::Logger& logger, Notifier& notifier, + Telemetry& telemetry); virtual ~SourceImpl(); SourceImpl(const SourceImpl& oth) = delete; SourceImpl& operator=(const SourceImpl& oth) = delete; @@ -146,6 +152,10 @@ class SourceImpl : public PropertyContainer { // Current video mode mutable VideoMode m_mode; + wpi::Logger& m_logger; + Notifier& m_notifier; + Telemetry& m_telemetry; + private: void ReleaseImage(std::unique_ptr image); std::unique_ptr AllocFrameImpl(); diff --git a/cscore/src/main/native/cpp/Telemetry.cpp b/cscore/src/main/native/cpp/Telemetry.cpp index cfb3f804c3..fa6c93c5df 100644 --- a/cscore/src/main/native/cpp/Telemetry.cpp +++ b/cscore/src/main/native/cpp/Telemetry.cpp @@ -14,15 +14,20 @@ #include #include "Handle.h" +#include "Instance.h" #include "Notifier.h" +#include "SourceImpl.h" #include "cscore_cpp.h" using namespace cs; class Telemetry::Thread : public wpi::SafeThread { public: + explicit Thread(Notifier& notifier) : m_notifier(notifier) {} + void Main(); + Notifier& m_notifier; wpi::DenseMap, int64_t> m_user; wpi::DenseMap, int64_t> m_current; double m_period = 0.0; @@ -41,11 +46,9 @@ int64_t Telemetry::Thread::GetValue(CS_Handle handle, CS_TelemetryKind kind, return it->getSecond(); } -Telemetry::Telemetry() {} - Telemetry::~Telemetry() {} -void Telemetry::Start() { m_owner.Start(); } +void Telemetry::Start() { m_owner.Start(m_notifier); } void Telemetry::Stop() { m_owner.Stop(); } @@ -74,7 +77,7 @@ void Telemetry::Thread::Main() { prevTime = curTime; // notify - Notifier::GetInstance().NotifyTelemetryUpdated(); + m_notifier.NotifyTelemetryUpdated(); } } @@ -117,7 +120,7 @@ double Telemetry::GetAverageValue(CS_Handle handle, CS_TelemetryKind kind, void Telemetry::RecordSourceBytes(const SourceImpl& source, int quantity) { auto thr = m_owner.GetThread(); if (!thr) return; - auto handleData = Sources::GetInstance().Find(source); + auto handleData = Instance::GetInstance().FindSource(source); thr->m_current[std::make_pair(Handle{handleData.first, Handle::kSource}, static_cast(CS_SOURCE_BYTES_RECEIVED))] += quantity; @@ -126,7 +129,7 @@ void Telemetry::RecordSourceBytes(const SourceImpl& source, int quantity) { void Telemetry::RecordSourceFrames(const SourceImpl& source, int quantity) { auto thr = m_owner.GetThread(); if (!thr) return; - auto handleData = Sources::GetInstance().Find(source); + auto handleData = Instance::GetInstance().FindSource(source); thr->m_current[std::make_pair(Handle{handleData.first, Handle::kSource}, static_cast(CS_SOURCE_FRAMES_RECEIVED))] += quantity; diff --git a/cscore/src/main/native/cpp/Telemetry.h b/cscore/src/main/native/cpp/Telemetry.h index 2c869e8dc6..8729704111 100644 --- a/cscore/src/main/native/cpp/Telemetry.h +++ b/cscore/src/main/native/cpp/Telemetry.h @@ -14,16 +14,14 @@ namespace cs { +class Notifier; class SourceImpl; class Telemetry { friend class TelemetryTest; public: - static Telemetry& GetInstance() { - static Telemetry instance; - return instance; - } + explicit Telemetry(Notifier& notifier) : m_notifier(notifier) {} ~Telemetry(); void Start(); @@ -41,7 +39,7 @@ class Telemetry { void RecordSourceFrames(const SourceImpl& source, int quantity); private: - Telemetry(); + Notifier& m_notifier; class Thread; wpi::SafeThreadOwner m_owner; diff --git a/cscore/src/main/native/cpp/UnlimitedHandleResource.h b/cscore/src/main/native/cpp/UnlimitedHandleResource.h index a235bdd38a..971cd625ba 100644 --- a/cscore/src/main/native/cpp/UnlimitedHandleResource.h +++ b/cscore/src/main/native/cpp/UnlimitedHandleResource.h @@ -163,20 +163,6 @@ UnlimitedHandleResource::FindIf(F func) { return std::make_pair(0, nullptr); } -template -class StaticUnlimitedHandleResource - : public UnlimitedHandleResource { - public: - static StaticUnlimitedHandleResource& GetInstance() { - static StaticUnlimitedHandleResource instance; - return instance; - } - - private: - StaticUnlimitedHandleResource() = default; -}; - } // namespace cs #endif // CSCORE_UNLIMITEDHANDLERESOURCE_H_ diff --git a/cscore/src/main/native/cpp/cscore_cpp.cpp b/cscore/src/main/native/cpp/cscore_cpp.cpp index d3791858c3..b1a4ef1f6f 100644 --- a/cscore/src/main/native/cpp/cscore_cpp.cpp +++ b/cscore/src/main/native/cpp/cscore_cpp.cpp @@ -11,6 +11,7 @@ #include #include "Handle.h" +#include "Instance.h" #include "Log.h" #include "NetworkListener.h" #include "Notifier.h" @@ -27,7 +28,7 @@ static std::shared_ptr GetPropertyContainer( Handle handle{propertyHandle}; if (handle.IsType(Handle::kProperty)) { int i = handle.GetParentIndex(); - auto data = Sources::GetInstance().Get(Handle{i, Handle::kSource}); + auto data = Instance::GetInstance().sources.Get(Handle{i, Handle::kSource}); if (!data) { *status = CS_INVALID_HANDLE; return nullptr; @@ -35,7 +36,7 @@ static std::shared_ptr GetPropertyContainer( container = data->source; } else if (handle.IsType(Handle::kSinkProperty)) { int i = handle.GetParentIndex(); - auto data = Sinks::GetInstance().Get(Handle{i, Handle::kSink}); + auto data = Instance::GetInstance().sinks.Get(Handle{i, Handle::kSink}); if (!data) { *status = CS_INVALID_HANDLE; return nullptr; @@ -159,7 +160,7 @@ std::vector GetEnumPropertyChoices(CS_Property property, // CS_SourceKind GetSourceKind(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return CS_SOURCE_UNKNOWN; @@ -168,7 +169,7 @@ CS_SourceKind GetSourceKind(CS_Source source, CS_Status* status) { } std::string GetSourceName(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return std::string{}; @@ -178,7 +179,7 @@ std::string GetSourceName(CS_Source source, CS_Status* status) { wpi::StringRef GetSourceName(CS_Source source, wpi::SmallVectorImpl& buf, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return wpi::StringRef{}; @@ -187,7 +188,7 @@ wpi::StringRef GetSourceName(CS_Source source, wpi::SmallVectorImpl& buf, } std::string GetSourceDescription(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return std::string{}; @@ -199,7 +200,7 @@ std::string GetSourceDescription(CS_Source source, CS_Status* status) { wpi::StringRef GetSourceDescription(CS_Source source, wpi::SmallVectorImpl& buf, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return wpi::StringRef{}; @@ -208,7 +209,7 @@ wpi::StringRef GetSourceDescription(CS_Source source, } uint64_t GetSourceLastFrameTime(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -219,7 +220,7 @@ uint64_t GetSourceLastFrameTime(CS_Source source, CS_Status* status) { void SetSourceConnectionStrategy(CS_Source source, CS_ConnectionStrategy strategy, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return; @@ -228,7 +229,7 @@ void SetSourceConnectionStrategy(CS_Source source, } bool IsSourceConnected(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return false; @@ -237,7 +238,7 @@ bool IsSourceConnected(CS_Source source, CS_Status* status) { } bool IsSourceEnabled(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return false; @@ -247,7 +248,7 @@ bool IsSourceEnabled(CS_Source source, CS_Status* status) { CS_Property GetSourceProperty(CS_Source source, const wpi::Twine& name, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -263,7 +264,7 @@ CS_Property GetSourceProperty(CS_Source source, const wpi::Twine& name, wpi::ArrayRef EnumerateSourceProperties( CS_Source source, wpi::SmallVectorImpl& vec, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -276,7 +277,7 @@ wpi::ArrayRef EnumerateSourceProperties( } VideoMode GetSourceVideoMode(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return VideoMode{}; @@ -286,7 +287,7 @@ VideoMode GetSourceVideoMode(CS_Source source, CS_Status* status) { bool SetSourceVideoMode(CS_Source source, const VideoMode& mode, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return false; @@ -296,7 +297,7 @@ bool SetSourceVideoMode(CS_Source source, const VideoMode& mode, bool SetSourcePixelFormat(CS_Source source, VideoMode::PixelFormat pixelFormat, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return false; @@ -306,7 +307,7 @@ bool SetSourcePixelFormat(CS_Source source, VideoMode::PixelFormat pixelFormat, bool SetSourceResolution(CS_Source source, int width, int height, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return false; @@ -315,7 +316,7 @@ bool SetSourceResolution(CS_Source source, int width, int height, } bool SetSourceFPS(CS_Source source, int fps, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return false; @@ -325,7 +326,7 @@ bool SetSourceFPS(CS_Source source, int fps, CS_Status* status) { std::vector EnumerateSourceVideoModes(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return std::vector{}; @@ -336,13 +337,14 @@ std::vector EnumerateSourceVideoModes(CS_Source source, wpi::ArrayRef EnumerateSourceSinks(CS_Source source, wpi::SmallVectorImpl& vec, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto& inst = Instance::GetInstance(); + auto data = inst.sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return wpi::ArrayRef{}; } vec.clear(); - Sinks::GetInstance().ForEach([&](CS_Sink sinkHandle, const SinkData& data) { + inst.sinks.ForEach([&](CS_Sink sinkHandle, const SinkData& data) { if (source == data.sourceHandle.load()) vec.push_back(sinkHandle); }); return vec; @@ -350,7 +352,7 @@ wpi::ArrayRef EnumerateSourceSinks(CS_Source source, CS_Source CopySource(CS_Source source, CS_Status* status) { if (source == 0) return 0; - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -361,16 +363,16 @@ CS_Source CopySource(CS_Source source, CS_Status* status) { void ReleaseSource(CS_Source source, CS_Status* status) { if (source == 0) return; - auto& inst = Sources::GetInstance(); - auto data = inst.Get(source); + auto& inst = Instance::GetInstance(); + auto data = inst.sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return; } if (data->refCount-- == 0) { - Notifier::GetInstance().NotifySource(data->source->GetName(), source, - CS_SOURCE_DESTROYED); - inst.Free(source); + inst.notifier.NotifySource(data->source->GetName(), source, + CS_SOURCE_DESTROYED); + inst.sources.Free(source); } } @@ -379,7 +381,7 @@ void ReleaseSource(CS_Source source, CS_Status* status) { // void SetCameraBrightness(CS_Source source, int brightness, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return; @@ -388,7 +390,7 @@ void SetCameraBrightness(CS_Source source, int brightness, CS_Status* status) { } int GetCameraBrightness(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -397,7 +399,7 @@ int GetCameraBrightness(CS_Source source, CS_Status* status) { } void SetCameraWhiteBalanceAuto(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return; @@ -406,7 +408,7 @@ void SetCameraWhiteBalanceAuto(CS_Source source, CS_Status* status) { } void SetCameraWhiteBalanceHoldCurrent(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return; @@ -416,7 +418,7 @@ void SetCameraWhiteBalanceHoldCurrent(CS_Source source, CS_Status* status) { void SetCameraWhiteBalanceManual(CS_Source source, int value, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return; @@ -425,7 +427,7 @@ void SetCameraWhiteBalanceManual(CS_Source source, int value, } void SetCameraExposureAuto(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return; @@ -434,7 +436,7 @@ void SetCameraExposureAuto(CS_Source source, CS_Status* status) { } void SetCameraExposureHoldCurrent(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return; @@ -443,7 +445,7 @@ void SetCameraExposureHoldCurrent(CS_Source source, CS_Status* status) { } void SetCameraExposureManual(CS_Source source, int value, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data) { *status = CS_INVALID_HANDLE; return; @@ -456,7 +458,7 @@ void SetCameraExposureManual(CS_Source source, int value, CS_Status* status) { // CS_SinkKind GetSinkKind(CS_Sink sink, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return CS_SINK_UNKNOWN; @@ -465,7 +467,7 @@ CS_SinkKind GetSinkKind(CS_Sink sink, CS_Status* status) { } std::string GetSinkName(CS_Sink sink, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return std::string{}; @@ -475,7 +477,7 @@ std::string GetSinkName(CS_Sink sink, CS_Status* status) { wpi::StringRef GetSinkName(CS_Sink sink, wpi::SmallVectorImpl& buf, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return wpi::StringRef{}; @@ -484,7 +486,7 @@ wpi::StringRef GetSinkName(CS_Sink sink, wpi::SmallVectorImpl& buf, } std::string GetSinkDescription(CS_Sink sink, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return std::string{}; @@ -495,7 +497,7 @@ std::string GetSinkDescription(CS_Sink sink, CS_Status* status) { wpi::StringRef GetSinkDescription(CS_Sink sink, wpi::SmallVectorImpl& buf, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return wpi::StringRef{}; @@ -505,7 +507,7 @@ wpi::StringRef GetSinkDescription(CS_Sink sink, wpi::SmallVectorImpl& buf, CS_Property GetSinkProperty(CS_Sink sink, const wpi::Twine& name, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -520,7 +522,7 @@ CS_Property GetSinkProperty(CS_Sink sink, const wpi::Twine& name, wpi::ArrayRef EnumerateSinkProperties( CS_Sink sink, wpi::SmallVectorImpl& vec, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -532,7 +534,7 @@ wpi::ArrayRef EnumerateSinkProperties( } void SetSinkSource(CS_Sink sink, CS_Source source, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return; @@ -540,7 +542,7 @@ void SetSinkSource(CS_Sink sink, CS_Source source, CS_Status* status) { if (source == 0) { data->sink->SetSource(nullptr); } else { - auto sourceData = Sources::GetInstance().Get(source); + auto sourceData = Instance::GetInstance().sources.Get(source); if (!sourceData) { *status = CS_INVALID_HANDLE; return; @@ -548,12 +550,12 @@ void SetSinkSource(CS_Sink sink, CS_Source source, CS_Status* status) { data->sink->SetSource(sourceData->source); } data->sourceHandle.store(source); - Notifier::GetInstance().NotifySinkSourceChanged(data->sink->GetName(), sink, - source); + Instance::GetInstance().notifier.NotifySinkSourceChanged( + data->sink->GetName(), sink, source); } CS_Source GetSinkSource(CS_Sink sink, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -563,7 +565,7 @@ CS_Source GetSinkSource(CS_Sink sink, CS_Status* status) { CS_Property GetSinkSourceProperty(CS_Sink sink, const wpi::Twine& name, CS_Status* status) { - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -573,7 +575,7 @@ CS_Property GetSinkSourceProperty(CS_Sink sink, const wpi::Twine& name, CS_Sink CopySink(CS_Sink sink, CS_Status* status) { if (sink == 0) return 0; - auto data = Sinks::GetInstance().Get(sink); + auto data = Instance::GetInstance().sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return 0; @@ -584,16 +586,15 @@ CS_Sink CopySink(CS_Sink sink, CS_Status* status) { void ReleaseSink(CS_Sink sink, CS_Status* status) { if (sink == 0) return; - auto& inst = Sinks::GetInstance(); - auto data = inst.Get(sink); + auto& inst = Instance::GetInstance(); + auto data = inst.sinks.Get(sink); if (!data) { *status = CS_INVALID_HANDLE; return; } if (data->refCount-- == 0) { - Notifier::GetInstance().NotifySink(data->sink->GetName(), sink, - CS_SINK_DESTROYED); - inst.Free(sink); + inst.notifier.NotifySink(data->sink->GetName(), sink, CS_SINK_DESTROYED); + inst.sinks.Free(sink); } } @@ -602,22 +603,22 @@ void ReleaseSink(CS_Sink sink, CS_Status* status) { // void SetListenerOnStart(std::function onStart) { - Notifier::GetInstance().SetOnStart(onStart); + Instance::GetInstance().notifier.SetOnStart(onStart); } void SetListenerOnExit(std::function onExit) { - Notifier::GetInstance().SetOnExit(onExit); + Instance::GetInstance().notifier.SetOnExit(onExit); } CS_Listener AddListener(std::function callback, int eventMask, bool immediateNotify, CS_Status* status) { - int uid = Notifier::GetInstance().AddListener(callback, eventMask); + auto& inst = Instance::GetInstance(); + int uid = inst.notifier.AddListener(callback, eventMask); if ((eventMask & CS_NETWORK_INTERFACES_CHANGED) != 0) { // start network interface event listener - NetworkListener::GetInstance().Start(); - if (immediateNotify) - Notifier::GetInstance().NotifyNetworkInterfacesChanged(); + inst.network_listener.Start(); + if (immediateNotify) inst.notifier.NotifyNetworkInterfacesChanged(); } if (immediateNotify) { // TODO @@ -631,7 +632,7 @@ void RemoveListener(CS_Listener handle, CS_Status* status) { *status = CS_INVALID_HANDLE; return; } - Notifier::GetInstance().RemoveListener(uid); + Instance::GetInstance().notifier.RemoveListener(uid); } bool NotifierDestroyed() { return Notifier::destroyed(); } @@ -640,37 +641,39 @@ bool NotifierDestroyed() { return Notifier::destroyed(); } // Telemetry Functions // void SetTelemetryPeriod(double seconds) { - Telemetry::GetInstance().Start(); - Telemetry::GetInstance().SetPeriod(seconds); + auto& inst = Instance::GetInstance(); + inst.telemetry.Start(); + inst.telemetry.SetPeriod(seconds); } double GetTelemetryElapsedTime() { - return Telemetry::GetInstance().GetElapsedTime(); + return Instance::GetInstance().telemetry.GetElapsedTime(); } int64_t GetTelemetryValue(CS_Handle handle, CS_TelemetryKind kind, CS_Status* status) { - return Telemetry::GetInstance().GetValue(handle, kind, status); + return Instance::GetInstance().telemetry.GetValue(handle, kind, status); } double GetTelemetryAverageValue(CS_Handle handle, CS_TelemetryKind kind, CS_Status* status) { - return Telemetry::GetInstance().GetAverageValue(handle, kind, status); + return Instance::GetInstance().telemetry.GetAverageValue(handle, kind, + status); } // // Logging Functions // void SetLogger(LogFunc func, unsigned int min_level) { - Logger& logger = Logger::GetInstance(); + auto& logger = Instance::GetInstance().logger; logger.SetLogger(func); logger.set_min_level(min_level); } void SetDefaultLogger(unsigned int min_level) { - Logger& logger = Logger::GetInstance(); - logger.SetDefaultLogger(); - logger.set_min_level(min_level); + auto& inst = Instance::GetInstance(); + inst.SetDefaultLogger(); + inst.logger.set_min_level(min_level); } // @@ -679,12 +682,12 @@ void SetDefaultLogger(unsigned int min_level) { wpi::ArrayRef EnumerateSourceHandles( wpi::SmallVectorImpl& vec, CS_Status* status) { - return Sources::GetInstance().GetAll(vec); + return Instance::GetInstance().sources.GetAll(vec); } wpi::ArrayRef EnumerateSinkHandles(wpi::SmallVectorImpl& vec, CS_Status* status) { - return Sinks::GetInstance().GetAll(vec); + return Instance::GetInstance().sinks.GetAll(vec); } std::string GetHostname() { return wpi::GetHostname(); } diff --git a/cscore/src/main/native/linux/NetworkListener.cpp b/cscore/src/main/native/linux/NetworkListener.cpp index 1c1978f6fd..c04703a66e 100644 --- a/cscore/src/main/native/linux/NetworkListener.cpp +++ b/cscore/src/main/native/linux/NetworkListener.cpp @@ -27,8 +27,12 @@ using namespace cs; class NetworkListener::Thread : public wpi::SafeThread { public: + Thread(wpi::Logger& logger, Notifier& notifier) + : m_logger(logger), m_notifier(notifier) {} void Main(); + wpi::Logger& m_logger; + Notifier& m_notifier; #ifdef __linux__ int m_command_fd = -1; #endif @@ -36,10 +40,7 @@ class NetworkListener::Thread : public wpi::SafeThread { NetworkListener::~NetworkListener() { Stop(); } -void NetworkListener::Start() { - auto thr = m_owner.GetThread(); - if (!thr) m_owner.Start(); -} +void NetworkListener::Start() { m_owner.Start(m_logger, m_notifier); } void NetworkListener::Stop() { // Wake up thread @@ -125,7 +126,7 @@ void NetworkListener::Thread::Main() { if (nh->nlmsg_type == NLMSG_DONE) break; if (nh->nlmsg_type == RTM_NEWLINK || nh->nlmsg_type == RTM_DELLINK || nh->nlmsg_type == RTM_NEWADDR || nh->nlmsg_type == RTM_DELADDR) { - Notifier::GetInstance().NotifyNetworkInterfacesChanged(); + m_notifier.NotifyNetworkInterfacesChanged(); } } } diff --git a/cscore/src/main/native/linux/UsbCameraImpl.cpp b/cscore/src/main/native/linux/UsbCameraImpl.cpp index 3fe1963306..4dabe2109e 100644 --- a/cscore/src/main/native/linux/UsbCameraImpl.cpp +++ b/cscore/src/main/native/linux/UsbCameraImpl.cpp @@ -30,6 +30,7 @@ #include #include "Handle.h" +#include "Instance.h" #include "JpegUtil.h" #include "Log.h" #include "Notifier.h" @@ -209,14 +210,17 @@ static std::string GetDescriptionImpl(const char* cpath) { return std::string{}; } -UsbCameraImpl::UsbCameraImpl(const wpi::Twine& name, const wpi::Twine& path) - : SourceImpl{name}, +UsbCameraImpl::UsbCameraImpl(const wpi::Twine& name, wpi::Logger& logger, + Notifier& notifier, Telemetry& telemetry, + const wpi::Twine& path) + : SourceImpl{name, logger, notifier, telemetry}, m_path{path.str()}, m_fd{-1}, m_command_fd{eventfd(0, 0)}, m_active{true} { SetDescription(GetDescriptionImpl(m_path.c_str())); SetQuirks(); + CreateProperty(kPropConnectVerbose, [] { return std::make_unique(kPropConnectVerbose, kPropConnectVerboseId, @@ -640,7 +644,7 @@ CS_StatusValue UsbCameraImpl::DeviceCmdSetMode( DeviceConnect(); } if (wasStreaming) DeviceStreamOn(); - Notifier::GetInstance().NotifySourceVideoMode(*this, newMode); + m_notifier.NotifySourceVideoMode(*this, newMode); lock.lock(); } else if (newMode.fps != m_mode.fps) { m_mode = newMode; @@ -650,7 +654,7 @@ CS_StatusValue UsbCameraImpl::DeviceCmdSetMode( if (wasStreaming) DeviceStreamOff(); DeviceSetFPS(); if (wasStreaming) DeviceStreamOn(); - Notifier::GetInstance().NotifySourceVideoMode(*this, newMode); + m_notifier.NotifySourceVideoMode(*this, newMode); lock.lock(); } @@ -886,7 +890,7 @@ void UsbCameraImpl::DeviceCacheMode() { if (formatChanged) DeviceSetMode(); if (fpsChanged) DeviceSetFPS(); - Notifier::GetInstance().NotifySourceVideoMode(*this, m_mode); + m_notifier.NotifySourceVideoMode(*this, m_mode); } void UsbCameraImpl::DeviceCacheProperty( @@ -1068,7 +1072,7 @@ void UsbCameraImpl::DeviceCacheVideoModes() { std::lock_guard lock(m_mutex); m_videoModes.swap(modes); } - Notifier::GetInstance().NotifySource(*this, CS_SOURCE_VIDEOMODES_UPDATED); + m_notifier.NotifySource(*this, CS_SOURCE_VIDEOMODES_UPDATED); } CS_StatusValue UsbCameraImpl::SendAndWait(Message&& msg) const { @@ -1259,9 +1263,11 @@ CS_Source CreateUsbCameraDev(const wpi::Twine& name, int dev, CS_Source CreateUsbCameraPath(const wpi::Twine& name, const wpi::Twine& path, CS_Status* status) { - auto source = std::make_shared(name, path); - auto handle = Sources::GetInstance().Allocate(CS_SOURCE_USB, source); - Notifier::GetInstance().NotifySource(name, handle, CS_SOURCE_CREATED); + auto& inst = Instance::GetInstance(); + auto source = std::make_shared( + name, inst.logger, inst.notifier, inst.telemetry, path); + auto handle = inst.sources.Allocate(CS_SOURCE_USB, source); + inst.notifier.NotifySource(name, handle, CS_SOURCE_CREATED); // Start thread after the source created event to ensure other events // come after it. source->Start(); @@ -1269,7 +1275,7 @@ CS_Source CreateUsbCameraPath(const wpi::Twine& name, const wpi::Twine& path, } std::string GetUsbCameraPath(CS_Source source, CS_Status* status) { - auto data = Sources::GetInstance().Get(source); + auto data = Instance::GetInstance().sources.Get(source); if (!data || data->kind != CS_SOURCE_USB) { *status = CS_INVALID_HANDLE; return std::string{}; @@ -1300,7 +1306,7 @@ std::vector EnumerateUsbCameras(CS_Status* status) { closedir(dp); } else { // *status = ; - ERROR("Could not open /dev"); + WPI_ERROR(Instance::GetInstance().logger, "Could not open /dev"); return retval; } diff --git a/cscore/src/main/native/linux/UsbCameraImpl.h b/cscore/src/main/native/linux/UsbCameraImpl.h index fecd1c0992..2b6afdab7a 100644 --- a/cscore/src/main/native/linux/UsbCameraImpl.h +++ b/cscore/src/main/native/linux/UsbCameraImpl.h @@ -31,9 +31,13 @@ namespace cs { +class Notifier; +class Telemetry; + class UsbCameraImpl : public SourceImpl { public: - UsbCameraImpl(const wpi::Twine& name, const wpi::Twine& path); + UsbCameraImpl(const wpi::Twine& name, wpi::Logger& logger, Notifier& notifier, + Telemetry& telemetry, const wpi::Twine& path); ~UsbCameraImpl() override; void Start(); diff --git a/cscore/src/main/native/linux/UsbUtil.cpp b/cscore/src/main/native/linux/UsbUtil.cpp index 1ecb887500..ac48178496 100644 --- a/cscore/src/main/native/linux/UsbUtil.cpp +++ b/cscore/src/main/native/linux/UsbUtil.cpp @@ -16,6 +16,7 @@ #include #include +#include "Instance.h" #include "Log.h" namespace cs { @@ -150,8 +151,9 @@ int CheckedIoctl(int fd, unsigned long req, void* data, // NOLINT(runtime/int) if (!quiet && retval < 0) { wpi::SmallString<64> localfile{file}; localfile.push_back('\0'); - ERROR("ioctl " << name << " failed at " << basename(localfile.data()) << ":" - << line << ": " << std::strerror(errno)); + WPI_ERROR(Instance::GetInstance().logger, + "ioctl " << name << " failed at " << basename(localfile.data()) + << ":" << line << ": " << std::strerror(errno)); } return retval; }