aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2021-04-29 11:27:21 +0200
committerAaron Rossetto <aaron.rossetto@ni.com>2021-05-04 14:34:44 -0500
commit87de94748ad5324024adb7d149878d7b6c92e71a (patch)
tree300eabe79c8dadd7025ec1e8854236206fe5ab48
parent1a213267a080ea7f1c364ff3afefdf6e9e4cb509 (diff)
downloaduhd-87de94748ad5324024adb7d149878d7b6c92e71a.tar.gz
uhd-87de94748ad5324024adb7d149878d7b6c92e71a.tar.bz2
uhd-87de94748ad5324024adb7d149878d7b6c92e71a.zip
experts: Change coercion policy for regular prop nodes
The experts framework has two ways of integrating expert nodes into the property tree: add_prop_node() and add_dual_prop_node(). In the latter case, the experts should take care of coercion, and thus, we subscribe to the desired value. In the former case, this is not necessary, and precludes us from using set_coercer() with prop nodes on the prop tree. This change lets us use regular nodes in the expert framework that also use property tree coercers. As of now, there is not a single property node in UHD that uses add_prop_node() and also does any kind of coercion, so this change has no effect on current code (this is only used in TwinRX as of now).
-rw-r--r--host/lib/include/uhdlib/experts/expert_factory.hpp14
-rw-r--r--host/tests/expert_test.cpp11
2 files changed, 19 insertions, 6 deletions
diff --git a/host/lib/include/uhdlib/experts/expert_factory.hpp b/host/lib/include/uhdlib/experts/expert_factory.hpp
index 4568abd61..6821775e9 100644
--- a/host/lib/include/uhdlib/experts/expert_factory.hpp
+++ b/host/lib/include/uhdlib/experts/expert_factory.hpp
@@ -65,6 +65,16 @@ public:
/*!
* Add a expert property to a property tree AND an expert graph
*
+ * The underlying property can be used like any other property tree property,
+ * including setting a coercer through set_coercer(). However, this means
+ * that the coercion is happening outside of the expert framework. This is
+ * primarily useful for tiny coercions (e.g., we accept both upper and lower
+ * case values, but only want lower case downstream) for which we don't want
+ * to bother with a full expert, or for which we don't want to trigger
+ * resolution at all (if mode is set to AUTO_RESOLVE_OFF).
+ * For more full-fledged coercion, prefer add_dual_prop_node(). This will
+ * properly engage the expert graph.
+ *
* \param container A shared pointer to the expert container to add the node to
* \param subtree A shared pointer to subtree to add the property to
* \param path The path of the property in the subtree
@@ -87,11 +97,11 @@ public:
const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF)
{
property<data_t>& prop =
- subtree->create<data_t>(path, property_tree::MANUAL_COERCE);
+ subtree->create<data_t>(path, property_tree::AUTO_COERCE);
data_node_t<data_t>* node_ptr =
new data_node_t<data_t>(name, init_val, &container->resolve_mutex());
prop.set(init_val);
- prop.add_desired_subscriber(
+ prop.add_coerced_subscriber(
std::bind(&data_node_t<data_t>::commit, node_ptr, std::placeholders::_1));
prop.set_publisher(std::bind(&data_node_t<data_t>::retrieve, node_ptr));
container->add_data_node(node_ptr, mode);
diff --git a/host/tests/expert_test.cpp b/host/tests/expert_test.cpp
index a23c9cbb8..8ca60477a 100644
--- a/host/tests/expert_test.cpp
+++ b/host/tests/expert_test.cpp
@@ -187,6 +187,9 @@ BOOST_AUTO_TEST_CASE(test_experts)
expert_factory::add_data_node<int>(container, "F", 0);
expert_factory::add_data_node<int>(container, "G", 0);
+ // B also gets a coercer. It coerces 4 to 3.
+ tree->access<int>("B").set_coercer([](const int b) { return b == 4 ? 3 : b; });
+
// Add worker nodes to container
expert_factory::add_worker_node<worker1_t>(container, container->node_retriever());
expert_factory::add_worker_node<worker2_t>(container, container->node_retriever());
@@ -225,11 +228,11 @@ BOOST_AUTO_TEST_CASE(test_experts)
BOOST_CHECK(nodeF.is_dirty());
BOOST_CHECK(nodeG.is_dirty());
container->resolve_all();
- VALIDATE_ALL_DEPENDENCIES // Ensure a default resolve
+ VALIDATE_ALL_DEPENDENCIES; // Ensure a default resolve
+
+ // Ensure basic node value propagation
+ tree->access<int>("B").set(4); // Set it 4, but that will get coerced to 3
- // Ensure basic node value propagation
- tree->access<int>("B")
- .set(3);
BOOST_CHECK(nodeB.get() == 3); // Ensure value propagated
BOOST_CHECK(nodeB.is_dirty()); // Ensure that nothing got resolved...
container->resolve_all();