Skip to content

Commit

Permalink
PR IntelRealSense#12265 from Eran: rsdds-device-factory : rscore/devi…
Browse files Browse the repository at this point in the history
…ce-factory
  • Loading branch information
maloel authored Oct 9, 2023
2 parents e360c4b + fbccf40 commit 9d9429e
Show file tree
Hide file tree
Showing 15 changed files with 335 additions and 180 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion src/backend-device-factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
18 changes: 5 additions & 13 deletions src/backend-device-factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,13 @@

#pragma once

#include <rscore/device-factory.h>
#include <rsutils/subscription.h>
#include <memory>
#include <vector>


struct rs2_device_info;


namespace librealsense {


class device_info;
class context;
class device_watcher_singleton;


Expand All @@ -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 > >
Expand Down
178 changes: 33 additions & 145 deletions src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,24 @@
// Copyright(c) 2015 Intel Corporation. All Rights Reserved.

#include "context.h"

#include "media/playback/playback-device-info.h"
#include "environment.h"
#include <src/backend.h>


#include "backend-device-factory.h"
#ifdef BUILD_WITH_DDS
#include "dds/rs-dds-device-info.h"

#include <realdds/dds-device-watcher.h>
#include <realdds/dds-participant.h>
#include <realdds/dds-device.h>
#include <realdds/topics/device-info-msg.h>
#include <rsutils/shared-ptr-singleton.h>
#include <rsutils/os/executable-name.h>
#include <rsutils/string/slice.h>

// We manage one participant and device-watcher per domain:
// Two contexts with the same domain-id will share the same participant and watcher, while a third context on a
// different domain will have its own.
//
struct dds_domain_context
{
rsutils::shared_ptr_singleton< realdds::dds_participant > participant;
rsutils::shared_ptr_singleton< realdds::dds_device_watcher > device_watcher;
};
//
// Domains are mapped by ID:
// Two contexts with the same participant name on different domain-ids are using two different participants!
//
static std::map< realdds::dds_domain_id, dds_domain_context > dds_domain_context_by_id;

#endif // BUILD_WITH_DDS
#include "dds/rsdds-device-factory.h"
#endif

#include <rsutils/string/from.h>
#include <rsutils/json.h>
using json = nlohmann::json;


namespace librealsense
{
context::context( json const & settings )
: _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 ); } )
{
static bool version_logged = false;
if( ! version_logged )
Expand All @@ -57,39 +28,17 @@ namespace librealsense
LOG_DEBUG( "Librealsense VERSION: " << RS2_API_VERSION_STR );
}

#ifdef BUILD_WITH_DDS
nlohmann::json dds_settings
= rsutils::json::get< nlohmann::json >( settings, std::string( "dds", 3 ), nlohmann::json::object() );
if( dds_settings.is_object() )
{
realdds::dds_domain_id domain_id
= rsutils::json::get< int >( dds_settings, std::string( "domain", 6 ), 0 );
std::string participant_name = rsutils::json::get< std::string >( dds_settings,
std::string( "participant", 11 ),
rsutils::os::executable_name() );

auto & domain = dds_domain_context_by_id[domain_id];
_dds_participant = domain.participant.instance();
if( ! _dds_participant->is_valid() )
{
_dds_participant->init( domain_id, participant_name, std::move( dds_settings ) );
}
else if( rsutils::json::has_value( dds_settings, std::string( "participant", 11 ) )
&& participant_name != _dds_participant->name() )
{
throw std::runtime_error( rsutils::string::from() << "A DDS participant '" << _dds_participant->name()
<< "' already exists in domain " << domain_id
<< "; cannot create '" << participant_name << "'" );
}
_dds_watcher = domain.device_watcher.instance( _dds_participant );
_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 ); } ) );

// The DDS device watcher should always be on
if( _dds_watcher && _dds_watcher->is_stopped() )
{
start_dds_device_watcher();
}
}
#endif //BUILD_WITH_DDS
#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
}


Expand All @@ -101,10 +50,6 @@ namespace librealsense

context::~context()
{
#ifdef BUILD_WITH_DDS
if( _dds_watcher )
_dds_watcher->stop();
#endif //BUILD_WITH_DDS
}


