USRP Hardware Driver and USRP Manual Version: 4.1.0.1
UHD and USRP Manual
property.hpp
Go to the documentation of this file.
1//
2// Copyright 2019 Ettus Research, a National Instruments Brand
3//
4// SPDX-License-Identifier: GPL-3.0-or-later
5//
6
7#pragma once
8
9#include <uhd/exception.hpp>
11#include <uhd/utils/cast.hpp>
13#include <memory>
14#include <string>
15
16
17namespace uhd { namespace rfnoc {
18
19// Forward declaration, separates includes
20class prop_accessor_t;
21
26{
27public:
28 enum access_t {
30 RO = 0x1,
31 RW = 0x3,
32 RWLOCKED = 0x5
34 };
35
36 property_base_t(const std::string& id, const res_source_info& source_info)
37 : _id(id), _source_info(source_info)
38 {
39 if(_id.find(':') != std::string::npos) {
40 throw uhd::value_error("Property ID `" + _id + "' contains invalid character!");
41 }
42 }
43
45 {
46 //nop
47 }
48
50 const std::string& get_id() const
51 {
52 return _id;
53 }
54
57 {
58 return _source_info;
59 }
60
62 //
63 // If it's true, that means this property was recently changed, but changes
64 // have not propagated yet and still need resolving.
65 virtual bool is_dirty() const = 0;
66
68 //
69 // If it's false, that means this property has a default value that should
70 // NOT be forwarded.
71 virtual bool is_valid() const = 0;
72
75 {
76 return static_cast<uint8_t>(_access_mode) & 0x1;
77 }
78
81 {
82 return static_cast<uint8_t>(_access_mode) & 0x2;
83 }
84
87 {
88 return _access_mode;
89 }
90
92 virtual bool equal(property_base_t* rhs) const = 0;
93
95 //
96 // The copy must have the same type, value, and ID. However, it is often
97 // desirable to have a new source information, so that can be overridden.
98 //
99 // The cleanliness state of \p original is not preserved. The new property
100 // will have the same cleanliness state as any other new property.
101 //
102 virtual std::unique_ptr<property_base_t> clone(res_source_info)
103 {
104 throw uhd::not_implemented_error("Cloning is not available for this property.");
105 }
106
107 virtual void force_dirty() = 0;
108
117 virtual void set_from_str(const std::string& new_val_str) = 0;
118
119private:
120 friend class prop_accessor_t;
121
123 virtual void mark_clean() = 0;
124
126 virtual void forward(property_base_t* next_prop) = 0;
127
129 //
130 // Note: This uses RTTI to evaluate type equality
131 virtual bool is_type_equal(property_base_t* other_prop) const = 0;
132
133 /*** Attributes **********************************************************/
135 const std::string _id;
136
138 const res_source_info _source_info;
139
141 // write this.
142 access_t _access_mode = RO;
143};
144
148template <typename data_t>
150{
151public:
153 using value_type = data_t;
154
155 property_t(const std::string& id, data_t&& value, const res_source_info& source_info);
156
158 const std::string& id, const data_t& value, const res_source_info& source_info);
159
160 property_t(const std::string& id, const res_source_info& source_info);
161
162 property_t(const property_t<data_t>& prop) = default;
163
165 //
166 // If true, this means the value was recently changed, but it wasn't marked
167 // clean yet.
168 bool is_dirty() const override
169 {
170 return _data.is_dirty();
171 }
172
174 //
175 // If it's false, that means this property has a default value that should
176 // NOT be used.
177 bool is_valid() const override
178 {
179 return _valid;
180 }
181
182 bool equal(property_base_t* rhs) const override
183 {
184 if (!is_type_equal(rhs)) {
185 return false;
186 }
187 return get() == dynamic_cast<property_t<data_t>*>(rhs)->get();
188 }
189
190 std::unique_ptr<property_base_t> clone(res_source_info new_src_info) override
191 {
192 return std::unique_ptr<property_base_t>(
193 new property_t<data_t>(get_id(), get(), new_src_info));
194 }
195
196 void set_from_str(const std::string& new_val_str) override
197 {
198 try {
199 set(uhd::cast::from_str<data_t>(new_val_str));
200 } catch (uhd::runtime_error& ex) {
201 throw uhd::runtime_error(
202 std::string("Property ") + get_id() + ":" + ex.what());
203 }
204 }
205
207 // const res_source_info& get_src_info() const = 0;
208
210 //
211 // \throws uhd::access_error if the current access mode is not RW or RWLOCKED
212 // \throws uhd::resolve_error if the property is RWLOCKED but the new value
213 // doesn't match
214 void set(const data_t& value)
215 {
216 if (write_access_granted()) {
217 _data = value;
218 _valid = true;
219 } else if (get_access_mode() == RWLOCKED) {
220 if (_data.get() != value) {
221 throw uhd::resolve_error(std::string("Attempting to overwrite property `")
222 + get_id() + "@" + get_src_info().to_string()
223 + "' with a new value after it was locked!");
224 }
225 } else {
226 throw uhd::access_error(std::string("Attempting to write to property `")
227 + get_id() + "' without access privileges!");
228 }
229 }
230
231 void force_dirty() override
232 {
233 if (write_access_granted()) {
234 _data.force_dirty();
235 } else if (get_access_mode() == RWLOCKED) {
236 if (!_data.is_dirty()) {
237 throw uhd::resolve_error(std::string("Attempting to overwrite property `")
238 + get_id()
239 + "' with dirty flag after it was locked!");
240 }
241 } else {
242 throw uhd::access_error(std::string("Attempting to flag dirty property `")
243 + get_id() + "' without access privileges!");
244 }
245 }
246
248 //
249 // \throws uhd::access_error if either the property is flagged as invalid,
250 // or if no read access was granted.
251 const data_t& get() const
252 {
253 if (!is_valid()) {
254 throw uhd::access_error(std::string("Attempting to read property `")
255 + get_id() + "@" + get_src_info().to_string()
256 + "' before it was initialized!");
257 }
258 if (read_access_granted()) {
259 return _data;
260 }
261 throw uhd::access_error(std::string("Attempting to read property `") + get_id()
262 + "' without access privileges!");
263 }
264
265 operator const data_t&() const
266 {
267 return get();
268 }
269
270 bool operator==(const data_t& rhs)
271 {
272 return get() == rhs;
273 }
274
275 property_t<data_t>& operator=(const data_t& value)
276 {
277 set(value);
278 return *this;
279 }
280
281private:
282 void mark_clean() override
283 {
284 _data.mark_clean();
285 }
286
287 void forward(property_base_t* next_prop) override
288 {
289 if (not _valid) {
290 throw uhd::resolve_error(
291 std::string("Unable to forward invalid property ") + get_id());
292 }
293 property_t<data_t>* prop_ptr = dynamic_cast<property_t<data_t>*>(next_prop);
294 if (prop_ptr == nullptr) {
295 throw uhd::type_error(std::string("Unable to cast property ")
296 + next_prop->get_id() + " to the same type as property "
297 + get_id());
298 }
299
300 prop_ptr->set(get());
301 }
302
303 bool is_type_equal(property_base_t* other_prop) const override
304 {
305 return dynamic_cast<property_t<data_t>*>(other_prop) != nullptr;
306 }
307
308 dirty_tracked<data_t> _data;
309 bool _valid;
310}; // class property_t
311
312}} /* namespace uhd::rfnoc */
313
314#include <uhd/rfnoc/property.ipp>
Definition: property.hpp:26
const std::string & get_id() const
Gets the ID (name) of this property.
Definition: property.hpp:50
virtual void force_dirty()=0
const res_source_info & get_src_info() const
Return the source info for this property.
Definition: property.hpp:56
virtual bool equal(property_base_t *rhs) const =0
Return true if rhs has the same type and value.
access_t
Definition: property.hpp:28
@ NONE
Neither reading nor writing to this property is permitted.
Definition: property.hpp:29
@ RWLOCKED
Definition: property.hpp:32
property_base_t(const std::string &id, const res_source_info &source_info)
Definition: property.hpp:36
virtual void set_from_str(const std::string &new_val_str)=0
virtual bool is_valid() const =0
Query this property's valid flag.
virtual std::unique_ptr< property_base_t > clone(res_source_info)
Create a copy of this property.
Definition: property.hpp:102
access_t get_access_mode() const
Return the current access mode.
Definition: property.hpp:86
virtual ~property_base_t()
Definition: property.hpp:44
bool write_access_granted() const
Returns true if this property can be written to.
Definition: property.hpp:80
bool read_access_granted() const
Returns true if this property can be read.
Definition: property.hpp:74
virtual bool is_dirty() const =0
Query this property's dirty flag.
Definition: property.hpp:150
const data_t & get() const
Get the value of this property.
Definition: property.hpp:251
void set(const data_t &value)
Returns the source info for the property.
Definition: property.hpp:214
bool is_dirty() const override
Returns the dirty state of this property.
Definition: property.hpp:168
property_t(const std::string &id, data_t &&value, const res_source_info &source_info)
Definition: property.ipp:10
property_t< data_t > & operator=(const data_t &value)
Definition: property.hpp:275
bool is_valid() const override
Query this property's valid flag.
Definition: property.hpp:177
void set_from_str(const std::string &new_val_str) override
Definition: property.hpp:196
data_t value_type
We want to be good C++ citizens.
Definition: property.hpp:153
bool operator==(const data_t &rhs)
Definition: property.hpp:270
bool equal(property_base_t *rhs) const override
Return true if rhs has the same type and value.
Definition: property.hpp:182
void force_dirty() override
Definition: property.hpp:231
std::unique_ptr< property_base_t > clone(res_source_info new_src_info) override
Create a copy of this property.
Definition: property.hpp:190
property_t(const property_t< data_t > &prop)=default
#define UHD_API
Definition: config.h:70
Definition: build_info.hpp:12
Definition: exception.hpp:169
Definition: exception.hpp:158
Definition: exception.hpp:282
Definition: res_source_info.hpp:18
Definition: exception.hpp:133
Definition: exception.hpp:97
Definition: exception.hpp:109