浏览代码

#event_trigger修改

zxs 5 天之前
父节点
当前提交
7cb7704c37
共有 1 个文件被更改,包括 70 次插入97 次删除
  1. 70 97
      robot/robotics/event_trigger.hpp

+ 70 - 97
robot/robotics/event_trigger.hpp

@@ -14,102 +14,75 @@
 
 
 namespace robotics {
 namespace robotics {
 	namespace v3 {
 	namespace v3 {
-		template<typename ..._Args>
-		struct event_trigger {
-			event_trigger() {
-				start();
-			}
-			~event_trigger() {
-				stop();
-			}
-			/**
-			 * @brief 添加任务
-			 * @param sleep
-			 * @param ...args
-			 */
-			void add(time_t sleep, _Args const&...args) {
-				std::lock_guard<std::mutex> locker(mutex_);
-				task_list_.push_back(std::make_pair(std::make_tuple(args...), v3::utils::steady_time_stamp() + sleep));
-				cv_.notify_one();
-			}
-			/**
-			 * @brief 清空
-			 */
-			void clear() {
-				std::lock_guard<std::mutex> locker(mutex_);
-				task_list_.clear();
-			}
-			/**
-			 * @brief
-			 * @param fn
-			 */
-			void bind(std::function<void(_Args...)>&& fn) {
-				event.bind(std::move(fn));
-			}
-			/**
-			 * @brief
-			 * @param fn
-			 */
-			void operator+=(std::function<void(_Args...)>&& fn) {
-				bind(std::move(fn));
-			}
-			/**
-			 * @brief
-			 * @tparam _Fn
-			 * @tparam _Obj
-			 * @param fn
-			 * @param obj
-			 */
-			template<typename _Fn, typename _Obj>
-			void bind(_Fn&& fn, _Obj&& obj) {
-				bind(std::bind_front(std::move(fn), std::move(obj)));
-			}
-			/**
-			 * @brief 事件
-			 */
-			delegates<_Args...> event;
-		private:
-			void start() {
-				std::thread th(&event_trigger::thread_work, this);
-				thread_ = std::move(th);
-			}
-			void stop() {
-				running_ = false;
-				cv_.notify_all();
-				if (thread_.joinable())
-					thread_.join();
-			}
-			void on_event(int time, _Args...args) {
-				event(args...);
-			}
-			void thread_work() {
-				running_ = true;
-				while (running_) {
-					{
-						std::unique_lock<std::mutex> lock(mutex_);
-						while (task_list_.empty() && running_)
-							cv_.wait(lock);
-						time_t current_time = v3::utils::steady_time_stamp();
-						for (int i = 0; i < task_list_.size(); ++i) {
-							if (task_list_[i].second <= current_time) {
-								std::apply([&](auto&&...args) {
-									on_event(current_time - task_list_[i].second, std::forward<decltype(args)>(args)...);
-									}, task_list_[i].first);
-								task_list_.erase(task_list_.begin() + i);
-								--i;
-							}
-						}
-					}
-					std::this_thread::sleep_for(std::chrono::microseconds(1));
-				}
-				running_ = false;
-			}
-		private:
-			std::thread thread_;
-			bool running_ = false;
-			std::mutex mutex_;
-			std::condition_variable cv_;
-			std::vector<std::pair<std::tuple<_Args...>, time_t>> task_list_;
-		};
+        class event_trigger {
+            using _Func = std::function<void()>;
+        public:
+            /**
+             * @brief 构造
+             */
+            event_trigger() {
+                start();
+            }
+            /**
+             * @brief 虚构
+             */
+            ~event_trigger() {
+                stop();
+            }
+            /**
+             * @brief 添加任务
+             * @tparam _Fn
+             * @tparam _This
+             * @tparam ..._Args
+             * @param sleep
+             * @param fn
+             * @param ths
+             * @param ...args
+             */
+            template<typename _Fn, typename _This, typename ..._Args>
+            void add(int sleep, _Fn&& fn, _This&& ths, _Args&& ...args) {
+                std::shared_ptr<asio::steady_timer> timer = std::make_shared<asio::steady_timer>(io_, asio::chrono::milliseconds(sleep));
+                _Func bound_fn = std::bind(std::forward<_Fn>(fn), std::forward<_This>(ths), std::forward<_Args>(args)...);
+                std::size_t key = (std::size_t)timer.get();
+                {
+                    std::lock_guard<std::mutex> lock(mutex_);
+                    task_list_[key] = timer;
+                }
+                timer->async_wait(std::bind(&event_trigger::on_event, this, std::placeholders::_1, bound_fn, key));
+            }
+            v3::delegates<std::string const&> error_event;
+        private:
+            void start() {
+                thread_ = std::thread(&event_trigger::run, this);
+            }
+            void on_event(const asio::error_code& ec, _Func const& fn, std::size_t key) {
+                {
+                    std::lock_guard<std::mutex> lock(mutex_);
+                    task_list_.erase(key);
+                }
+                if (ec) {
+                    error_event(ec.message());
+                }
+                else {
+                    fn();
+                }
+            }
+            void stop() {
+                work_->reset();
+                if (thread_.joinable()) {
+                    thread_.join();
+                }
+            }
+            void run() {
+                work_.reset(new asio::executor_work_guard<asio::io_context::executor_type>(asio::make_work_guard(io_)));
+                io_.run();
+            }
+        private:
+            std::thread thread_;
+            std::mutex mutex_;
+            asio::io_context io_;
+            std::map<std::size_t, std::shared_ptr<asio::steady_timer>> task_list_;
+            std::shared_ptr<asio::executor_work_guard<asio::io_context::executor_type>> work_;
+        };
 	}
 	}
 }
 }