Browse Source

实现了载入变量默认值的功能

jcsyshc 2 năm trước cách đây
mục cha
commit
ea5ccc8f87

+ 28 - 0
src/core/basic_obj_types.hpp

@@ -135,6 +135,34 @@ namespace sophiar {
         return 3 * sizeof(double);
     }
 
+    template<typename SmallObjType>
+    struct basic_obj_traits {
+        using value_type = typename SmallObjType::value_type;
+        using element_type = value_type;
+        static constexpr size_t element_size = 1;
+    };
+
+    template<>
+    struct basic_obj_traits<transform_obj> {
+        using value_type = transform_obj::value_type;
+        using element_type = double;
+        static constexpr size_t element_size = 7;
+    };
+
+    template<>
+    struct basic_obj_traits<scalarxyz_obj> {
+        using value_type = scalarxyz_obj::value_type;
+        using element_type = double;
+        static constexpr size_t element_size = 3;
+    };
+
+    template<>
+    struct basic_obj_traits<array6_obj> {
+        using value_type = array6_obj::value_type;
+        using element_type = double;
+        static constexpr size_t element_size = 6;
+    };
+
 }
 
 #endif //SOPHIAR2_BASIC_OBJ_TYPES_HPP

+ 43 - 5
src/core/sophiar_pool.cpp

