Skip to content

Instantly share code, notes, and snippets.

@yinyunqiao
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yinyunqiao/cc37fbdafd1bc70f7cb0 to your computer and use it in GitHub Desktop.
Save yinyunqiao/cc37fbdafd1bc70f7cb0 to your computer and use it in GitHub Desktop.
Task manager
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