Newer
Older
Import / projects / Gameloft / glwebtools / include / glwebtools / os / glwebtools_taskgroup.h
#pragma once
#ifndef _GLWEBTOOLS_TASKGROUP_INCLUDED_
#define _GLWEBTOOLS_TASKGROUP_INCLUDED_

#include <glwebtools/os/glwebtools_threadpool.h>
#include <list>

namespace glwebtools
{
	struct Task
	{
	public:
		typedef unsigned long Id;
		typedef int Priority;

	public:
		Task();

	public:
		Job m_job;
		Id m_id;
		Priority m_priority;
	};

	class TaskQueue
	{
	public:
		typedef std::list<Task> QueueType;

	public:
		//! Schedule a tasks
		glwebtools::Error PushTask(const Task& task);
		//! Re-Schedule a popped task
		glwebtools::Error Reschedule(QueueType::const_iterator begin, QueueType::const_iterator end);
		//! Select a task to be executed
		glwebtools::Error PopTask(Task& task);
		//! Remove all tasks matching the id 
		glwebtools::Error RemoveTask(Task::Id id);
		//! Returns whether this task is scheduled
		bool IsScheduled(Task::Id id) const;
		//! Cancel all tasks
		void Clear();
		/*! Returns count of tasks in the queue
		*/
		size_t Size() const;
		//! Returns whether the queue is empty
		bool Empty() const;

	private:
		QueueType m_tasks;
	};

	class TaskGroup
	{
	public:
		typedef ThreadPool::CreationSettings CreationSettings;

	public:
		//! Default Constructor
		TaskGroup();

		//! Destructor
		~TaskGroup();

		//! Initialize the thread pool
		glwebtools::Error Initialize(const CreationSettings& creationSettings);

		//! Terminate the thread pool
		void Terminate();

		/*! Select scheduled taks from the queue and assign them to available threads
		\param delta_time_ms delta time (ms)
		*/
		glwebtools::Error Update(u64 delta_time_ms);

		//! Returns whether this instance is initialized
		bool IsInitialized() const;

		/*! Schedule a task
		Tasks of higher priority are scheduled first, tasks of same priority are scheduled in fifo order.
		\param task the task to schedule
		\param priority of the task to schedule ()
		\param[out] id The id given to this task in the TaskGroup
		*/
		glwebtools::Error PushTask(Task::Id* id, const Job& job, Task::Priority priority = 0);

		//! Remove all tasks matching the id 
		glwebtools::Error RemoveTask(Task::Id id);

		//! Returns whether this task is scheduled
		bool IsScheduled(Task::Id id) const;

		/*! Get count of tasks in the queue
		*/
		size_t Size() const;

		//! Returns whether the queue is empty
		bool Empty() const;

		/*! Returns whether all tasks are completed.
		Tasks are completed when the queue is empty and the threadpool is idle.
		*/
		bool Completed() const;

		//! Returns whether some thread are not idle.
		bool SomeThreadStarted() const;

	private:
		//! Scheduled tasks
		TaskQueue m_tasks;
		//! ThreadPool of threads, running or waiting
		ThreadPool m_threadpool;
		//! Mutex to synchronize all operations on this instance
		mutable Mutex m_mutex;
		//! Task counter to provide task ids
		Task::Id m_task_count;
	};

}//namespace glwebtools

#endif  //_GLWEBTOOLS_TASKGROUP_INCLUDED_