diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1d1ae8fc831..eddfd8065b5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -72,6 +72,7 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/device.cpp" "${CMAKE_CURRENT_LIST_DIR}/device-info.cpp" "${CMAKE_CURRENT_LIST_DIR}/device_hub.cpp" + "${CMAKE_CURRENT_LIST_DIR}/rscore/device-factory.h" "${CMAKE_CURRENT_LIST_DIR}/environment.cpp" "${CMAKE_CURRENT_LIST_DIR}/error-handling.cpp" "${CMAKE_CURRENT_LIST_DIR}/firmware_logger_device.cpp" diff --git a/src/backend-device-factory.cpp b/src/backend-device-factory.cpp index c05d928df2c..3edfb6240ba 100644 --- a/src/backend-device-factory.cpp +++ b/src/backend-device-factory.cpp @@ -124,7 +124,7 @@ std::shared_ptr< platform::backend > backend_device::get_backend() backend_device_factory::backend_device_factory( context & ctx, callback && cb ) - : _context( ctx ) + : super( ctx ) , _device_watcher( backend_device_watcher.instance() ) , _dtor( _device_watcher->subscribe( [this, cb = std::move( cb )]( platform::backend_device_group const & old, diff --git a/src/backend-device-factory.h b/src/backend-device-factory.h index 0c5fc5a00f4..1b71faf922b 100644 --- a/src/backend-device-factory.h +++ b/src/backend-device-factory.h @@ -3,19 +3,13 @@ #pragma once +#include #include -#include -#include - - -struct rs2_device_info; namespace librealsense { -class device_info; -class context; class device_watcher_singleton; @@ -35,23 +29,21 @@ class platform_device_info; // manages these device-info objects such that lifetime is tracked and updated appropriately, without the caller's // knowledge. // -class backend_device_factory +class backend_device_factory : public device_factory { - context & _context; + typedef device_factory super; + std::shared_ptr< device_watcher_singleton > const _device_watcher; rsutils::subscription const _dtor; // raii generic code, used to automatically unsubscribe our callback public: - using callback = std::function< void( std::vector< rs2_device_info > & rs2_devices_info_removed, - std::vector< rs2_device_info > & rs2_devices_info_added ) >; - backend_device_factory( context &, callback && ); ~backend_device_factory(); // Query any subset of available devices and return them as device-info objects // Devices will match both the requested mask and the device-mask from the context settings // - std::vector< std::shared_ptr< device_info > > query_devices( unsigned mask ) const; + std::vector< std::shared_ptr< device_info > > query_devices( unsigned mask ) const override; private: std::vector< std::shared_ptr< platform::platform_device_info > > diff --git a/src/context.cpp b/src/context.cpp index 1322fdf10e1..89fb99e2848 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -4,6 +4,11 @@ #include "context.h" #include "media/playback/playback-device-info.h" +#include "backend-device-factory.h" +#ifdef BUILD_WITH_DDS +#include "dds/rsdds-device-factory.h" +#endif + #include #include using json = nlohmann::json; @@ -15,15 +20,6 @@ namespace librealsense : _settings( settings ) , _device_mask( rsutils::json::get< unsigned >( settings, "device-mask", RS2_PRODUCT_LINE_ANY ) ) , _devices_changed_callback( nullptr, []( rs2_devices_changed_callback * ) {} ) - , _backend_device_factory( - *this, - [this]( std::vector< rs2_device_info > & removed, std::vector< rs2_device_info > & added ) - { invoke_devices_changed_callbacks( removed, added ); } ) -#ifdef BUILD_WITH_DDS - , _dds_device_factory( *this, - [this]( std::vector< rs2_device_info > & removed, std::vector< rs2_device_info > & added ) - { invoke_devices_changed_callbacks( removed, added ); } ) -#endif { static bool version_logged = false; if( ! version_logged ) @@ -31,6 +27,18 @@ namespace librealsense version_logged = true; LOG_DEBUG( "Librealsense VERSION: " << RS2_API_VERSION_STR ); } + + _factories.push_back( std::make_shared< backend_device_factory >( + *this, + [this]( std::vector< rs2_device_info > & removed, std::vector< rs2_device_info > & added ) + { invoke_devices_changed_callbacks( removed, added ); } ) ); + +#ifdef BUILD_WITH_DDS + _factories.push_back( std::make_shared< rsdds_device_factory >( + *this, + [this]( std::vector< rs2_device_info > & removed, std::vector< rs2_device_info > & added ) + { invoke_devices_changed_callbacks( removed, added ); } ) ); +#endif } @@ -57,39 +65,31 @@ namespace librealsense } - std::vector> context::query_devices( int requested_mask ) const + std::vector< std::shared_ptr< device_info > > context::query_devices( int requested_mask ) const { - auto list = _backend_device_factory.query_devices( requested_mask ); - query_software_devices( list, requested_mask ); + std::vector< std::shared_ptr< device_info > > list; + for( auto & factory : _factories ) + { + for( auto & dev_info : factory->query_devices( requested_mask ) ) + { + LOG_INFO( "... " << dev_info->get_address() ); + list.push_back( dev_info ); + } + } + for( auto & item : _playback_devices ) + { + if( auto dev_info = item.second.lock() ) + { + LOG_INFO( "... " << dev_info->get_address() ); + list.push_back( dev_info ); + } + } LOG_INFO( "Found " << list.size() << " RealSense devices (0x" << std::hex << requested_mask << " requested & 0x" << get_device_mask() << " from device-mask in settings)" << std::dec ); - for( auto & item : list ) - LOG_INFO( "... " << item->get_address() ); return list; } - void context::query_software_devices( std::vector< std::shared_ptr< device_info > > & list, unsigned requested_mask ) const - { - unsigned mask = combine_device_masks( requested_mask, get_device_mask() ); - - auto t = const_cast(this); // While generally a bad idea, we need to provide mutable reference to the devices - // to allow them to modify context later on - auto ctx = t->shared_from_this(); - -#ifdef BUILD_WITH_DDS - for( auto & info : _dds_device_factory.query_devices( requested_mask ) ) - list.push_back( info ); -#endif //BUILD_WITH_DDS - - for( auto && item : _playback_devices ) - { - if( auto dev = item.second.lock() ) - list.push_back( dev ); - } - } - - void context::invoke_devices_changed_callbacks( std::vector & rs2_devices_info_removed, std::vector & rs2_devices_info_added ) { diff --git a/src/context.h b/src/context.h index af03fe4f31b..c40ae7ec6a1 100644 --- a/src/context.h +++ b/src/context.h @@ -3,10 +3,7 @@ #pragma once -#include "backend-device-factory.h" -#ifdef BUILD_WITH_DDS -#include "dds/rsdds-device-factory.h" -#endif +#include #include "types.h" // devices_changed_callback_ptr #include @@ -72,8 +69,6 @@ namespace librealsense void unregister_internal_device_callback(uint64_t cb_id); void set_devices_changed_callback(devices_changed_callback_ptr callback); - void query_software_devices( std::vector< std::shared_ptr< device_info > > & list, unsigned requested_mask ) const; - std::shared_ptr add_device(const std::string& file); void remove_device(const std::string& file); @@ -91,10 +86,8 @@ namespace librealsense nlohmann::json _settings; // Save operation settings unsigned const _device_mask; - backend_device_factory _backend_device_factory; -#ifdef BUILD_WITH_DDS - rsdds_device_factory _dds_device_factory; -#endif + + std::vector< std::shared_ptr< device_factory > > _factories; devices_changed_callback_ptr _devices_changed_callback; std::map> _streams; diff --git a/src/dds/rsdds-device-factory.cpp b/src/dds/rsdds-device-factory.cpp index 128fbe787da..0716c977e5c 100644 --- a/src/dds/rsdds-device-factory.cpp +++ b/src/dds/rsdds-device-factory.cpp @@ -79,7 +79,7 @@ static std::mutex domain_context_by_id_mutex; rsdds_device_factory::rsdds_device_factory( context & ctx, callback && cb ) - : _context( ctx ) + : super( ctx ) { nlohmann::json dds_settings = rsutils::json::get< nlohmann::json >( _context.get_settings(), std::string( "dds", 3 ), diff --git a/src/dds/rsdds-device-factory.h b/src/dds/rsdds-device-factory.h index 57a764115cf..2fa2f053912 100644 --- a/src/dds/rsdds-device-factory.h +++ b/src/dds/rsdds-device-factory.h @@ -3,12 +3,8 @@ #pragma once +#include #include -#include -#include - - -struct rs2_device_info; namespace realdds { @@ -19,8 +15,6 @@ class dds_participant; namespace librealsense { -class device_info; -class context; class rsdds_watcher_singleton; @@ -31,24 +25,22 @@ class rsdds_watcher_singleton; // // Any devices created here will have a device-info that derives from dds_device_info. // -class rsdds_device_factory +class rsdds_device_factory : public device_factory { - context & _context; + typedef device_factory super; + std::shared_ptr< realdds::dds_participant > _participant; std::shared_ptr< rsdds_watcher_singleton > _watcher_singleton; rsutils::subscription _subscription; public: - using callback = std::function< void( std::vector< rs2_device_info > & rs2_devices_info_removed, - std::vector< rs2_device_info > & rs2_devices_info_added ) >; - rsdds_device_factory( context &, callback && ); ~rsdds_device_factory(); // Query any subset of available devices and return them as device-info objects // Devices will match both the requested mask and the device-mask from the context settings // - std::vector< std::shared_ptr< device_info > > query_devices( unsigned mask ) const; + std::vector< std::shared_ptr< device_info > > query_devices( unsigned mask ) const override; }; diff --git a/src/rscore/device-factory.h b/src/rscore/device-factory.h new file mode 100644 index 00000000000..592f45304b8 --- /dev/null +++ b/src/rscore/device-factory.h @@ -0,0 +1,57 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2023 Intel Corporation. All Rights Reserved. + +#pragma once + +#include +#include +#include + + +struct rs2_device_info; + + +namespace librealsense { + + +class device_info; +class context; + + +// Interface for device factories, allowing for: +// - notification callbacks for any device additions and removals +// - querying of current devices in the system +// +// A device factory is contained by a context, 1:1. I.e., multiple factory instances may exist at once, each for a +// different context. +// + +class device_factory +{ +protected: + context & _context; + + device_factory( context & ctx ) + : _context( ctx ) + { + } + +public: + // Callbacks take this form. + // + using callback = std::function< void( std::vector< rs2_device_info > & devices_removed, + std::vector< rs2_device_info > & devices_added ) >; + + virtual ~device_factory() = default; + + // Query any subset of available devices and return them as device-info objects from which actual devices can be + // created as needed. + // + // Devices will match both the requested mask and the device-mask from the context settings. See + // RS2_PRODUCT_LINE_... defines for possible values. + // + virtual std::vector< std::shared_ptr< device_info > > query_devices( unsigned mask ) const = 0; +}; + + +} // namespace librealsense