Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F129977
TaskManager.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
TaskManager.h
View Options
#ifndef _ECHO_TASKMANAGER_H_
#define _ECHO_TASKMANAGER_H_
#include
<list>
#include
<queue>
#include
<echo/Types.h>
#include
<echo/Chrono/Chrono.h>
#include
<echo/Kernel/Task.h>
#include
<echo/cpp/functional>
namespace
Echo
{
class
Task
;
/**
* TaskManagers manages a list of tasks.
* Tasks are added to task managers in order to be updated, receive pause and resume
* notifications and are started and stopped as needed.
*
*/
class
TaskManager
:
public
InheritableEnableSharedFromThis
<
TaskManager
>
{
public
:
typedef
function
<
void
(
void
)
>
Action
;
TaskManager
(
std
::
string
name
=
""
);
virtual
~
TaskManager
();
/**
* Check if the manager has a task.
*/
bool
HasTask
(
Task
*
task
)
const
;
/**
* Check if the manager has a task.
*/
bool
HasTask
(
Task
&
task
)
const
{
return
HasTask
(
&
task
);
}
/**
* Check if the manager has at least one task.
*/
inline
bool
HasAtLeastOneTask
()
const
{
return
!
mTaskList
.
empty
();
}
/**
* Set the TaskManager name.
*/
virtual
void
SetTaskManagerName
(
const
std
::
string
&
name
)
{
mManagerName
=
name
;
}
/**
* Get the TaskManager name.
*/
const
std
::
string
&
GetTaskManagerName
()
const
{
return
mManagerName
;
}
/**
* Get whether the TaskManager is executing.
*/
bool
GetExecuting
()
const
{
return
mExecuting
;
}
/**
* Get whether the TaskManager is paused.
* The paused state of a manager changes when PauseAllActiveTasks(),
* ResumeAllPreviouslyActiveTasks() or ResumeAllTasks() is called.
*/
bool
GetPaused
()
const
{
return
mPaused
;
}
/**
* Calling this method will cause the Task's OnStart() method to be called.
* If any task fails to start (OnStart() returns false) then all tasks are stopped and
* this method will return false. This method returns true if all tasks successfully start.
*
* Normally this method is called by another TaskManager or TaskGroup when a Kernel starts,
* however if you are managing the Updates of a TaskManager yourself call this method to
* before you begin calling UpdateTasks(). This essentially changes the state of
* TaskManager to "executing" to ensure newly added tasks are started and updated. Call
* this method on your manually updated TaskManager before updates even if you haven't
* added any tasks.
*
* The main purpose of StartTasks() is to provide tasks an opportunity to do something at
* the beginning of their execution, which is different to Puase() and Resume(), which might
* happen many times during execution. This provides tasks an OnStart() notification.
*
* All tasks in the list, whether active or not, will have their Start(), and subsequently
* OnStart() methods called.
*/
bool
StartTasks
();
/**
* Stop all tasks.
* This modifies the internal state of the manager to not executing.
*
* The method does not modify the task lists. i.e. the active task list will remain active.
* It is expected that after StopTasks() you will no longer call UpdateTasks(), however if
* you do the active tasks will still be updated. This is not a bug and by design to allow
* task manages top be stopped, moved then started again without changing the task lists.
*
* Similar to StartTasks() the main purpose of StopTasks() is to provide tasks an opportunity
* to do something at end of their execution, which is different to Puase() and Resume(),
* which might happen many times during execution. This provides tasks an OnStart()
* notification.
*
* All tasks in the list, whether active or not, will have their Stop(), and subsequently
* OnStop() called.
*/
void
StopTasks
();
/**
* Add a task to the manager.
*
* After a Tasks is added it will be resumed if it was previously paused. This is due to the
* assumption that a Task that is added to the manager is ready to be updated. If you want
* a task to be paused, add it then pause it.
*
* If the TaskManager is executing the Task's Start() method will be called.
*
* Tasks will notify any managers they are members of when they are deleted so this is
* effectively as safe as using a shared pointer.
* @returns false if the task has already been added to this manager or if the Task's Start()
* method returns false.
*/
bool
AddTask
(
Task
*
task
)
{
return
AddTask
(
task
,
shared_ptr
<
Task
>
());
}
/**
* Overload of AddTask() that takes a reference.
* Tasks will notify any managers they are members of when they are deleted so this is
* effectively as safe as using a shared pointer.
* @see AddTask(Task* task)
*/
bool
AddTask
(
Task
&
task
)
{
return
AddTask
(
&
task
,
shared_ptr
<
Task
>
());
}
/**
* Overload of AddTask() that takes a shared pointer.
* @see AddTask(Task* task)
*/
bool
AddTask
(
shared_ptr
<
Task
>
task
)
{
return
AddTask
(
task
.
get
(),
task
);
}
/**
* Remove a task from the manager.
*/
void
RemoveTask
(
Task
*
tTask
);
/**
* Remove a task from the manager.
*/
void
RemoveTask
(
Task
&
task
)
{
RemoveTask
(
&
task
);
}
/**
* Remove a task from the manager.
* The task does not need to be added using a shared pointer for this to work since
* TaskManagers use raw pointers for comparison.
*/
void
RemoveTask
(
shared_ptr
<
Task
>
task
)
{
RemoveTask
(
task
.
get
());
}
/**
* Remove a task by name from the manager.
* The name of a task is not cached when added, so the comparison is against any current task names.
*/
void
RemoveTask
(
const
std
::
string
&
taskName
);
/**
* Remove all tasks from the manager.
* This clears all tasks from the task list.
*/
void
RemoveAllTasks
();
/**
* Pause a task by name.
* This method performs a search and if a task is found it is paused.
* @see FindTask()
* @param taskName the name of the task to look for.
* @param deepSearch whether or not to perform a deepSearch.
* @return true if the task was found.
*/
bool
PauseTask
(
const
std
::
string
&
taskName
,
bool
deepSearch
);
/**
* Resume a task by name.
* This method performs a search and if a task is found it is resumed.
* @see FindTask()
* @param taskName the name of the task to look for.
* @param deepSearch whether or not to perform a deepSearch.
* @return true if the task was found.
*/
bool
ResumeTask
(
const
std
::
string
&
taskName
,
bool
deepSearch
);
/**
* Search for a task.
* Searching is performed in this object first then if deepSearch is true the search
* will continue in each child TaskManager.
* @param name the name of the task to search for.
* @param deepSearch if a matching task isn't found in the TaskManager each task will be checked to see if
* it is a TaskManager and continue the search from there.
* @return A pointer to the task if found, otherwise a null pointer.
*/
Task
*
FindTask
(
const
std
::
string
&
name
,
bool
deepSearch
);
/**
* Search for a task by name and attempt to get the shared pointer for it.
* @note The task needs to have been added using AddTask(shared_ptr<Task>).
* @see FindTask()
* @return A pointer to the task if found, otherwise a null pointer.
*/
shared_ptr
<
Task
>
FindSharedTask
(
const
std
::
string
&
name
,
bool
deepSearch
);
/**
* Search for a task by name and attempt to get the cast pointer for it.
* @see FindTask()
* @return A pointer to the task if found, otherwise null pointer.
*/
template
<
class
T
>
T
*
FindTask
(
const
std
::
string
&
name
,
bool
deepSearch
)
{
return
dynamic_cast
<
T
*>
(
FindTask
(
name
,
deepSearch
));
}
/**
* Search for a task by name and attempt to get the cast shared pointer for it.
* @note The task needs to have been added using AddTask(shared_ptr<Task>).
* @see FindSharedTask()
* @return A pointer to the task if found, otherwise a null pointer.
*/
template
<
class
T
>
shared_ptr
<
T
>
FindSharedTask
(
const
std
::
string
&
name
,
bool
deepSearch
)
{
return
dynamic_pointer_cast
<
T
>
(
FindSharedTask
(
name
,
deepSearch
));
}
/**
* Pause all active tasks.
* This results in the TaskManager state changing to paused.
*/
void
PauseAllActiveTasks
(
bool
applicationPause
=
false
);
/**
* Resume all previously active tasks.
* This results in the task manager's state to change to resumed.
*/
void
ResumeAllPreviouslyActiveTasks
(
bool
applicationResume
=
false
);
/**
* Resume all tasks.
* This method resumes all active tasks but does not change the task managers resumed state.
*/
void
ResumeAllTasks
(
bool
applicationResume
=
false
);
void
TaskWasPaused
(
Task
&
task
);
void
TaskWasResumed
(
Task
&
task
);
/**
* Update all active tasks.
* Calling this after StopTasks() may still result in tasks being updated. @see StopTasks() for more information.
*/
void
UpdateTasks
(
Seconds
lastFrameTime
);
//!\ brief Get the number of active tasks in this manager.
//!\ param includeChildTaskManagerTasks if true include the number of tasks active in child state manages too.
//!\ param outputTaskList Outputs task names to std cout.
//!\ param indendDepth this method is recursive and this parameter is used to set the indent depth for the task lists.
size_t
GetNumberOfActiveTasks
(
bool
includeChildTaskManagerTasks
=
true
,
bool
outputTaskList
=
false
,
size_t
indentDepth
=
0
)
const
;
//!\ brief Get the number of tasks in this manager.
//!\ param includeChildTaskManagerTasks if true include the number of tasks active in child state manages too.
//!\ param outputTaskList Outputs task names to std cout.
//!\ param indendDepth this method is recursive and this parameter is used to set the indent depth for the task lists.
size_t
GetNumberOfTasks
(
bool
includeChildTaskManagerTasks
=
false
,
bool
outputTaskList
=
false
,
size_t
indentDepth
=
0
)
const
;
/**
* Queue some action to be executed following the completion of the current or next UpdateTasks() call.
* Actions are executed after UpdateTasks() finishes updating tasks so if the action is queued during an update it will
* be performed immediately after, otherwise it will be performed after the next UpdateTasks() call.
* updated.
* This can be used when you're in a situation that you want to clean up some task in a hierarchy but doing so would delete
* object that are in use/part way through updating. TaskManager tasks care of these situations with tasks automatically
* and never updates deleted, removed or paused tasks even part way through an update but it has no control over
* specialised Tasks.
* @note Actions cannot be cancelled so only queue actions that you know will be valid when the TaskManager gets around to
* executing them.
* @param action Generic action to be called. The action is executed once then discarded.
*/
void
QueuePostUpdateAction
(
Action
action
);
private
:
void
UpdateLists
();
/**
* Internal structure used to manage the different ways a task might be added to a manager and
* to provide a consistent way for the manager to use Tasks without checking how each task was
* added to the manager.
*/
class
TaskInfo
{
public
:
TaskInfo
(
Task
*
task
,
shared_ptr
<
Task
>
taskPtr
=
shared_ptr
<
Task
>
())
{
mHasBeenRemoved
=
make_shared
<
bool
>
(
false
);
mHasBeenPaused
=
make_shared
<
bool
>
(
false
);
mWaitingForResume
=
make_shared
<
bool
>
(
false
);
mWaitingForPauseProcessing
=
make_shared
<
bool
>
(
false
);
mCurrentPriority
=
task
->
GetPriority
();
mTask
=
task
;
mTaskPtr
=
taskPtr
;
}
TaskInfo
(
const
TaskInfo
&
otherTaskInfo
)
{
mTask
=
otherTaskInfo
.
mTask
;
mTaskPtr
=
otherTaskInfo
.
mTaskPtr
;
mHasBeenRemoved
=
otherTaskInfo
.
mHasBeenRemoved
;
mHasBeenPaused
=
otherTaskInfo
.
mHasBeenPaused
;
mWaitingForResume
=
otherTaskInfo
.
mWaitingForResume
;
mWaitingForPauseProcessing
=
otherTaskInfo
.
mWaitingForPauseProcessing
;
mCurrentPriority
=
otherTaskInfo
.
mCurrentPriority
;
}
TaskInfo
&
operator
=
(
const
TaskInfo
&
otherTaskInfo
)
{
if
(
this
==
&
otherTaskInfo
)
return
*
this
;
mTask
=
otherTaskInfo
.
mTask
;
mTaskPtr
=
otherTaskInfo
.
mTaskPtr
;
mHasBeenRemoved
=
otherTaskInfo
.
mHasBeenRemoved
;
mHasBeenPaused
=
otherTaskInfo
.
mHasBeenPaused
;
mWaitingForResume
=
otherTaskInfo
.
mWaitingForResume
;
mWaitingForPauseProcessing
=
otherTaskInfo
.
mWaitingForPauseProcessing
;
mCurrentPriority
=
otherTaskInfo
.
mCurrentPriority
;
return
*
this
;
}
bool
operator
<
(
const
TaskInfo
&
other
)
const
{
return
(
mCurrentPriority
<
other
.
mCurrentPriority
);
}
bool
operator
==
(
const
TaskInfo
&
otherTaskInfo
)
const
{
return
(
mTask
==
otherTaskInfo
.
GetTask
());
}
bool
operator
==
(
const
Task
*
otherTask
)
const
{
return
(
mTask
==
otherTask
);
}
inline
Task
*
GetTask
()
const
{
return
mTask
;
}
inline
shared_ptr
<
Task
>
GetSharedTask
()
{
return
mTaskPtr
;
}
inline
bool
GetHasBeenRemoved
()
const
{
return
*
mHasBeenRemoved
;
}
void
SetHasBeenRemoved
(
bool
hasBeenRemoved
)
{
*
mHasBeenRemoved
=
hasBeenRemoved
;
}
inline
bool
GetHasBeenPaused
()
const
{
return
*
mHasBeenPaused
;
}
void
SetHasBeenPaused
(
bool
hasBeenPaused
)
{
*
mHasBeenPaused
=
hasBeenPaused
;
}
inline
bool
GetWaitingForResume
()
const
{
return
*
mWaitingForResume
;
}
inline
bool
GetWaitingForPauseProcessing
()
const
{
return
*
mWaitingForPauseProcessing
;
}
void
SetWaitingForResume
(
bool
hasBeenResumed
)
{
*
mWaitingForResume
=
hasBeenResumed
;
}
void
SetWaitingForPauseProcessing
(
bool
hasBeenPaused
)
{
*
mWaitingForPauseProcessing
=
hasBeenPaused
;
}
void
UpdatePriority
()
{
if
(
mTask
)
{
mCurrentPriority
=
mTask
->
GetPriority
();
}
}
private
:
Task
*
mTask
;
shared_ptr
<
Task
>
mTaskPtr
;
//!< If the task is added as a shared pointer this will be set.
u32
mCurrentPriority
;
/*
* These members are always going to be valid pointers. They are shared
* pointers to reflect the state between lists.
*/
shared_ptr
<
bool
>
mHasBeenRemoved
;
//!< Task has been removed.
shared_ptr
<
bool
>
mHasBeenPaused
;
//!< Task has been paused.
shared_ptr
<
bool
>
mWaitingForResume
;
//!< Task is waiting for resume processing to get into the active list.
shared_ptr
<
bool
>
mWaitingForPauseProcessing
;
//!< Task is waiting for pause processing to be removed from the active list.
};
typedef
std
::
list
<
TaskInfo
>
TaskList
;
typedef
TaskList
::
iterator
TaskListIterator
;
typedef
TaskList
::
const_iterator
TaskListConstIterator
;
bool
AddTask
(
Task
*
task
,
shared_ptr
<
Task
>
taskPtr
);
std
::
vector
<
Action
>
mPostUpdateActions
;
std
::
string
mManagerName
;
TaskList
mTaskList
;
TaskList
mActiveTaskList
;
TaskList
mPreviouslyActiveTaskList
;
bool
mExecuting
;
bool
mPaused
;
bool
mUpdating
;
};
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Mon, May 19, 10:25 AM (14 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
76959
Default Alt Text
TaskManager.h (15 KB)
Attached To
Mode
rEE Echo 3
Attached
Detach File
Event Timeline
Log In to Comment