Loading...
Searching...
No Matches
property.hpp
Go to the documentation of this file.
//
// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#pragma once
#include <uhd/exception.hpp>
#include <uhd/rfnoc/res_source_info.hpp>
#include <uhd/utils/cast.hpp>
#include <uhd/utils/dirty_tracked.hpp>
#include <memory>
#include <string>
namespace uhd { namespace rfnoc {
// Forward declaration, separates includes
class prop_accessor_t;
class UHD_API property_base_t
{
public:
enum access_t {
NONE,
RO = 0x1,
RW = 0x3,
RWLOCKED = 0x5
};
property_base_t(const std::string& id, const res_source_info& source_info)
: _id(id), _source_info(source_info)
{
if (_id.find(':') != std::string::npos) {
throw uhd::value_error(
"Property ID `" + _id + "' contains invalid character!");
}
}
virtual ~property_base_t()
{
// nop
}
const std::string& get_id() const
{
return _id;
}
const res_source_info& get_src_info() const
{
return _source_info;
}
//
// If it's true, that means this property was recently changed, but changes
// have not propagated yet and still need resolving.
virtual bool is_dirty() const = 0;
//
// If it's false, that means this property has a default value that should
// NOT be forwarded.
virtual bool is_valid() const = 0;
bool read_access_granted() const
{
return static_cast<uint8_t>(_access_mode) & 0x1;
}
bool write_access_granted() const
{
return static_cast<uint8_t>(_access_mode) & 0x2;
}
access_t get_access_mode() const
{
return _access_mode;
}
virtual bool equal(property_base_t* rhs) const = 0;
//
// The copy must have the same type, value, and ID. However, it is often
// desirable to have a new source information, so that can be overridden.
//
// The cleanliness state of \p original is not preserved. The new property
// will have the same cleanliness state as any other new property.
//
virtual std::unique_ptr<property_base_t> clone(res_source_info)
{
throw uhd::not_implemented_error("Cloning is not available for this property.");
}
virtual void force_dirty() = 0;
virtual void set_from_str(const std::string& new_val_str) = 0;
private:
friend class prop_accessor_t;
virtual void mark_clean() = 0;
virtual void forward(property_base_t* next_prop) = 0;
//
// Note: This uses RTTI to evaluate type equality
virtual bool is_type_equal(property_base_t* other_prop) const = 0;
/*** Attributes **********************************************************/
const std::string _id;
const res_source_info _source_info;
// write this.
access_t _access_mode = RO;
};
template <typename data_t>
class UHD_API_HEADER property_t : public property_base_t
{
public:
using value_type = data_t;
property_t(const std::string& id, data_t&& value, const res_source_info& source_info);
property_t(
const std::string& id, const data_t& value, const res_source_info& source_info);
property_t(const std::string& id, const res_source_info& source_info);
property_t(const property_t<data_t>& prop) = default;
//
// If true, this means the value was recently changed, but it wasn't marked
// clean yet.
bool is_dirty() const override
{
return _data.is_dirty();
}
//
// If it's false, that means this property has a default value that should
// NOT be used.
bool is_valid() const override
{
return _valid;
}
bool equal(property_base_t* rhs) const override
{
if (!is_type_equal(rhs)) {
return false;
}
return get() == dynamic_cast<property_t<data_t>*>(rhs)->get();
}
std::unique_ptr<property_base_t> clone(res_source_info new_src_info) override
{
return std::unique_ptr<property_base_t>(
new property_t<data_t>(get_id(), get(), new_src_info));
}
void set_from_str(const std::string& new_val_str) override
{
try {
set(uhd::cast::from_str<data_t>(new_val_str));
} catch (uhd::runtime_error& ex) {
throw uhd::runtime_error(
std::string("Property ") + get_id() + ":" + ex.what());
}
}
// const res_source_info& get_src_info() const = 0;
//
// \throws uhd::access_error if the current access mode is not RW or RWLOCKED
// \throws uhd::resolve_error if the property is RWLOCKED but the new value
// doesn't match
void set(const data_t& value)
{
if (write_access_granted()) {
_data = value;
_valid = true;
} else if (get_access_mode() == RWLOCKED) {
if (_data.get() != value) {
throw uhd::resolve_error(std::string("Attempting to overwrite property `")
+ get_id() + "@" + get_src_info().to_string()
+ "' with a new value after it was locked!");
}
} else {
throw uhd::access_error(std::string("Attempting to write to property `")
+ get_id() + "' without access privileges!");
}
}
void force_dirty() override
{
if (write_access_granted()) {
_data.force_dirty();
} else if (get_access_mode() == RWLOCKED) {
if (!_data.is_dirty()) {
throw uhd::resolve_error(std::string("Attempting to overwrite property `")
+ get_id()
+ "' with dirty flag after it was locked!");
}
} else {
throw uhd::access_error(std::string("Attempting to flag dirty property `")
+ get_id() + "' without access privileges!");
}
}
//
// \throws uhd::access_error if either the property is flagged as invalid,
// or if no read access was granted.
const data_t& get() const
{
if (!is_valid()) {
throw uhd::access_error(std::string("Attempting to read property `")
+ get_id() + "@" + get_src_info().to_string()
+ "' before it was initialized!");
}
if (read_access_granted()) {
return _data;
}
throw uhd::access_error(std::string("Attempting to read property `") + get_id()
+ "' without access privileges!");
}
operator const data_t&() const
{
return get();
}
bool operator==(const data_t& rhs)
{
return get() == rhs;
}
property_t<data_t>& operator=(const data_t& value)
{
set(value);
return *this;
}
private:
void mark_clean() override
{
_data.mark_clean();
}
void forward(property_base_t* next_prop) override
{
if (not _valid) {
throw uhd::resolve_error(
std::string("Unable to forward invalid property ") + get_id());
}
property_t<data_t>* prop_ptr = dynamic_cast<property_t<data_t>*>(next_prop);
if (prop_ptr == nullptr) {
throw uhd::type_error(std::string("Unable to cast property ")
+ next_prop->get_id() + " to the same type as property "
+ get_id());
}
prop_ptr->set(get());
}
bool is_type_equal(property_base_t* other_prop) const override
{
return dynamic_cast<property_t<data_t>*>(other_prop) != nullptr;
}
dirty_tracked<data_t> _data;
bool _valid;
}; // class property_t
}} /* namespace uhd::rfnoc */
#include <uhd/rfnoc/property.ipp>
cast.hpp
uhd::rfnoc::property_base_t::get_id
const std::string & get_id() const
Gets the ID (name) of this property.
Definition property.hpp:51
uhd::rfnoc::property_base_t::force_dirty
virtual void force_dirty()=0
uhd::rfnoc::property_base_t::get_src_info
const res_source_info & get_src_info() const
Return the source info for this property.
Definition property.hpp:57
uhd::rfnoc::property_base_t::equal
virtual bool equal(property_base_t *rhs) const =0
Return true if rhs has the same type and value.
uhd::rfnoc::property_base_t::access_t
access_t
Definition property.hpp:28
uhd::rfnoc::property_base_t::RO
@ RO
Read-Only.
Definition property.hpp:30
uhd::rfnoc::property_base_t::RW
@ RW
Read-Write.
Definition property.hpp:31
uhd::rfnoc::property_base_t::NONE
@ NONE
Neither reading nor writing to this property is permitted.
Definition property.hpp:29
uhd::rfnoc::property_base_t::RWLOCKED
@ RWLOCKED
Definition property.hpp:32
uhd::rfnoc::property_base_t::property_base_t
property_base_t(const std::string &id, const res_source_info &source_info)
Definition property.hpp:36
uhd::rfnoc::property_base_t::set_from_str
virtual void set_from_str(const std::string &new_val_str)=0
uhd::rfnoc::property_base_t::prop_accessor_t
friend class prop_accessor_t
Definition property.hpp:121
uhd::rfnoc::property_base_t::is_valid
virtual bool is_valid() const =0
Query this property's valid flag.
uhd::rfnoc::property_base_t::clone
virtual std::unique_ptr< property_base_t > clone(res_source_info)
Create a copy of this property.
Definition property.hpp:103
uhd::rfnoc::property_base_t::get_access_mode
access_t get_access_mode() const
Return the current access mode.
Definition property.hpp:87
uhd::rfnoc::property_base_t::~property_base_t
virtual ~property_base_t()
Definition property.hpp:45
uhd::rfnoc::property_base_t::write_access_granted
bool write_access_granted() const
Returns true if this property can be written to.
Definition property.hpp:81
uhd::rfnoc::property_base_t::read_access_granted
bool read_access_granted() const
Returns true if this property can be read.
Definition property.hpp:75
uhd::rfnoc::property_base_t::is_dirty
virtual bool is_dirty() const =0
Query this property's dirty flag.
uhd::rfnoc::property_t::get
const data_t & get() const
Get the value of this property.
Definition property.hpp:252
uhd::rfnoc::property_t::set
void set(const data_t &value)
Returns the source info for the property.
Definition property.hpp:215
uhd::rfnoc::property_t::is_dirty
bool is_dirty() const override
Returns the dirty state of this property.
Definition property.hpp:169
uhd::rfnoc::property_t::property_t
property_t(const std::string &id, data_t &&value, const res_source_info &source_info)
Definition property.ipp:10
uhd::rfnoc::property_t::operator=
property_t< data_t > & operator=(const data_t &value)
Definition property.hpp:276
uhd::rfnoc::property_t::is_valid
bool is_valid() const override
Query this property's valid flag.
Definition property.hpp:178
uhd::rfnoc::property_t::set_from_str
void set_from_str(const std::string &new_val_str) override
Definition property.hpp:197
uhd::rfnoc::property_t::value_type
data_t value_type
We want to be good C++ citizens.
Definition property.hpp:154
uhd::rfnoc::property_t::operator==
bool operator==(const data_t &rhs)
Definition property.hpp:271
uhd::rfnoc::property_t::equal
bool equal(property_base_t *rhs) const override
Return true if rhs has the same type and value.
Definition property.hpp:183
uhd::rfnoc::property_t::force_dirty
void force_dirty() override
Definition property.hpp:232
uhd::rfnoc::property_t::clone
std::unique_ptr< property_base_t > clone(res_source_info new_src_info) override
Create a copy of this property.
Definition property.hpp:191
uhd::rfnoc::property_t::property_t
property_t(const property_t< data_t > &prop)=default
UHD_API_HEADER
#define UHD_API_HEADER
Definition config.h:88
UHD_API
#define UHD_API
Definition config.h:87
dirty_tracked.hpp
exception.hpp
uhd::cast::from_str
data_t from_str(const std::string &)
Generic cast-from-string function.
Definition cast.hpp:51
uhd::rfnoc
Definition actions.hpp:24
uhd
Definition build_info.hpp:12
property.ipp
res_source_info.hpp
uhd::access_error
Definition exception.hpp:168
uhd::not_implemented_error
Definition exception.hpp:157
uhd::resolve_error
Definition exception.hpp:281
uhd::rfnoc::res_source_info
Definition res_source_info.hpp:18
uhd::runtime_error
Definition exception.hpp:132
uhd::type_error
Definition exception.hpp:96