From 84b3a127a851d9c06e1f8b2277270776f7ddece5 Mon Sep 17 00:00:00 2001 From: "Kevin M. Godby" Date: Fri, 23 Sep 2016 12:11:41 -0500 Subject: [PATCH] Added PluginKit API for plugins to trigger hardware detection. --- examples/plugin/CMakeLists.txt | 4 +- ...org_osvr_example_TriggerHardwareDetect.cpp | 114 ++++++++++++++++++ .../PluginSpecificRegistrationContext.h | 3 + inc/osvr/PluginKit/PluginKit.h | 6 + inc/osvr/PluginKit/PluginRegistration.h | 14 ++- inc/osvr/PluginKit/PluginRegistrationC.h | 14 ++- .../PluginSpecificRegistrationContextImpl.cpp | 10 ++ .../PluginSpecificRegistrationContextImpl.h | 3 + src/osvr/PluginKit/PluginRegistrationC.cpp | 17 ++- 9 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 examples/plugin/org_osvr_example_TriggerHardwareDetect.cpp diff --git a/examples/plugin/CMakeLists.txt b/examples/plugin/CMakeLists.txt index 00604e724..2b69cc49d 100644 --- a/examples/plugin/CMakeLists.txt +++ b/examples/plugin/CMakeLists.txt @@ -6,7 +6,8 @@ set(OSVR_EXAMPLE_DEVICE_PLUGINS_SIMPLE com_osvr_example_EyeTracker com_osvr_example_Locomotion com_osvr_example_MultipleAsync - org_osvr_example_Tracker) + org_osvr_example_Tracker + org_osvr_example_TriggerHardwareDetect) # These are all the plugin targets: one listed only here need more careful configuration. set(OSVR_EXAMPLE_DEVICE_PLUGINS @@ -41,6 +42,7 @@ foreach(pluginname com_osvr_example_EyeTracker com_osvr_example_Locomotion org_osvr_example_Tracker + org_osvr_example_TriggerHardwareDetect com_osvr_example_MultipleAsync) target_link_libraries(${pluginname} osvr_cxx11_flags) endforeach() diff --git a/examples/plugin/org_osvr_example_TriggerHardwareDetect.cpp b/examples/plugin/org_osvr_example_TriggerHardwareDetect.cpp new file mode 100644 index 000000000..92ab25483 --- /dev/null +++ b/examples/plugin/org_osvr_example_TriggerHardwareDetect.cpp @@ -0,0 +1,114 @@ +/** @date 2016 + @author + Sensics, Inc. + +*/ + +// Copyright 2016 Sensics Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Internal Includes +#include +#include +#include +#include + +// Library/third-party includes + +// Standard includes +#include +#include +#include +#include + + +// Anonymous namespace to avoid symbol collision +namespace { + +/** + * @brief This fake device just triggers an autodetect every few seconds. + */ +class FakeDevice { + public: + FakeDevice(OSVR_PluginRegContext ctx) : m_context(ctx) { + /// Create the initialization options + OSVR_DeviceInitOptions opts = osvrDeviceCreateInitOptions(ctx); + + // configure our tracker + osvrDeviceButtonConfigure(opts, &m_button, 1); + + /// Create the device token with the options + m_dev.initAsync(ctx, "Hardware detection trigger", opts); + + /// Send JSON descriptor + //m_dev.sendJsonDescriptor("{}"); + + /// Register update callback + m_dev.registerUpdateCallback(this); + } + + OSVR_ReturnCode update() { + std::this_thread::sleep_for(std::chrono::seconds(3)); + + osvr::pluginkit::triggerHardwareDetect(m_context); + + return OSVR_RETURN_SUCCESS; + } + + private: + OSVR_PluginRegContext m_context; + osvr::pluginkit::DeviceToken m_dev; + OSVR_ButtonDeviceInterface m_button; +}; + +class HardwareDetection { + public: + HardwareDetection() : m_found(false), m_count(0), m_mutex() + { + logger_ = osvr::util::log::make_logger("org_osvr_example_TriggerHardwareDetect"); + } + + OSVR_ReturnCode operator()(OSVR_PluginRegContext ctx) { + std::lock_guard guard(m_mutex); + + m_count++; + logger_->info() << "Hardware detection triggered " << m_count << " times."; + + if (m_found) + return OSVR_RETURN_SUCCESS; + + osvr::pluginkit::registerObjectForDeletion(ctx, new FakeDevice(ctx)); + m_found = true; + + return OSVR_RETURN_SUCCESS; + } + + private: + bool m_found; + int m_count; + std::mutex m_mutex; + osvr::util::log::LoggerPtr logger_; +}; + +} // namespace + +OSVR_PLUGIN(org_osvr_example_TriggerHardwareDetect) { + osvr::pluginkit::PluginContext context(ctx); + + /// Register a detection callback function object. + context.registerHardwareDetectCallback(new HardwareDetection()); + + return OSVR_RETURN_SUCCESS; +} + diff --git a/inc/osvr/PluginHost/PluginSpecificRegistrationContext.h b/inc/osvr/PluginHost/PluginSpecificRegistrationContext.h index f8c7f3024..1826dcced 100644 --- a/inc/osvr/PluginHost/PluginSpecificRegistrationContext.h +++ b/inc/osvr/PluginHost/PluginSpecificRegistrationContext.h @@ -132,6 +132,9 @@ namespace pluginhost { /// @brief Accessor for plugin name. OSVR_PLUGINHOST_EXPORT const std::string &getName() const; + /// @brief Trigger system-wide hardware detection. + OSVR_PLUGINHOST_EXPORT virtual void triggerHardwareDetect() = 0; + /// @brief Log a message to the plugin-specific channel. /// /// @param severity The severity of the message. diff --git a/inc/osvr/PluginKit/PluginKit.h b/inc/osvr/PluginKit/PluginKit.h index 5b2d66ae7..336373372 100644 --- a/inc/osvr/PluginKit/PluginKit.h +++ b/inc/osvr/PluginKit/PluginKit.h @@ -94,6 +94,12 @@ namespace pluginkit { return ::osvr::pluginkit::registerObjectForDeletion(m_ctx, obj); } + /// @brief Triggers system-wide hardware detection. + /// @sa ::osvr::pluginkit::triggerHardwareDetect. + void triggerHardwareDetect() { + ::osvr::pluginkit::triggerHardwareDetect(m_ctx); + } + /// @brief Log a message to the plugin-specific channel. /// /// @param severity The severity of the log message. diff --git a/inc/osvr/PluginKit/PluginRegistration.h b/inc/osvr/PluginKit/PluginRegistration.h index df739ed33..9783255a4 100644 --- a/inc/osvr/PluginKit/PluginRegistration.h +++ b/inc/osvr/PluginKit/PluginRegistration.h @@ -197,12 +197,24 @@ namespace pluginkit { "registerDriverInstantiationCallback failed!"); } } - /// @} + + /// @brief Triggers system-wide hardware detection. + /// + /// @param ctx The registration context passed to your entry point. + /// + /// @sa PluginContext::triggerHardwareDetect + inline void triggerHardwareDetect(OSVR_PluginRegContext ctx) { + const OSVR_ReturnCode ret = osvrPluginTriggerHardwareDetect(ctx); + if (ret != OSVR_RETURN_SUCCESS) { + throw std::runtime_error("triggerHardwareDetect failed!"); + } + } inline void log(OSVR_PluginRegContext ctx, OSVR_LogLevel severity, const char *message) { osvrPluginLog(ctx, severity, message); } + /// @} } // namespace pluginkit } // namespace osvr diff --git a/inc/osvr/PluginKit/PluginRegistrationC.h b/inc/osvr/PluginKit/PluginRegistrationC.h index c0daab154..f682eb79d 100644 --- a/inc/osvr/PluginKit/PluginRegistrationC.h +++ b/inc/osvr/PluginKit/PluginRegistrationC.h @@ -144,6 +144,17 @@ OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrPluginRegisterDataWithDeleteCallback( OSVR_INOUT_PTR void *pluginData) OSVR_FUNC_NONNULL((1, 2, 3)); /** @} */ +/** + * @brief Trigger system-wide hardware detection. + * + * This causes each plugin's hardware detection callback to be called prior to + * the next run of the server main loop. + * + * @param ctx The registration context passed to your entry point. + */ +OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrPluginTriggerHardwareDetect( + OSVR_INOUT_PTR OSVR_PluginRegContext ctx) OSVR_FUNC_NONNULL((1)); + /** * @brief Log a message to the plugin's log channel. * @@ -160,4 +171,5 @@ OSVR_EXTERN_C_END /** @} */ -#endif +#endif /* INCLUDED_PluginRegistrationC_h_GUID_C019DFA9_5B54_4791_B0A4_040EA20501BA */ + diff --git a/src/osvr/PluginHost/PluginSpecificRegistrationContextImpl.cpp b/src/osvr/PluginHost/PluginSpecificRegistrationContextImpl.cpp index 95668c371..4939fc2d0 100644 --- a/src/osvr/PluginHost/PluginSpecificRegistrationContextImpl.cpp +++ b/src/osvr/PluginHost/PluginSpecificRegistrationContextImpl.cpp @@ -26,6 +26,7 @@ // Internal Includes #include "PluginSpecificRegistrationContextImpl.h" +#include #include // Library/third-party includes @@ -169,5 +170,14 @@ namespace pluginhost { util::AnyMap const &PluginSpecificRegistrationContextImpl::data() const { return m_data; } + + void PluginSpecificRegistrationContextImpl::triggerHardwareDetect() { + if (m_parent == nullptr) { + throw std::logic_error( + "Can't access the registration context parent - it is null!"); + } + m_parent->triggerHardwareDetect(); + } + } // namespace pluginhost } // namespace osvr diff --git a/src/osvr/PluginHost/PluginSpecificRegistrationContextImpl.h b/src/osvr/PluginHost/PluginSpecificRegistrationContextImpl.h index 850131313..51abc0e52 100644 --- a/src/osvr/PluginHost/PluginSpecificRegistrationContextImpl.h +++ b/src/osvr/PluginHost/PluginSpecificRegistrationContextImpl.h @@ -115,6 +115,9 @@ namespace pluginhost { void *userData); /// @} + /// @brief Trigger system-wide hardware detection. + virtual void triggerHardwareDetect(); + private: /// @brief Pointer with ownership semantics for deletion of plugin data. typedef unique_ptr PluginDataPtr; diff --git a/src/osvr/PluginKit/PluginRegistrationC.cpp b/src/osvr/PluginKit/PluginRegistrationC.cpp index e7a380c5c..953a396f0 100644 --- a/src/osvr/PluginKit/PluginRegistrationC.cpp +++ b/src/osvr/PluginKit/PluginRegistrationC.cpp @@ -80,6 +80,22 @@ OSVR_ReturnCode osvrPluginRegisterDataWithDeleteCallback( return OSVR_RETURN_SUCCESS; } +OSVR_ReturnCode +osvrPluginTriggerHardwareDetect(OSVR_INOUT_PTR OSVR_PluginRegContext ctx) { + OSVR_PLUGIN_HANDLE_NULL_CONTEXT("osvrPluginTriggerHardwareDetect", ctx); + + try { + osvr::pluginhost::PluginSpecificRegistrationContext::get(ctx) + .triggerHardwareDetect(); + } catch (const std::exception &e) { + std::cerr << "Error in osvrPluginTriggerHardwareDetectCallback - " + "caught exception reporting: " + << e.what() << std::endl; + return OSVR_RETURN_FAILURE; + } + return OSVR_RETURN_SUCCESS; +} + void osvrPluginLog(OSVR_INOUT_PTR OSVR_PluginRegContext ctx, OSVR_IN OSVR_LogLevel severity, OSVR_IN const char *message) { @@ -93,4 +109,3 @@ void osvrPluginLog(OSVR_INOUT_PTR OSVR_PluginRegContext ctx, auto s = static_cast(severity); context->log(s, message); } -