//This file is part of Photon (http://photon.sourceforge.net) //Copyright (C) 2004-2005 James Turk // // Author: // James Turk (jpt2433@rit.edu) // // Version: // $Id: Kernel.cpp,v 1.4 2005/08/07 07:12:47 cozman Exp $ #include "Kernel.hpp" #include "exceptions.hpp" #include "Log.hpp" namespace photon { Kernel::Kernel() { } Kernel::~Kernel() { killAllTasks(); } void Kernel::step() { std::list::iterator it; // loop through active tasks, updating each one for(it = tasks_.begin(); it != tasks_.end(); ++it) { TaskPtr& task(*it); // only update alive, non-paused tasks if(task->isAlive() && !task->isPaused()) { task->update(); } } // loop through tasks, removing any dead tasks for(it = tasks_.begin(); it != tasks_.end(); ) { TaskPtr& task(*it); // remove dead tasks if(!task->isAlive()) { task->onKill(); // symmetry with onStart, clean up act it = tasks_.erase(it); } else { ++it; //advance iterator, if not deleting } } } void Kernel::run() { // loop on activeTasks while(!tasks_.empty()) { step(); } } void Kernel::addTask(TaskPtr task) { std::list::iterator it = tasks_.begin(); // attempt to find task std::list::iterator found = std::find_if(tasks_.begin(), tasks_.end(), std::bind2nd(TaskNameEq(), task->getName()) ); // if found task (meaning task w/ same name exists) throw exception if(found != tasks_.end()) { throw PreconditionException("Attempted to add duplicate task \"" + task->getName() + "\"."); } task->onStart(); // called whenever a task is being started // find the first task in the list with a lower priority while(it != tasks_.end() && (*it)->getPriority() <= task->getPriority()) { ++it; } tasks_.insert(it, task); // insert task after iterator } void Kernel::killTask(const std::string& taskName) { // attempt to find the task std::list::iterator task = std::find_if(tasks_.begin(), tasks_.end(), std::bind2nd(TaskNameEq(), taskName) ); if(task != tasks_.end()) // kill task if found { (*task)->kill(); } else { throw PreconditionException("Attempted to kill nonexistant task \"" + taskName + "\"."); } } void Kernel::pauseTask(const std::string& taskName) { // attempt to find the task std::list::iterator task = std::find_if(tasks_.begin(), tasks_.end(), std::bind2nd(TaskNameEq(), taskName) ); if(task != tasks_.end()) // pause task if found { (*task)->onPause(); } else { throw PreconditionException("Attempted to pause nonexistant task \"" + taskName + "\"."); } } void Kernel::unpauseTask(const std::string& taskName) { // attempt to find the task std::list::iterator task = std::find_if(tasks_.begin(), tasks_.end(), std::bind2nd(TaskNameEq(), taskName) ); if(task != tasks_.end()) // unpause task if found { (*task)->onUnpause(); } else { throw PreconditionException("Attempted to unpause nonexistant task \"" + taskName + "\"."); } } void Kernel::killAllTasks() { // set all tasks to dead for(std::list::iterator it = tasks_.begin(); it != tasks_.end(); ++it) { (*it)->kill(); } } bool Kernel::TaskNameEq::operator()(const TaskPtr& lhs, const std::string& rhs) const { return lhs->getName() == rhs; } }