Jelajahi Sumber

修改了信号通知器

jcsyshc 3 tahun lalu
induk
melakukan
6e0343d057

+ 19 - 24
src/core/datanode_base.cpp

@@ -3,6 +3,7 @@
 #include "utility/bit_operations.hpp"
 #include "utility/coro_signal.hpp"
 #include "utility/statistic_timer.hpp"
+#include "utility/tiny_signal.hpp"
 
 #include <boost/asio/co_spawn.hpp>
 #include <boost/asio/detached.hpp>
@@ -10,7 +11,6 @@
 #include <boost/asio/high_resolution_timer.hpp>
 #include <boost/asio/this_coro.hpp>
 #include <boost/asio/use_awaitable.hpp>
-#include <boost/intrusive/list.hpp>
 
 #include <fmt/format.h>
 
@@ -30,26 +30,25 @@ namespace sophiar {
     template<typename FreqTag>
     struct datanode_base<FreqTag>::impl {
 
-        datanode_base *q_this = nullptr;
+        using state_type = typename tristate_obj<FreqTag>::state_type;
+        using connection_signal_type = tiny_signal<typename data_packet::pointer>;
 
-        using connection_hook = boost::intrusive::list_base_hook<
-                boost::intrusive::link_mode<
-                        boost::intrusive::auto_unlink> >;
-        struct connection_node_type : public connection_hook {
-            datanode_base *datanode;
+        struct connection_node_type : public connection_signal_type::listener_type {
+            impl *p_this;
             uint8_t channel_index;
-        };
 
-        using connection_list_type = boost::intrusive::list<
-                connection_node_type, boost::intrusive::constant_time_size<false> >;
+            void on_signal_received(typename data_packet::pointer packet) override {
+                p_this->update_input_data(channel_index, packet);
+            }
+        };
 
-        using state_type = typename tristate_obj<FreqTag>::state_type;
+        datanode_base *q_this = nullptr;
 
         typename data_packet::pointer input_data[MAX_CHANNEL_CNT];
         typename data_packet::pointer output_data[MAX_CHANNEL_CNT];
 
         connection_node_type channel_input_nodes[MAX_CHANNEL_CNT];
-        connection_list_type channel_output_list[MAX_CHANNEL_CNT];
+        connection_signal_type channel_output_list[MAX_CHANNEL_CNT];
         channel_mask_type input_update_mask = 0;
         channel_mask_type output_updated_mask = 0;
 
@@ -77,7 +76,12 @@ namespace sophiar {
         impl()
                 : trigger_timer(datanode_base::get_context()),
                   exec_cancel_signal(datanode_base::get_context()),
-                  run_finished_signal(datanode_base::get_context()) {}
+                  run_finished_signal(datanode_base::get_context()) {
+            for (uint8_t i = 0; i < MAX_CHANNEL_CNT; ++i) {
+                channel_input_nodes[i].p_this = this;
+                channel_input_nodes[i].channel_index = i;
+            }
+        }
 
         bool check_is_running() const {
             return q_this->get_state() == state_type::RUNNING;
@@ -90,9 +94,7 @@ namespace sophiar {
         void commit_output() {
             for (uint8_t i = 0; i < MAX_CHANNEL_CNT; ++i) {
                 if (test_bit(output_updated_mask, i)) {
-                    for (const auto &node: channel_output_list[i]) {
-                        node.datanode->update_input_data(node.channel_index, output_data[i]);
-                    }
+                    channel_output_list[i].emit_signal(output_data[i]);
                 }
             }
             output_updated_mask = 0;
@@ -236,10 +238,6 @@ namespace sophiar {
     datanode_base<FreqTag>::datanode_base()
             : pimpl(std::make_unique<impl>()) {
         pimpl->q_this = this;
-        for (uint8_t i = 0; i < MAX_CHANNEL_CNT; ++i) {
-            pimpl->channel_input_nodes[i].datanode = this;
-            pimpl->channel_input_nodes[i].channel_index = i;
-        }
     }
 
     template<typename FreqTag>
@@ -308,10 +306,7 @@ namespace sophiar {
         assert(sender_channel_index < MAX_CHANNEL_CNT);
         assert(receiver_channel_index < MAX_CHANNEL_CNT);
         auto &receiver_channel_node = receiver.pimpl->channel_input_nodes[receiver_channel_index];
-        if (receiver_channel_node.is_linked()) {
-            receiver_channel_node.unlink();
-        }
-        sender.pimpl->channel_output_list[sender_channel_index].push_back(receiver_channel_node);
+        sender.pimpl->channel_output_list[sender_channel_index].add_listener(receiver_channel_node);
     }
 
     template<typename FreqTag>

+ 3 - 7
src/main.cpp

@@ -13,23 +13,19 @@ using boost::asio::detached;
 
 using namespace sophiar;
 
-struct fake_state_listener : public ur_status_listener {
-    fake_state_listener()
-            : node(this) {}
-
-    void on_new_ur_status(const ur_status::pointer &status) override {
+struct fake_state_listener : public ur_status_signal_type::listener_type {
+    void on_signal_received(ur_status::pointer status) override {
         ++cnt;
     }
 
     size_t cnt = 0;
-    ur_status_signal_type::node_type node;
 };
 
 int main() {
     ur_interface ur;
     fake_state_listener listener;
     ur.set_ur_ip(boost::asio::ip::make_address_v4("192.168.38.141"));
-    ur.add_status_listener(listener.node);
+    ur.add_status_listener(listener);
     ur.set_report_frequency(125);
     auto func = [&]() -> boost::asio::awaitable<void> {
         co_await ur.init();

+ 2 - 4
src/robot/ur/ur_interface.cpp

@@ -426,9 +426,7 @@ namespace sophiar {
             };
             rtde_buffer >> data_packet;
             assert(data_packet.recipe_id == outputs_recipe_id);
-            ur_status_signal.emit_signal([=](ur_status_listener *listener) {
-                listener->on_new_ur_status(status);
-            });
+            ur_status_signal.emit_signal(status);
         }
 
         void handle_text_message() {
@@ -513,7 +511,7 @@ namespace sophiar {
         pimpl->ur_tcp = std::move(tcp);
     }
 
-    void ur_interface::add_status_listener(ur_status_signal_type::node_type &node) {
+    void ur_interface::add_status_listener(ur_status_signal_type::listener_type &node) {
         pimpl->ur_status_signal.add_listener(node);
     }
 

+ 2 - 6
src/robot/ur/ur_interface.h

@@ -74,11 +74,7 @@ namespace sophiar {
                        public small_obj<ur_status> {
     };
 
-    struct ur_status_listener {
-        virtual void on_new_ur_status(const ur_status::pointer &status) = 0;
-    };
-
-    using ur_status_signal_type = tiny_signal<ur_status_listener>;
+    using ur_status_signal_type = tiny_signal<ur_status::pointer>;
 
     class ur_interface : public tristate_obj<ur_freq_tag> {
     public:
@@ -99,7 +95,7 @@ namespace sophiar {
         // default 125Hz
         void set_report_frequency(double freq);
 
-        void add_status_listener(ur_status_signal_type::node_type &node);
+        void add_status_listener(ur_status_signal_type::listener_type &node);
 
         void set_tcp(ur_vector6d_pointer tcp);
 

+ 8 - 13
src/utility/tiny_signal.hpp

@@ -5,7 +5,7 @@
 
 #include <type_traits>
 
-template<typename ListenerType>
+template<typename... Args>
 class tiny_signal {
 public:
 
@@ -13,28 +13,23 @@ public:
             boost::intrusive::link_mode<
                     boost::intrusive::auto_unlink>>;
 
-    struct node_type : public hook_type {
-        ListenerType *listener;
-
-        explicit node_type(ListenerType *other = nullptr)
-                : listener(other) {}
+    struct listener_type : public hook_type {
+        virtual void on_signal_received(Args... args) = 0;
     };
 
     using list_type = boost::intrusive::list<
-            node_type, boost::intrusive::constant_time_size<false>>;
+            listener_type, boost::intrusive::constant_time_size<false>>;
 
-    void add_listener(node_type &node) {
+    void add_listener(listener_type &node) {
         if (node.is_linked()) {
             node.unlink();
         }
         node_list.push_back(node);
     }
 
-    template<typename FuncType>
-    std::enable_if_t<std::is_void_v<std::invoke_result_t<FuncType, ListenerType *>>>
-    emit_signal(FuncType &&func) const {
-        for (const auto &node: node_list) {
-            func(node.listener);
+    void emit_signal(Args... args) {
+        for (auto &node: node_list) {
+            node.on_signal_received(args...);
         }
     }