#ifndef HYDRATASKSCHEDULER #define HYDRATASKSCHEDULER #include "../engine/HydraObject.h" #include "HydraTaskBarrier.h" #include "../task/HydraTask.h" #include #include #include #include #include class HydraThread; class HydraWorkItem; // class HydraTask; class CLASS_DEFINE HydraTaskScheduler : public HydraObject { private: std::vector m_barriers; std::queue m_available_barrier_ids; std::mutex m_mutex; bool m_waiting = false; bool m_running = true; HydraID m_waiting_id = INVALID_HYDRA_ID; std::vector m_general_thread; HydraThread *m_render_thread = nullptr; HydraThread *m_physics_thread = nullptr; std::vector m_tasks; std::vector m_task_ids_waiting_for_children; std::deque m_avaialble_task_ids; std::deque m_general_tasks_ready_to_run; std::deque m_render_tasks_ready_to_run; std::deque m_physics_tasks_ready_to_run; HydraID _SaveTask(HydraTask *taskItem); HydraID _GetRenderTaskReadyToRun(); HydraID _GetPhysicsTaskReadyToRun(); void _DecrementBarrier(HydraID taskID, HydraID barrierID); void _UpdateDependantTaskComplete(HydraID taskID); void _DeleteTask(HydraID taskID); void _AddTaskToBarrier(HydraID taskID, HydraID barrierID); void _StartTask(HydraID taskID, bool notifyThread = false); void _NotifyThread(std::thread::id thread_id); HydraID _CreateBarrier(); HydraTask *const _GetTask(HydraID taskID); HydraID _GetTaskReadyToRun(HydraThreadAffinity thread_affinity); void _CompleteBarrier(uint32_t barrierID); protected: public: template HydraID CreateTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID = INVALID_HYDRA_ID); template HydraID CreateAndStartTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID = INVALID_HYDRA_ID); HydraTask *const GetTask(HydraID taskID); void StartTask(HydraID taskID); void WaitForTask(HydraID taskID); HydraID CreateBarrier(); void AddTaskToBarrier(HydraID taskID, HydraID barrierID); void WaitForBarrier(HydraID barrierID); void DecrementBarrier(HydraID taskID, HydraID barrierID); void Initialise(int thread_count); void Shutdown(); void NotifyStart(HydraID taskID); void NotifyComplete(HydraID taskID); void ProcessTask(); void DeleteTask(HydraID taskID); }; template inline HydraID HydraTaskScheduler::CreateTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID) { std::lock_guard lock(m_mutex); T *taskType = new T(); HydraTask *task = dynamic_cast(taskType); if (task != nullptr) { task->m_barrierID = barrierID; task->ThreadAffinity = ThreadAffinity; HydraID id = _SaveTask(task); if (id != INVALID_HYDRA_ID) { _AddTaskToBarrier(id, barrierID); } else { delete taskType; } return id; } else { delete taskType; return INVALID_HYDRA_ID; } }; template inline HydraID HydraTaskScheduler::CreateAndStartTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID) { HydraID taskID = CreateTask(ThreadAffinity, barrierID); if (taskID != INVALID_HYDRA_ID) { StartTask(taskID); } return taskID; }; #endif /* HYDRATASKSCHEDULER */