Orocos Real-Time Toolkit  2.6.0
SlaveActivity.cpp
00001 /***************************************************************************
00002   tag: Peter Soetens  Mon Jun 26 13:25:56 CEST 2006  SlaveActivity.cxx
00003 
00004                         SlaveActivity.cxx -  description
00005                            -------------------
00006     begin                : Mon June 26 2006
00007     copyright            : (C) 2006 Peter Soetens
00008     email                : peter.soetens@fmtc.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037 
00038 
00039 #include "SlaveActivity.hpp"
00040 #include "../os/MainThread.hpp"
00041 #include "Logger.hpp"
00042 
00043 namespace RTT {
00044     using namespace extras;
00045     using namespace base;
00046     SlaveActivity::SlaveActivity( ActivityInterface* master, RunnableInterface* run /*= 0*/ )
00047         :ActivityInterface(run), mmaster(master), mperiod( master->getPeriod() ), running(false), active(false)
00048     {
00049     }
00050 
00051     SlaveActivity::SlaveActivity( double period, RunnableInterface* run /*= 0*/ )
00052         :ActivityInterface(run), mmaster(0), mperiod(period), running(false), active(false)
00053     {
00054     }
00055 
00056     SlaveActivity::SlaveActivity( RunnableInterface* run /*= 0*/ )
00057         :ActivityInterface(run), mmaster(0), mperiod(0.0), running(false), active(false)
00058     {
00059     }
00060 
00061     SlaveActivity::~SlaveActivity()
00062     {
00063         stop();
00064     }
00065 
00066     Seconds SlaveActivity::getPeriod() const
00067     {
00068         if (mmaster)
00069             return mmaster->getPeriod(); // master can change period.
00070         return mperiod;
00071     }
00072 
00073     bool SlaveActivity::setPeriod(Seconds s) {
00074         if (mmaster)
00075             return false; // refuse to set period if master is involved.
00076         mperiod = s;
00077         return true;
00078     }
00079 
00080     unsigned SlaveActivity::getCpuAffinity() const
00081     {
00082         if (mmaster)
00083             return mmaster->getCpuAffinity();
00084         return ~0;
00085     }
00086 
00087     bool SlaveActivity::setCpuAffinity(unsigned cpu)
00088     {
00089         return false;
00090     }
00091 
00092     os::ThreadInterface* SlaveActivity::thread()
00093     {
00094         return mmaster ? mmaster->thread() : os::MainThread::Instance();
00095     }
00096 
00097     bool SlaveActivity::initialize()
00098     {
00099         return true;
00100     }
00101 
00102     void SlaveActivity::step()
00103     {
00104     }
00105 
00106     void SlaveActivity::loop()
00107     {
00108         this->step();
00109     }
00110 
00111     bool SlaveActivity::breakLoop()
00112     {
00113         return false;
00114     }
00115 
00116 
00117     void SlaveActivity::finalize()
00118     {
00119     }
00120 
00121     bool SlaveActivity::start()
00122     {
00123         if (mmaster && !mmaster->isActive())
00124         {
00125             Logger::log() << Logger::Error << "Unable to start slave as master activity is not running" << Logger::endl;
00126             return false;
00127         }
00128         if ( active == true )
00129         {
00130             Logger::log() << Logger::Error  << "Unable to start slave as it is already started" << Logger::endl;
00131             return false;
00132         }
00133 
00134         active = true;
00135 
00136         if ( runner ? runner->initialize() : this->initialize() ) {
00137             running = this->isPeriodic();
00138         } else {
00139             active = false;
00140         }
00141         return active;
00142     }
00143 
00144 
00145     bool SlaveActivity::stop()
00146     {
00147         if ( !active )
00148             return false;
00149 
00150         // use breakLoop if not periodic and within loop
00151         if ( this->isPeriodic() == false) {
00152             if ( running && (runner ? (runner->breakLoop() == false): (this->breakLoop() == false) ) )
00153                 return false;
00154         }
00155 
00156         running = false;
00157         if (runner)
00158             runner->finalize();
00159         else
00160             this->finalize();
00161         active = false;
00162         return true;
00163     }
00164 
00165     bool SlaveActivity::isRunning() const
00166     {
00167         return running;
00168     }
00169 
00170     bool SlaveActivity::isPeriodic() const
00171     {
00172         return mperiod != 0.0;
00173     }
00174     bool SlaveActivity::isActive() const
00175     {
00176         return active;
00177     }
00178 
00179     bool SlaveActivity::trigger()
00180     {
00181         if (mmaster)
00182             return mmaster->trigger();
00183         return false;
00184     }
00185 
00186     bool SlaveActivity::execute()
00187     {
00188         // non periodic case.
00189         if ( mperiod == 0.0 ) {
00190             if ( !active || running )
00191                 return false;
00192             running = true;
00193             if (runner)
00194                 runner->loop();
00195             else
00196                 this->loop();
00197             running = false;
00198             return true;
00199         }
00200 
00201         if ( running ) {
00202             if (runner) runner->step(); else this->step();
00203         }
00204         return running;
00205     }
00206 
00207 
00208 }