Expand All @@ -120,65 +65,31 @@ namespace librealsense
}


std::vector<std::shared_ptr<device_info>> 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<context *>(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
if( _dds_watcher )
_dds_watcher->foreach_device(
[&]( std::shared_ptr< realdds::dds_device > const & dev ) -> bool
{
if( !dev->is_ready() )
{
LOG_DEBUG( "device '" << dev->device_info().debug_name() << "' is not yet ready" );
return true;
}
if( dev->device_info().product_line == "D400" )
{
if( !(mask & RS2_PRODUCT_LINE_D400) )
return true;
}
else if( dev->device_info().product_line == "D500" )
{
if( !(mask & RS2_PRODUCT_LINE_D500) )
return true;
}
else if( !(mask & RS2_PRODUCT_LINE_NON_INTEL) )
{
return true;
}

std::shared_ptr< device_info > info = std::make_shared< dds_device_info >( ctx, dev );
list.push_back( info );
return true;
} );
#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_device_info> & rs2_devices_info_removed,
std::vector<rs2_device_info> & rs2_devices_info_added )
{
Expand Down Expand Up @@ -225,29 +136,6 @@ namespace librealsense
}


#ifdef BUILD_WITH_DDS
void context::start_dds_device_watcher()
{
_dds_watcher->on_device_added( [this]( std::shared_ptr< realdds::dds_device > const & dev ) {
dev->wait_until_ready(); // make sure handshake is complete

std::vector<rs2_device_info> rs2_device_info_added;
std::vector<rs2_device_info> rs2_device_info_removed;
auto info = std::make_shared< dds_device_info >( shared_from_this(), dev );
rs2_device_info_added.push_back( { shared_from_this(), info } );
invoke_devices_changed_callbacks( rs2_device_info_removed, rs2_device_info_added );
} );
_dds_watcher->on_device_removed( [this]( std::shared_ptr< realdds::dds_device > const & dev ) {
std::vector<rs2_device_info> rs2_device_info_added;
std::vector<rs2_device_info> rs2_device_info_removed;
auto info = std::make_shared< dds_device_info >( shared_from_this(), dev );
rs2_device_info_removed.push_back( { shared_from_this(), info } );
invoke_devices_changed_callbacks( rs2_device_info_removed, rs2_device_info_added );
} );
_dds_watcher->start();
}
#endif //BUILD_WITH_DDS

uint64_t context::register_internal_device_callback(devices_changed_callback_ptr callback)
{
std::lock_guard<std::mutex> lock(_devices_changed_callbacks_mtx);
Expand Down
21 changes: 3 additions & 18 deletions src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#pragma once

#include "backend-device-factory.h"
#include "types.h" // devices_changed_callback_ptr

#include <rsutils/lazy.h>
Expand Down Expand Up @@ -38,18 +37,11 @@ struct rs2_stream_profile
};


#ifdef BUILD_WITH_DDS
namespace realdds {
class dds_device_watcher;
class dds_participant;
} // namespace realdds
#endif


namespace librealsense
{
class playback_device_info;
class stream_interface;
class device_factory;

class context : public std::enable_shared_from_this<context>
{
Expand Down Expand Up @@ -77,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<playback_device_info> add_device(const std::string& file);
void remove_device(const std::string& file);

Expand All @@ -93,16 +83,11 @@ namespace librealsense

std::map<std::string, std::weak_ptr<device_info>> _playback_devices;
std::map<uint64_t, devices_changed_callback_ptr> _devices_changed_callbacks;
#ifdef BUILD_WITH_DDS
std::shared_ptr< realdds::dds_participant > _dds_participant;
std::shared_ptr< realdds::dds_device_watcher > _dds_watcher;

void start_dds_device_watcher();
#endif

nlohmann::json _settings; // Save operation settings
unsigned const _device_mask;
backend_device_factory _backend_device_factory;

std::vector< std::shared_ptr< device_factory > > _factories;

devices_changed_callback_ptr _devices_changed_callback;
std::map<int, std::weak_ptr<const stream_interface>> _streams;
Expand Down
Loading

0 comments on commit 9d9429e

Please sign in to comment.