void ShmdataStat::update_tree(const InfoTree::ptr& tree, const std::string& key) const { tree->graft(key + ".stat.byte_rate", InfoTree::make(bytes_)); tree->graft(key + ".stat.rate", InfoTree::make(accesses_)); }
PropertyQuid::PropertyQuid(quid::Config&& conf) : Quiddity(std::forward<quid::Config>(conf)), bool_id_(pmanage<MPtr(&PContainer::make_bool)>("bool_", [this](bool val) { bool_ = val; return true; }, [this]() { return bool_; }, "Bool Example", "This property is an example for type bool", bool_)), string_id_( pmanage<MPtr(&PContainer::make_string)>("string_", [this](const std::string& val) { string_ = val; return true; }, [this]() { return string_; }, "String Example", "This property is an example for type string", string_)), char_id_(pmanage<MPtr(&PContainer::make_char)>("char_", [this](const char& val) { char_ = val; return true; }, [this]() { return char_; }, "Char Example", "This property is an example for type char", char_)), color_id_(pmanage<MPtr(&PContainer::make_color)>("color_", [this](const Color& val) { color_ = val; return true; }, [this]() { return color_; }, "Color Example", "This property is an example for type color", color_)), integral_group_id_(pmanage<MPtr(&PContainer::make_group)>( "integrals", "Integral Group Example", "This property is an example for grouping integral types")), int_id_(pmanage<MPtr(&PContainer::make_parented_int)>( // PContainer factory "int_", // string id "integrals", // parent [this](int val) { int_ = val; return true; }, // setter [this]() { return int_; }, // getter "Int Example", // name "This property is an example for type int", // description int_, // default value -10, // min 10)), // max short_id_(pmanage<MPtr(&PContainer::make_parented_short)>( "short_", "integrals", [this](short val) { short_ = val; return true; }, [this]() { return short_; }, "Short Example", "This property is an example for type short", short_, -11, 11)), long_id_(pmanage<MPtr(&PContainer::make_parented_long)>( "long_", "integrals", [this](long val) { long_ = val; return true; }, [this]() { return long_; }, "Long Example", "This property is an example for type long", long_, -20, 20)), long_long_id_(pmanage<MPtr(&PContainer::make_parented_long_long)>( "long_long_", "integrals", [this](long long val) { long_long_ = val; return true; }, [this]() { return long_long_; }, "Long Long Example", "This property is an example for type long long", long_long_, -21, 21)), unsigned_int_id_(pmanage<MPtr(&PContainer::make_parented_unsigned_int)>( "unsigned_int_", "integrals", [this](unsigned int val) { unsigned_int_ = val; return true; }, [this]() { return unsigned_int_; }, "Unsigned Int Example", "This property is an example for type unsigned int", unsigned_int_, 0, 10)), unsigned_short_id_(pmanage<MPtr(&PContainer::make_parented_unsigned_short)>( "unsigned_short_", "integrals", [this](unsigned short val) { unsigned_short_ = val; return true; }, [this]() { return unsigned_short_; }, "Unsigned Short Example", "This property is an example for type unsigned short", unsigned_short_, 1, 11)), unsigned_long_id_(pmanage<MPtr(&PContainer::make_parented_unsigned_long)>( "unsigned_long_", "integrals", [this](unsigned long val) { unsigned_long_ = val; return true; }, [this]() { return unsigned_long_; }, "Unsigned Long Example", "This property is an example for type unsigned long", unsigned_long_, 4, 200)), unsigned_long_long_id_(pmanage<MPtr(&PContainer::make_parented_unsigned_long_long)>( "unsigned_long_long_", "integrals", [this](unsigned long long val) { unsigned_long_long_ = val; return true; }, [this]() { return unsigned_long_long_; }, "Unsigned Long Long Example", "This property is an example for type unsigned long long", unsigned_long_long_, 2, 210)), floating_point_group_id_(pmanage<MPtr(&PContainer::make_group)>( "floats", "Floating Point Group Example", "This property is an example for grouping floating points")), float_id_(pmanage<MPtr(&PContainer::make_parented_float)>( "float_", "floats", [this](float val) { float_ = val; return true; }, [this]() { return float_; }, "Float Example", "This property is an example for type float", float_, -1.f, 1.f)), double_id_(pmanage<MPtr(&PContainer::make_parented_double)>( "double_", "floats", [this](double val) { double_ = val; return true; }, [this]() { return double_; }, "Double Example", "This property is an example for type double", double_, -1.f, 10.f)), long_double_id_(pmanage<MPtr(&PContainer::make_parented_long_double)>( "long_double_", "floats", [this](long double val) { long_double_ = val; return true; }, [this]() { return long_double_; }, "Long Double Example", "This property is an example for type long double", long_double_, -1.f, 10.f)), selection_id_( pmanage<MPtr(&PContainer::make_selection<>)>("enum_", [this](const IndexOrName& val) { selection_.select(val); return true; }, [this]() { return selection_.get(); }, "Selection Example", "This property is an example for type enum", selection_)), tuple_id_( pmanage<MPtr(&PContainer::make_tuple<MyTuple>)>("tuple_", [this](const MyTuple& val) { tuple_ = val; return true; }, [this]() { return tuple_; }, "Tuple Example", "This property is an example for tuple", tuple_)), fraction_id_( pmanage<MPtr(&PContainer::make_fraction)>("fraction_", [this](const Fraction& val) { fraction_ = val; return true; }, [this]() { return fraction_; }, "Fraction Example", "This property is an example for fraction", fraction_, -10, 1, // min num/denom 10, 10) // max num/denom ) { // std::cout << pmanage<MPtr(&PContainer::get<int>)>( int_id_) << std::endl; // std::cout << pmanage<MPtr(&PContainer::get<unsigned int>)>( uint_id_) << // std::endl; pmanage<MPtr(&PContainer::set<MyTuple>)>( tuple_id_, std::make_tuple<long long, float, std::string>(2, 2.2, "a22")); std::cout << std::get<0>(tuple_) << " " // 2 << std::get<1>(tuple_) << " " // 2.2 << std::get<2>(tuple_) << "\n"; // a22 // creating some custom infos InfoTree::ptr tree = InfoTree::make(); tree->graft(".child1.child2", InfoTree::make("switch")); tree->graft(".child1.child3", InfoTree::make(1.2f)); tree->graft(".child1.child2.bla1", InfoTree::make("wire")); tree->graft(".child1.child2.bla2", InfoTree::make("hub")); // attaching it to the quiddity (at the root) graft_tree(".custom.information.", tree); debug("hello from plugin"); }
//---------------- test int main() { using namespace switcher; auto string_compare = [](const std::string& first, const std::string& second) { return (0 == first.compare(second)); }; { // node data as std::string InfoTree::ptr tree = InfoTree::make(std::string("truc")); assert(tree->is_leaf()); std::string data = tree->get_value(); assert(0 == data.compare("truc")); } { // node data as const char * (converted to std::string) InfoTree::ptr tree = InfoTree::make("test"); assert(tree->is_leaf()); } { // node data as float InfoTree::ptr tree = InfoTree::make(1.2f); float val = tree->get_value(); assert(1.2f == val); } { // graft a multiple childs and get them InfoTree::ptr tree = InfoTree::make(); tree->graft("...child1....child2..", InfoTree::make(1.2f)); assert(!tree->is_leaf()); InfoTree::ptr child2 = tree->get_tree("..child1.child2"); assert(child2); assert(child2->is_leaf()); float data = child2->get_value(); assert(1.2f == data); InfoTree::ptr child1 = tree->get_tree(".child1.."); assert(!child1->is_leaf()); assert(tree->get_tree("child1.foo")->empty()); // this is not a child } { // graft a childs and prune it InfoTree::ptr tree = InfoTree::make(); tree->graft("child1.child2", InfoTree::make()); assert(!tree->is_leaf()); InfoTree::ptr child1 = tree->prune("child1"); assert(child1); assert(tree->is_leaf()); assert(!child1->is_leaf()); // child2 from the pruned child1 InfoTree::ptr child2 = child1->prune("child2"); assert(child2); assert(child1->is_leaf()); assert(child2->is_leaf()); } { // absolute prune InfoTree::ptr tree = InfoTree::make(); tree->graft("child1.child2", InfoTree::make()); InfoTree::ptr child2 = tree->prune("child1.child2"); assert(!tree->is_leaf()); assert(tree->branch_is_leaf("child1")); } { // is_leaf with path InfoTree::ptr tree = InfoTree::make(); tree->graft("child1", InfoTree::make()); tree->graft("child1.child2", InfoTree::make()); tree->graft("child1.child2.child3", InfoTree::make()); assert(tree->branch_is_leaf("child1.child2.child3")); assert(!tree->branch_is_leaf("child1.child2")); assert(!tree->branch_is_leaf("child1")); assert(!tree->branch_is_leaf("foofoo")); } { // set/get data with path InfoTree::ptr tree = InfoTree::make(); // tree->set_value ("", 1.2f); // this is not possible // float tree_data = tree->get_value ("."); // this is not possible // assert (1.2f == tree_data); tree->graft("child1.child2", InfoTree::make()); assert(tree->branch_set_value("child1.child2", nullptr)); assert(tree->branch_set_value("child1", 1.2f)); std::string child2_data = tree->branch_get_value("child1.child2"); assert("" == child2_data); float child1_data = tree->branch_get_value("child1"); assert(1.2f == child1_data); } { // removing using empty data InfoTree::ptr tree = InfoTree::make(); tree->set_value("test"); assert(tree->has_data()); tree->set_value(Any()); assert(!tree->has_data()); tree->graft("child1.child2", InfoTree::make()); assert(tree->branch_set_value("child1.child2", "test")); assert(tree->branch_set_value("child1", "test")); assert(tree->branch_has_data("child1.child2")); assert(tree->branch_has_data("child1")); assert(tree->branch_set_value("child1.child2", Any())); assert(tree->branch_set_value("child1", Any())); assert(!tree->branch_has_data("child1.child2")); assert(!tree->branch_has_data("child1")); } { // Any to string Any n; Any a(std::string("test")); Any b(1.2f); Widget widget; Any w(std::move(widget)); SerializableWidget serializable_widget; Any sw(serializable_widget); std::stringstream ss; ss << n << "-" << a << "-" << b << "-" << w << "-" << sw; // std::cout << ss.str () << '\n'; assert(0 == ss.str().compare("null-test-1.200000-not serializable-hello")); } { // basic serialization InfoTree::ptr tree = InfoTree::make(); tree->graft(".child1.child2", InfoTree::make("switch")); tree->graft(".child1.child3", InfoTree::make(1.2f)); tree->graft(".child1.child2.bla1", InfoTree::make("wire")); tree->graft(".child1.child2.bla2", InfoTree::make("hub")); std::string serialized = BasicSerializer::serialize(tree.get()); // std::cout << serialized << '\n'; InfoTree::ptr tree2 = BasicSerializer::deserialize(serialized); assert(tree2); std::string serialized2 = BasicSerializer::serialize(tree2.get()); // std::cout << serialized2 << '\n'; assert(serialized == serialized2); } { // JSON serialization with child1.child2 as an array InfoTree::ptr tree = InfoTree::make(); // if children are grafted to child3, its value // will be serialized with "key_value, as follow: // "child3" : { // "key_value" : 1.2, // "child4" : "float" // } tree->graft(".child1.child3", InfoTree::make(1.2f)); tree->graft(".child1.child3.child4", InfoTree::make("a string value")); tree->graft(".int_type", InfoTree::make(9)); tree->graft(".bool_type", InfoTree::make(true)); tree->graft(".float_type", InfoTree::make(3.14)); tree->graft(".null_type", InfoTree::make()); // if the array is made with a value, it will not be serialized // a node trageted as an array should be created like this : // tree->graft (".child1.child2", InfoTree::make ()); // however, this is accepted: tree->graft(".child1.child2", InfoTree::make("switch")); // InfoTree::ptr elem1 = InfoTree::make(); elem1->graft("equipment", InfoTree::make("door")); elem1->graft("color", InfoTree::make("red")); InfoTree::ptr elem2 = InfoTree::make(); elem2->graft("equipment", InfoTree::make("door")); elem2->graft("color", InfoTree::make("black")); tree->graft(".child1.child2.red_door", elem1); tree->graft(".child1.child2.black_door", elem2); tree->tag_as_array(".child1.child2", true); std::string serialized = JSONSerializer::serialize(tree.get()); // std::cout << serialized << '\n'; auto deserialized_tree = JSONSerializer::deserialize(serialized); auto deserialized_string = JSONSerializer::serialize(deserialized_tree.get()); // std::cout << deserialized_string << '\n'; assert(serialized == deserialized_string); // test copy auto tree_cpy = InfoTree::copy(tree.get()); assert(serialized == JSONSerializer::serialize(tree_cpy.get())); auto tree_cpy2 = tree->branch_get_copy("."); assert(serialized == JSONSerializer::serialize(tree_cpy2.get())); } { // get childs keys inserting in an existing container InfoTree::ptr tree = InfoTree::make(); std::list<std::string> childs{ "child1", "child2", "child3", "child4", "child5", "child6", "child7", "child8", "child9"}; std::for_each(childs.begin(), childs.end(), [tree](const std::string& val) { tree->graft(".root." + val, InfoTree::make("val")); }); std::vector<std::string> child_keys; auto insert_it = std::insert_iterator<decltype(child_keys)>(child_keys, child_keys.begin()); tree->copy_and_insert_child_keys(".root", insert_it); assert(std::equal(childs.begin(), childs.end(), child_keys.begin(), [](const std::string& first, const std::string& second) { return (0 == first.compare(second)); })); } { // get childs keys in a newly allocated container InfoTree::ptr tree = InfoTree::make(); std::list<std::string> childs{ "child1", "child2", "child3", "child4", "child5", "child6", "child7", "child8", "child9"}; std::for_each(childs.begin(), childs.end(), [tree](const std::string& val) { tree->graft(".root." + val, InfoTree::make("val")); }); // using a default container auto child_keys_list = tree->get_child_keys(".root"); assert(std::equal(childs.begin(), childs.end(), child_keys_list.begin(), string_compare)); } { // copy_leaf_values InfoTree::ptr tree = InfoTree::make(); std::list<std::string> original_values{"0", "1", "2"}; for (auto& it : original_values) tree->graft(std::string(".branch.item" + it), InfoTree::make(it)); tree->graft(".other.branch", InfoTree::make()); // not into copy_leaf_values tree->tag_as_array("branch.", true); // std::string serialized = JSONSerializer::serialize(tree); // std::cout << serialized << '\n'; std::list<std::string> values = tree->copy_leaf_values(".branch"); assert( std::equal(original_values.begin(), original_values.end(), values.begin(), string_compare)); // for (auto &it : values) // std::cout << it << '\n'; } { // collecting data InfoTree::ptr tree = InfoTree::make(); tree->graft("root.1.id", InfoTree::make(0)); tree->graft("root.2.1.id", InfoTree::make(2)); tree->graft("root.3.21.id", InfoTree::make(4)); tree->graft("root.4.id", InfoTree::make(8)); tree->graft("root.5.id", InfoTree::make(16)); tree->graft("root.5.id.id", InfoTree::make(1)); // subtree of root.5.id tree->graft("root.1.2.id", InfoTree::make(3)); // sibling of root.1.id auto collected = InfoTree::collect_values(tree.get(), [](const std::string& key, InfoTree::ptrc) { return key == "id"; }, false); // do not continue search on siblings and subtree assert(5 == collected.size()); std::vector<int> values{0, 2, 4, 8, 16}; for (auto& it : collected) { assert(values.end() != std::find(values.cbegin(), values.cend(), it.copy_as<int>())); } } return 0; }
std::string QuiddityManager::get_serialized_command_history() const { auto quiddities = manager_impl_->get_instances(); for (auto& it : quiddities_at_reset_) { auto tmp = std::find(quiddities.begin(), quiddities.end(), it); if (quiddities.end() != tmp) quiddities.erase(tmp); } if (quiddities.empty()) { g_warning("nothing to save"); return {}; } InfoTree::ptr tree = InfoTree::make(); // saving history for (unsigned int i = 0; i < command_history_.history_.size(); i++) { tree->graft(std::string("history.") + std::to_string(i), command_history_.history_[i]->get_info_tree()); } tree->tag_as_array("history", true); // saving per-quiddity information auto quid_str = std::string(".quiddities."); for (auto& quid_name : quiddities) { // name and class auto quid_class = manager_impl_->get_quiddity(quid_name)->get_documentation()->get_class_name(); tree->graft(quid_str + quid_name, InfoTree::make(quid_class)); // saving custom tree if some is provided auto custom_tree = manager_impl_->get_quiddity(quid_name)->on_saving(); if (custom_tree && !custom_tree->empty()) tree->graft(".custom_states." + quid_name, std::move(custom_tree)); // user data auto quid_user_data_tree = user_data<MPtr(&InfoTree::get_tree)>(quid_name, "."); if (!quid_user_data_tree->empty()) { tree->graft(".userdata." + quid_name, user_data<MPtr(&InfoTree::get_tree)>(quid_name, ".")); } // writable property values use_prop<MPtr(&PContainer::update_values_in_tree)>(quid_name); auto props = use_tree<MPtr(&InfoTree::get_child_keys)>(quid_name, "property"); for (auto& prop : props) { if (use_tree<MPtr(&InfoTree::branch_get_value)>( quid_name, std::string("property.") + prop + ".writable")) { tree->graft(".properties." + quid_name + "." + prop, InfoTree::make(use_tree<MPtr(&InfoTree::branch_get_value)>( quid_name, std::string("property.") + prop + ".value"))); } } // Record shmdata connections. // Ignore them if no connect-to methods is installed for this quiddity. if (!manager_impl_->get_quiddity(quid_name)->has_method("connect")) continue; auto readers = use_tree<MPtr(&InfoTree::get_child_keys)>(quid_name, "shmdata.reader"); int nb = 0; for (auto& reader : readers) { if (!reader.empty()) { tree->graft(".readers." + quid_name + ".reader_" + std::to_string(++nb), InfoTree::make(reader)); } } tree->tag_as_array(".readers." + quid_name, true); } // calling on_saved callback for (auto& quid_name : quiddities) { manager_impl_->get_quiddity(quid_name)->on_saved(); } return JSONSerializer::serialize(tree.get()); }
InfoTree::ptr AnalogSourceDevice::getTree() const { InfoTree::ptr tree = SourceDevice::getTree(); tree->graft("type", InfoTree::make("vrpn_Analog")); tree->graft("numChannels", InfoTree::make(properties_.size())); return tree; }