@@ -14,7 +14,7 @@ namespace sophiar {
     struct sophiar_pool::impl {
 
         struct variable_type_info {
-            using creator_func_type = void *(*)();
+            using creator_func_type = void *(*)(const nlohmann::json &);
 
             size_t binary_length;
             std::type_index type = typeid(void);
@@ -40,6 +40,43 @@ namespace sophiar {
 
         named_vector<variable_index_type, variable_info_impl> variable_pool;
 
+        template<typename SmallObjType>
+        static void *create_variable_pointer(const nlohmann::json &config) {
+            auto placeholder = new SmallObjType::pointer{};
+            if (!config.contains("value")) {
+                return (void *) placeholder;
+            }
+
+            // load default value
+            using elem_type = basic_obj_traits<SmallObjType>::element_type;
+            static constexpr auto elem_num = basic_obj_traits<SmallObjType>::element_size;
+
+            struct elem_provider {
+                std::array<elem_type, elem_num> vals = {};
+                size_t pos = 0;
+
+                auto &operator>>(elem_type &_val) {
+                    _val = vals[pos++];
+                    return *this;
+                }
+            };
+
+            auto provider = elem_provider{};
+            const auto &value_conf = config["value"];
+            if (!value_conf.is_array()) {
+                assert(elem_num == 1);
+                provider.vals[0] = value_conf.get<elem_type>();
+            } else {
+                assert(elem_num == value_conf.size());
+                for (int i = 0; i < elem_num; ++i) {
+                    provider.vals[i] = value_conf[i].get<elem_type>();
+                }
+            }
+            *placeholder = SmallObjType::new_instance();
+            (*placeholder)->fill_from(provider);
+            return (void *) placeholder;
+        }
+
         template<typename SmallObjType>
         void register_variable_type(std::string_view type_name) {
             static_assert(SmallObjType::binary_length() <= std::numeric_limits<uint8_t>::max());
@@ -58,7 +95,7 @@ namespace sophiar {
             type_info.binary_length = SmallObjType::binary_length();
             type_info.type = type;
             type_info.type_name = type_name;
-            type_info.creator_func = []() { return (void *) new SmallObjType::pointer; };
+            type_info.creator_func = create_variable_pointer<SmallObjType>;
 
             // create IO functions
 #define REGISTER_WRITER_FUNC(writer_type) { \
@@ -109,7 +146,8 @@ namespace sophiar {
         }
 
         void register_variable(std::string_view name,
-                               std::string_view type_name) {
+                               std::string_view type_name,
+                               const nlohmann::json &config = {}) {
             auto index = variable_pool.new_elem(name);
             auto &info = variable_pool[index];
 
@@ -117,7 +155,7 @@ namespace sophiar {
             auto var_type_index = variable_type_name_index_map.query(type_name);
             const auto &type_info = variable_type_info_pool[var_type_index];
 
-            info.placeholder = type_info.creator_func();
+            info.placeholder = type_info.creator_func(config);
             info.update_signal = new coro_signal2{};
             info.type_info = &type_info;
             info.last_update_ts = 0;
@@ -135,7 +173,7 @@ namespace sophiar {
             for (auto &var_config: config["variable_list"]) {
                 auto var_name = LOAD_STRING_ITEM2(var_config, "name");
                 auto type_name = LOAD_STRING_ITEM2(var_config, "type");
-                register_variable(var_name, type_name);
+                register_variable(var_name, type_name, var_config);
             }
         }
 

+ 9 - 2
src/utility/variable_utility.hpp

@@ -23,8 +23,8 @@ namespace sophiar {
     class string_writer {
     public:
 
-        explicit string_writer(std::string _sep = ", ")
-                : sep(std::move(_sep)) {}
+        explicit string_writer(std::string_view _sep = ", ")
+                : sep(_sep) {}
 
         template<typename T>
         string_writer &operator<<(const T &val) {
@@ -88,6 +88,13 @@ namespace sophiar {
         int sep_length;
     };
 
+    template<typename SmallObjType>
+    inline std::string variable_to_string(const SmallObjType &var) {
+        auto writer = string_writer{};
+        var.write_to(writer);
+        return writer.get_string_and_reset();
+    }
+
     template<typename SmallObjType>
     inline coro_worker::pointer variable_debug_watcher_func(const nlohmann::json &config) {
         std::string var_name;

+ 63 - 0
tests/core/sophiar_pool.cpp

@@ -0,0 +1,63 @@
+#define BOOST_TEST_DYN_LINK
+
+#include "core/basic_obj_types.hpp"
+#include "core/global_defs.h"
+#include "core/sophiar_pool.h"
+
+#include <boost/test/unit_test.hpp>
+
+#include <fstream>
+
+using namespace sophiar;
+
+BOOST_AUTO_TEST_CASE(test_sophiar_pool) {
+
+    std::ifstream config_file("data/sophiar_pool_config.json");
+    BOOST_TEST(config_file.is_open());
+    auto config = nlohmann::json::parse(config_file);
+    initialize(config);
+
+    {
+        auto var_index = REQUIRE_VARIABLE(bool_obj, "var_bool");
+        auto var_ptr = QUERY_VARIABLE(bool_obj, var_index);
+        BOOST_TEST(var_ptr != nullptr);
+        BOOST_TEST(var_ptr->value == true);
+    }
+    {
+        auto var_index = REQUIRE_VARIABLE(u64int_obj, "var_num");
+        auto var_ptr = QUERY_VARIABLE(u64int_obj, var_index);
+        BOOST_TEST(var_ptr != nullptr);
+        BOOST_TEST(var_ptr->value == 12345678);
+    }
+    {
+        auto var_index = REQUIRE_VARIABLE(double_obj, "var_float");
+        auto var_ptr = QUERY_VARIABLE(double_obj, var_index);
+        BOOST_TEST(var_ptr != nullptr);
+        BOOST_TEST(var_ptr->value == 1234.5678);
+    }
+    {
+        auto var_index = REQUIRE_VARIABLE(scalarxyz_obj, "var_vec");
+        auto var_ptr = QUERY_VARIABLE(scalarxyz_obj, var_index);
+        BOOST_TEST(var_ptr != nullptr);
+        BOOST_TEST(var_ptr->value.z() == 3);
+    }
+    {
+        auto var_index = REQUIRE_VARIABLE(transform_obj, "var_trans");
+        auto var_ptr = QUERY_VARIABLE(transform_obj, var_index);
+        BOOST_TEST(var_ptr != nullptr);
+        BOOST_TEST(var_ptr->value.translation().z() == 6);
+    }
+    {
+        auto var_index = REQUIRE_VARIABLE(transform_obj, "var_trans");
+        auto var_ptr = QUERY_VARIABLE(transform_obj, var_index);
+        BOOST_TEST(var_ptr != nullptr);
+        BOOST_TEST(var_ptr->value.translation().z() == 6);
+    }
+    {
+        auto var_index = REQUIRE_VARIABLE(array6_obj, "var_array");
+        auto var_ptr = QUERY_VARIABLE(array6_obj, var_index);
+        BOOST_TEST(var_ptr != nullptr);
+        BOOST_TEST(var_ptr->value[0] == 6);
+    }
+
+}

+ 55 - 0
tests/data/sophiar_pool_config.json

@@ -0,0 +1,55 @@
+{
+  "controller_port": 5277,
+  "variable_list": [
+    {
+      "name": "var_bool",
+      "type": "bool_obj",
+      "value": true
+    },
+    {
+      "name": "var_num",
+      "type": "u64int_obj",
+      "value": 12345678
+    },
+    {
+      "name": "var_float",
+      "type": "double_obj",
+      "value": 1234.5678
+    },
+    {
+      "name": "var_vec",
+      "type": "scalarxyz_obj",
+      "value": [
+        1,
+        2,
+        3
+      ]
+    },
+    {
+      "name": "var_trans",
+      "type": "transform_obj",
+      "value": [
+        4,
+        5,
+        6,
+        1,
+        0,
+        0,
+        0
+      ]
+    },
+    {
+      "name": "var_array",
+      "type": "array6_obj",
+      "value": [
+        6,
+        5,
+        4,
+        3,
+        2,
+        1
+      ]
+    }
+  ],
+  "object_list": []
+}