/*------------------------------------------------------------------------------ * Copyright (c) 2023 by Bai Bing (seread@163.com) * S++ COPYING file for copying and redistribution conditions. * * Alians IT Studio. *----------------------------------------------------------------------------*/ #pragma once #include #include #include #include #include #include namespace ais { enum class TaskStatus : int { UNKNOWN = 0, UNASSIGNED, // not assigned to execute thread, added to avoid multi-assigned a task to different thread NOT_START, // assigned but not start RUNNING, COMPLETED, CANCELED, FAILED, SKIP, }; // task class carry task function to support multi calling class Task { public: Task() = default; //============================================================================ // Method Description: /// Individuals task which can be executing thread, use promise function to get task result /// /// @param name: task name which can be individually assigned /// @param func: task function /// @param args: task arguments /// @return Task /// /// Task construct for non-void return functions template , std::decay_t...>, typename = std::enable_if_t>> Task(const std::string &_name, const F &func, const A &...args) : name(_name), fun([func, args..., this]() { try { taskPromise.set_value(task(args...)); } catch (...) { taskPromise.set_exception(std::current_exception()); } }) { result = taskPromise.get_future(); } //============================================================================ // Method Description: /// Individuals task which can be executing thread, use promise function to get task result /// /// @param name: task name which can be individually assigned /// @param func: task function /// @param args: task arguments /// @return Task /// /// Task construct for void return functions template , std::decay_t...>>>> Task(const std::string &_name, const F &func, const A &...args) : name(_name), fun([func, args..., this]() { try { task(args...); taskPromise.set_value(true); } catch (...) { taskPromise.set_exception(std::current_exception()); } }) { result = taskPromise.get_future(); } std::shared_future result; // task name, used to identify task and search key in TaskManager std::string name; std::function fun; private: std::promise taskPromise; }; // task node class included task and task extended properties, // task manager will use task node as scheduling control // 1 task can be scheduled in multi node for clone tasks. struct TaskNode { public: std::shared_ptr p_task; // shared pointer to Task // clone id to identify the different clone tasks std::string clone_id = ""; TaskNode(std::shared_ptr _p_task, const std::string &_clone_id = "") : p_task(_p_task), clone_id(_clone_id) { // when create a task node by p_task, make it unassigned. status = TaskStatus::UNASSIGNED; }; TaskStatus status = TaskStatus::UNKNOWN; // task status bool is_async = false; // task is a async or not std::string async_fetch_task_name = ""; // async fetch task name // add_time will be setup while TaskNode have been constructed std::chrono::system_clock::time_point add_time = std::chrono::system_clock::now(); // time for task start and completed. std::chrono::system_clock::time_point start_time; std::chrono::system_clock::time_point complete_time; template const uint64_t executed_spend_time() { return complete_time <= start_time ? 0 : (uint64_t)std::chrono::duration_cast(complete_time - start_time).count(); } void exec(); // set up callback functions for main task fun before/completed void set_before_callback(std::function cb); void set_after_callback(std::function cb); void set_failed_callback(std::function cb); std::thread::id executor_tid; private: // callback functions std::function on_fun_before; std::function on_fun_completed; std::function on_fun_failed; }; } // namespace ais