Last active
August 29, 2015 14:17
-
-
Save yinyunqiao/cc37fbdafd1bc70f7cb0 to your computer and use it in GitHub Desktop.
Task manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Task | |
{ | |
public: | |
typedef map< string, Task * > TaskMap; | |
Task( const string & name ) : | |
_name( name ), | |
_succeed( false ), | |
_started ( false ) | |
{} | |
void addTask( Task * task ) | |
{ | |
assert ( task && task != this ); | |
if (_postTasks.find( task->name() ) != _postTasks.end()) | |
{ | |
return; | |
} | |
_postTasks[ task->name() ] = task; | |
task->addDepend( this ); | |
} | |
void removeTask ( Task * task ) { this->removeTask( task->name();} | |
void removeDepend( Task * task ) { this->removeDepend( task->name(); } | |
void removeTask ( const string & taskName ) | |
{ | |
TaskMap::iterator iter = _postTasks.find( taskName ); | |
if (iter == _postTasks.end()) | |
{ | |
return; | |
} | |
iter->second->removeDepend( this ); | |
_postTasks.erase( iter ); | |
} | |
void removeDepend ( const string & taskName ) | |
{ | |
TaskMap::iterator iter = _preTasks.find( taskName ); | |
if (iter == _preTasks.end()) | |
{ | |
return; | |
} | |
iter->second->removeTask( this ); | |
_preTasks.erase( iter ); | |
} | |
void addDepend( Task * task ) | |
{ | |
assert ( task && task != this ); | |
assert( !task->depend( this )); // check circular dependencies | |
if (_preTasks.find( task->name() ) != _preTasks.end()) | |
{ | |
return; | |
} | |
_preTasks[ task->name() ] = task; | |
task->addTask( this ); | |
} | |
const string & name() const { return _name; } | |
bool succeed() { return _succeed; } | |
bool fail() { return !_succeed; } | |
bool started() { return _started; } | |
bool canStart() | |
{ | |
for (TaskSet::const_iterator iter = _preTasks.begin(); iter != _preTsak.end(); ++iter) | |
{ | |
if (!(*iter)->started() || (*iter)->fail()) | |
return false; | |
} | |
return true; | |
} | |
void start() | |
{ | |
if (this->canStart()) | |
{ | |
_started = true; | |
this->run(); | |
} | |
this->runPostTasks(); | |
} | |
virtual void run() | |
{ | |
// default implementation | |
this->succeed( true ); | |
} | |
protected: | |
void succeed( bool result ) | |
{ | |
_succeed = result; | |
} | |
private: | |
bool depend( Task * task ) | |
{ | |
if (_preTasks.find( task->name() ) != _preTasks.end()) | |
{ | |
return true; | |
} | |
for (TaskSet::iterator iter = _preTasks.begin(); iter != _preTasks.end(); ++iter) | |
{ | |
if (this->depend( iter->second )) | |
{ | |
return true; | |
} | |
} | |
return false; | |
} | |
void runPostTasks() | |
{ | |
for (TaskSet::iterator iter = _postTasks.begin(); iter != _postTasks.end(); ++iter) | |
{ | |
*iter->second->start(); | |
} | |
} | |
string _name; | |
bool _started; | |
bool _succeed; | |
TaskMap _preTasks; | |
TaskMap _postTasks; | |
}; | |
//example: | |
Task a("A"), b("B"), c("C"), d("D"); | |
a.addTask( b ); | |
a.addTask( c ); | |
d.addDepend( b ); | |
d.addDepend( c ); | |
a.start(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment