You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
6.3 KiB

// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.
#include "pyrealsense2.h"
#include <librealsense2/hpp/rs_options.hpp>
using rsutils::json;
void init_options(py::module &m) {
/** rs_options.hpp **/
// Expose option values as a custom struct rather than 'rs2_option_value*'
struct option_value
{
rs2_option id;
rs2_option_type type;
py::object value;
option_value( rs2::option_value const & value_ )
: id( value_->id )
, type( value_->type )
{
if( ! value_->is_valid )
value = py::cast< py::none >( Py_None );
else if( RS2_OPTION_TYPE_FLOAT == value_->type )
value = py::float_( value_->as_float );
else if( RS2_OPTION_TYPE_STRING == value_->type )
value = py::str( value_->as_string );
else if( RS2_OPTION_TYPE_INTEGER == value_->type )
value = py::int_( value_->as_integer );
else if( RS2_OPTION_TYPE_BOOLEAN == value_->type )
value = py::bool_( value_->as_integer );
else
value = py::cast< py::none >( Py_None );
}
};
py::class_< option_value >( m, "option_value" )
.def_readwrite( "id", &option_value::id )
.def_readwrite( "value", &option_value::value ) // None if no value available
.def_readwrite( "type", &option_value::type )
.def( "__repr__",
[]( option_value const & self )
{
std::ostringstream os;
os << '<' << rs2_option_to_string( self.id );
os << ' ' << py::str( self.value );
os << '>';
return os.str();
} );
// given an iterator, return an option_value
struct option_value_from_iterator
{
option_value operator()( rs2::options_list::iterator const & it ) { return option_value( *it ); }
};
py::class_< rs2::options_list >( m, "options_list" )
.def( "__getitem__",
[]( const rs2::options_list & self, size_t i )
{
if( i >= self.size() )
throw py::index_error();
return option_value( self[i] );
} )
.def( "__len__", &rs2::options_list::size )
.def( "__iter__",
[]( const rs2::options_list & self )
{
return py::detail::make_iterator_impl< option_value_from_iterator, // how to access value from iterator
py::return_value_policy::reference_internal, // pybind default
rs2::options_list::iterator, // iterator type
rs2::options_list::iterator, // sentinel (end) type
option_value // value type
>( self.begin(), self.end() );
},
py::keep_alive< 0, 1 >() );
py::class_<rs2::options> options(m, "options", "Base class for options interface. Should be used via sensor or processing_block."); // No docstring in C++
options.def("is_option_read_only", &rs2::options::is_option_read_only, "Check if particular option "
"is read only.", "option"_a)
.def("get_option", &rs2::options::get_option, "Read option value from the device.", "option"_a, py::call_guard<py::gil_scoped_release>())
.def( "get_option_value",
[]( rs2::options const & self, rs2_option option_id ) -> option_value
{ return self.get_option_value( option_id ); } )
.def( "set_option_value",
[]( rs2::options const & self, rs2_option option_id, json value )
{
rs2::option_value rs2_value;
switch( value.type() )
{
case json::value_t::null:
rs2_value = rs2::option_value( option_id, rs2::option_value::invalid );
break;
case json::value_t::string:
rs2_value = rs2::option_value( option_id, value.string_ref().c_str() );
break;
case json::value_t::number_float:
rs2_value = rs2::option_value( option_id, value.get< float >() );
break;
case json::value_t::number_unsigned:
case json::value_t::number_integer:
rs2_value = rs2::option_value( option_id, value.get< int64_t >() );
break;
case json::value_t::boolean:
rs2_value = rs2::option_value( option_id, value.get< bool >() );
break;
default:
throw std::runtime_error( "invalid value type: " + value.dump() );
}
self.set_option_value( rs2_value );
} )
.def("get_option_range", &rs2::options::get_option_range, "Retrieve the available range of values "
"of a supported option", "option"_a, py::call_guard<py::gil_scoped_release>())
.def("set_option", &rs2::options::set_option, "Write new value to device option", "option"_a, "value"_a, py::call_guard<py::gil_scoped_release>())
.def("supports", (bool (rs2::options::*)(rs2_option option) const) &rs2::options::supports, "Check if particular "
"option is supported by a subdevice", "option"_a)
.def("get_option_description", &rs2::options::get_option_description, "Get option description.", "option"_a)
.def("get_option_value_description", &rs2::options::get_option_value_description, "Get option value description "
"(In case a specific option value holds special meaning)", "option"_a, "value"_a)
.def("get_supported_options", &rs2::options::get_supported_options, "Retrieve list of supported options") // No docstring in C++
.def( "on_options_changed", &rs2::options::on_options_changed,
"Sets a callback to notify in case options in this container change value", "callback"_a );
/** end rs_options.hpp **/
}