aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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();