From 936627bd942c8b2eec1fdf662cee22c3e7636c21 Mon Sep 17 00:00:00 2001 From: Thad House Date: Sun, 27 Oct 2019 08:37:30 -0700 Subject: [PATCH] wpilibc: Remove direct CameraServer dependency (#1989) This makes linking easier, particularly for third party vendors and other language wrappers. --- .../cpp/cameraserver/CameraServerShared.cpp | 16 ++++--- .../include/cameraserver/CameraServerShared.h | 8 +++- wpilibc/CMakeLists.txt | 2 +- wpilibc/build.gradle | 20 +++++--- .../shuffleboard/SendableCameraWrapper.cpp | 41 ++++++---------- .../shuffleboard/ShuffleboardContainer.cpp | 10 ---- .../main/native/{cpp => cppcs}/RobotBase.cpp | 40 ++++++++++++++-- .../frc/shuffleboard/SendableCameraWrapper.h | 48 +++++++++++++++++-- .../frc/shuffleboard/ShuffleboardContainer.h | 14 ++++++ .../src/main/native/windows/StackWalker.cpp | 5 +- 10 files changed, 142 insertions(+), 62 deletions(-) rename wpilibc/src/main/native/{cpp => cppcs}/RobotBase.cpp (78%) diff --git a/cameraserver/src/main/native/cpp/cameraserver/CameraServerShared.cpp b/cameraserver/src/main/native/cpp/cameraserver/CameraServerShared.cpp index 78ca95eed0..7d30d28e1b 100644 --- a/cameraserver/src/main/native/cpp/cameraserver/CameraServerShared.cpp +++ b/cameraserver/src/main/native/cpp/cameraserver/CameraServerShared.cpp @@ -24,15 +24,10 @@ class DefaultCameraServerShared : public frc::CameraServerShared { }; } // namespace -namespace frc { - -static std::unique_ptr cameraServerShared = nullptr; +static std::unique_ptr cameraServerShared = nullptr; static wpi::mutex setLock; -void SetCameraServerShared(std::unique_ptr shared) { - std::unique_lock lock(setLock); - cameraServerShared = std::move(shared); -} +namespace frc { CameraServerShared* GetCameraServerShared() { std::unique_lock lock(setLock); if (!cameraServerShared) { @@ -41,3 +36,10 @@ CameraServerShared* GetCameraServerShared() { return cameraServerShared.get(); } } // namespace frc + +extern "C" { +void CameraServer_SetCameraServerShared(frc::CameraServerShared* shared) { + std::unique_lock lock(setLock); + cameraServerShared.reset(shared); +} +} // extern "C" diff --git a/cameraserver/src/main/native/include/cameraserver/CameraServerShared.h b/cameraserver/src/main/native/include/cameraserver/CameraServerShared.h index 72b784efe3..cb72c9bdd7 100644 --- a/cameraserver/src/main/native/include/cameraserver/CameraServerShared.h +++ b/cameraserver/src/main/native/include/cameraserver/CameraServerShared.h @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2018-2019 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. */ @@ -26,6 +26,10 @@ class CameraServerShared { virtual std::pair GetRobotMainThreadId() const = 0; }; -void SetCameraServerShared(std::unique_ptr shared); CameraServerShared* GetCameraServerShared(); } // namespace frc + +extern "C" { +// Takes ownership +void CameraServer_SetCameraServerShared(frc::CameraServerShared* shared); +} // extern "C" diff --git a/wpilibc/CMakeLists.txt b/wpilibc/CMakeLists.txt index fcbb11a558..977200a1f4 100644 --- a/wpilibc/CMakeLists.txt +++ b/wpilibc/CMakeLists.txt @@ -8,7 +8,7 @@ find_package( OpenCV REQUIRED ) configure_file(src/generate/WPILibVersion.cpp.in WPILibVersion.cpp) file(GLOB_RECURSE - wpilibc_native_src src/main/native/cpp/*.cpp) + wpilibc_native_src src/main/native/cpp/*.cpp src/main/native/cppcs/*.cpp) add_library(wpilibc ${wpilibc_native_src} ${CMAKE_CURRENT_BINARY_DIR}/WPILibVersion.cpp) set_target_properties(wpilibc PROPERTIES DEBUG_POSTFIX "d") diff --git a/wpilibc/build.gradle b/wpilibc/build.gradle index 840a73a5b1..5f93f7ec6f 100644 --- a/wpilibc/build.gradle +++ b/wpilibc/build.gradle @@ -116,31 +116,39 @@ model { it.buildable = false return } + cppCompiler.define 'DYNAMIC_CAMERA_SERVER' lib project: ':ntcore', library: 'ntcore', linkage: 'shared' - lib project: ':cscore', library: 'cscore', linkage: 'shared' project(':hal').addHalDependency(it, 'shared') lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared' - lib project: ':cameraserver', library: 'cameraserver', linkage: 'shared' } } "${nativeName}"(NativeLibrarySpec) { sources { cpp { source { - srcDirs "${rootDir}/shared/singlelib" + srcDirs "src/main/native/cppcs" include '**/*.cpp' } exportedHeaders { - srcDirs 'src/main/native/include' + srcDirs 'src/main/native/include', '../cameraserver/src/main/native/include' } } } binaries.all { lib project: ':ntcore', library: 'ntcore', linkage: 'shared' - lib project: ':cscore', library: 'cscore', linkage: 'shared' project(':hal').addHalDependency(it, 'shared') lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared' - lib project: ':cameraserver', library: 'cameraserver', linkage: 'shared' + + if (it instanceof SharedLibraryBinarySpec) { + cppCompiler.define 'DYNAMIC_CAMERA_SERVER' + if (buildType == buildTypes.debug) { + cppCompiler.define 'DYNAMIC_CAMERA_SERVER_DEBUG' + } + } else { + lib project: ':cscore', library: 'cscore', linkage: 'shared' + lib project: ':cameraserver', library: 'cameraserver', linkage: 'shared' + } + } appendDebugPathToBinaries(binaries) } diff --git a/wpilibc/src/main/native/cpp/shuffleboard/SendableCameraWrapper.cpp b/wpilibc/src/main/native/cpp/shuffleboard/SendableCameraWrapper.cpp index 97add4aabd..b6f8ce984d 100644 --- a/wpilibc/src/main/native/cpp/shuffleboard/SendableCameraWrapper.cpp +++ b/wpilibc/src/main/native/cpp/shuffleboard/SendableCameraWrapper.cpp @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */ +/* Copyright (c) 2019 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. */ @@ -7,41 +7,30 @@ #include "frc/shuffleboard/SendableCameraWrapper.h" -#include +#include +#include +#include + #include #include "frc/smartdashboard/SendableBuilder.h" #include "frc/smartdashboard/SendableRegistry.h" -using namespace frc; - -namespace { -constexpr const char* kProtocol = "camera_server://"; -wpi::DenseMap> wrappers; -} // namespace - -SendableCameraWrapper& SendableCameraWrapper::Wrap( - const cs::VideoSource& source) { - return Wrap(source.GetHandle()); +namespace frc { +namespace detail { +std::shared_ptr& GetSendableCameraWrapper( + CS_Source source) { + static wpi::DenseMap> wrappers; + return wrappers[static_cast(source)]; } -SendableCameraWrapper& SendableCameraWrapper::Wrap(CS_Source source) { - auto& wrapper = wrappers[static_cast(source)]; - if (!wrapper) - wrapper = std::make_unique(source, private_init{}); - return *wrapper; -} - -SendableCameraWrapper::SendableCameraWrapper(CS_Source source, - const private_init&) - : m_uri(kProtocol) { - CS_Status status = 0; - auto name = cs::GetSourceName(source, &status); - SendableRegistry::GetInstance().Add(this, name); - m_uri += name; +void AddToSendableRegistry(frc::Sendable* sendable, std::string name) { + SendableRegistry::GetInstance().Add(sendable, name); } +} // namespace detail void SendableCameraWrapper::InitSendable(SendableBuilder& builder) { builder.AddStringProperty(".ShuffleboardURI", [this] { return m_uri; }, nullptr); } +} // namespace frc diff --git a/wpilibc/src/main/native/cpp/shuffleboard/ShuffleboardContainer.cpp b/wpilibc/src/main/native/cpp/shuffleboard/ShuffleboardContainer.cpp index c36e537020..bb9dc9e93c 100644 --- a/wpilibc/src/main/native/cpp/shuffleboard/ShuffleboardContainer.cpp +++ b/wpilibc/src/main/native/cpp/shuffleboard/ShuffleboardContainer.cpp @@ -11,7 +11,6 @@ #include #include "frc/shuffleboard/ComplexWidget.h" -#include "frc/shuffleboard/SendableCameraWrapper.h" #include "frc/shuffleboard/ShuffleboardComponent.h" #include "frc/shuffleboard/ShuffleboardLayout.h" #include "frc/shuffleboard/SimpleWidget.h" @@ -75,11 +74,6 @@ ComplexWidget& ShuffleboardContainer::Add(const wpi::Twine& title, return *ptr; } -ComplexWidget& ShuffleboardContainer::Add(const wpi::Twine& title, - const cs::VideoSource& video) { - return Add(title, SendableCameraWrapper::Wrap(video)); -} - ComplexWidget& ShuffleboardContainer::Add(Sendable& sendable) { auto name = SendableRegistry::GetInstance().GetName(&sendable); if (name.empty()) { @@ -88,10 +82,6 @@ ComplexWidget& ShuffleboardContainer::Add(Sendable& sendable) { return Add(name, sendable); } -ComplexWidget& ShuffleboardContainer::Add(const cs::VideoSource& video) { - return Add(SendableCameraWrapper::Wrap(video)); -} - SimpleWidget& ShuffleboardContainer::Add( const wpi::Twine& title, std::shared_ptr defaultValue) { CheckTitle(title); diff --git a/wpilibc/src/main/native/cpp/RobotBase.cpp b/wpilibc/src/main/native/cppcs/RobotBase.cpp similarity index 78% rename from wpilibc/src/main/native/cpp/RobotBase.cpp rename to wpilibc/src/main/native/cppcs/RobotBase.cpp index 8cf0633232..65c072d12f 100644 --- a/wpilibc/src/main/native/cpp/RobotBase.cpp +++ b/wpilibc/src/main/native/cppcs/RobotBase.cpp @@ -7,10 +7,13 @@ #include "frc/RobotBase.h" +#ifdef __FRC_ROBORIO__ +#include +#endif + #include #include -#include #include #include @@ -22,6 +25,8 @@ #include "frc/livewindow/LiveWindow.h" #include "frc/smartdashboard/SmartDashboard.h" +typedef void (*SetCameraServerSharedFP)(frc::CameraServerShared* shared); + using namespace frc; int frc::RunHALInitialization() { @@ -65,7 +70,36 @@ class WPILibCameraServerShared : public frc::CameraServerShared { } // namespace static void SetupCameraServerShared() { - SetCameraServerShared(std::make_unique()); +#ifdef __FRC_ROBORIO__ +#ifdef DYNAMIC_CAMERA_SERVER +#ifdef DYNAMIC_CAMERA_SERVER_DEBUG + auto cameraServerLib = dlopen("libcameraserverd.so", RTLD_NOW); +#else + auto cameraServerLib = dlopen("libcameraserver.so", RTLD_NOW); +#endif + + if (!cameraServerLib) { + wpi::outs() << "Camera Server Library Not Found\n"; + wpi::outs().flush(); + return; + } + auto symbol = dlsym(cameraServerLib, "CameraServer_SetCameraServerShared"); + if (symbol) { + auto setCameraServerShared = (SetCameraServerSharedFP)symbol; + setCameraServerShared(new WPILibCameraServerShared{}); + wpi::outs() << "Set Camera Server Shared\n"; + wpi::outs().flush(); + } else { + wpi::outs() << "Camera Server Shared Symbol Missing\n"; + wpi::outs().flush(); + } +#else + CameraServer_SetCameraServerShared(new WPILibCameraServerShared{}); +#endif +#else + wpi::outs() << "Not loading CameraServerShared\n"; + wpi::outs().flush(); +#endif } bool RobotBase::IsEnabled() const { return m_ds.IsEnabled(); } @@ -121,6 +155,6 @@ RobotBase::RobotBase() : m_ds(DriverStation::GetInstance()) { RobotBase::RobotBase(RobotBase&&) noexcept : m_ds(DriverStation::GetInstance()) {} -RobotBase::~RobotBase() { cs::Shutdown(); } +RobotBase::~RobotBase() {} RobotBase& RobotBase::operator=(RobotBase&&) noexcept { return *this; } diff --git a/wpilibc/src/main/native/include/frc/shuffleboard/SendableCameraWrapper.h b/wpilibc/src/main/native/include/frc/shuffleboard/SendableCameraWrapper.h index b1a46d304e..5610cf8e17 100644 --- a/wpilibc/src/main/native/include/frc/shuffleboard/SendableCameraWrapper.h +++ b/wpilibc/src/main/native/include/frc/shuffleboard/SendableCameraWrapper.h @@ -7,19 +7,34 @@ #pragma once +#include +#include #include -#include +#ifndef DYNAMIC_CAMERA_SERVER +#include +#else +namespace cs { +class VideoSource; +} // namespace cs +typedef int CS_Handle; +typedef CS_Handle CS_Source; +#endif #include "frc/smartdashboard/Sendable.h" #include "frc/smartdashboard/SendableHelper.h" -namespace cs { -class VideoSource; -} // namespace cs - namespace frc { +class SendableCameraWrapper; + +namespace detail { +constexpr const char* kProtocol = "camera_server://"; +std::shared_ptr& GetSendableCameraWrapper( + CS_Source source); +void AddToSendableRegistry(Sendable* sendable, std::string name); +} // namespace detail + /** * A wrapper to make video sources sendable and usable from Shuffleboard. */ @@ -54,4 +69,27 @@ class SendableCameraWrapper : public Sendable, std::string m_uri; }; +#ifndef DYNAMIC_CAMERA_SERVER +inline SendableCameraWrapper::SendableCameraWrapper(CS_Source source, + const private_init&) + : m_uri(detail::kProtocol) { + CS_Status status = 0; + auto name = cs::GetSourceName(source, &status); + detail::AddToSendableRegistry(this, name); + m_uri += name; +} + +inline SendableCameraWrapper& SendableCameraWrapper::Wrap( + const cs::VideoSource& source) { + return Wrap(source.GetHandle()); +} + +inline SendableCameraWrapper& SendableCameraWrapper::Wrap(CS_Source source) { + auto& wrapper = detail::GetSendableCameraWrapper(source); + if (!wrapper) + wrapper = std::make_shared(source, private_init{}); + return *wrapper; +} +#endif + } // namespace frc diff --git a/wpilibc/src/main/native/include/frc/shuffleboard/ShuffleboardContainer.h b/wpilibc/src/main/native/include/frc/shuffleboard/ShuffleboardContainer.h index d7a11c0da0..7b8b49d75e 100644 --- a/wpilibc/src/main/native/include/frc/shuffleboard/ShuffleboardContainer.h +++ b/wpilibc/src/main/native/include/frc/shuffleboard/ShuffleboardContainer.h @@ -501,3 +501,17 @@ class ShuffleboardContainer : public virtual ShuffleboardValue, #include "frc/shuffleboard/ComplexWidget.h" #include "frc/shuffleboard/ShuffleboardLayout.h" #include "frc/shuffleboard/SimpleWidget.h" + +#ifndef DYNAMIC_CAMERA_SERVER +#include "frc/shuffleboard/SendableCameraWrapper.h" + +inline frc::ComplexWidget& frc::ShuffleboardContainer::Add( + const cs::VideoSource& video) { + return Add(frc::SendableCameraWrapper::Wrap(video)); +} + +inline frc::ComplexWidget& frc::ShuffleboardContainer::Add( + const wpi::Twine& title, const cs::VideoSource& video) { + return Add(title, frc::SendableCameraWrapper::Wrap(video)); +} +#endif diff --git a/wpiutil/src/main/native/windows/StackWalker.cpp b/wpiutil/src/main/native/windows/StackWalker.cpp index 06a82e8745..237360a793 100644 --- a/wpiutil/src/main/native/windows/StackWalker.cpp +++ b/wpiutil/src/main/native/windows/StackWalker.cpp @@ -88,6 +88,7 @@ #include #include #pragma comment(lib, "version.lib") // for "VerQueryValue" +#pragma comment(lib, "Advapi32.lib") // for "GetUserName" #pragma warning(disable : 4826) #ifdef UNICODE @@ -484,8 +485,8 @@ private: if (hToolhelp == NULL) continue; createToolhelp32Snapshot = (tCT32S)GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot"); - module32First = (tM32F)GetProcAddress(hToolhelp, strModule32First); - module32Next = (tM32N)GetProcAddress(hToolhelp, strModule32Next); + module32First = (tM32F)GetProcAddress(hToolhelp, strModule32First); + module32Next = (tM32N)GetProcAddress(hToolhelp, strModule32Next); if ((createToolhelp32Snapshot != NULL) && (module32First != NULL) && (module32Next != NULL)) break; // found the functions! FreeLibrary(hToolhelp);