[openrtm-commit:00655] r2300 - trunk/OpenRTM-aist/src/lib/rtm

openrtm @ openrtm.org openrtm @ openrtm.org
2012年 2月 4日 (土) 02:31:23 JST


Author: n-ando
Date: 2012-02-04 02:31:23 +0900 (Sat, 04 Feb 2012)
New Revision: 2300

Added:
   trunk/OpenRTM-aist/src/lib/rtm/ExecutionContextWorker.cpp
   trunk/OpenRTM-aist/src/lib/rtm/ExecutionContextWorker.h
Log:
[incompat,header/impl,func] ExecutionContextWorker class was implemented. refs #2346

Added: trunk/OpenRTM-aist/src/lib/rtm/ExecutionContextWorker.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/ExecutionContextWorker.cpp	                        (rev 0)
+++ trunk/OpenRTM-aist/src/lib/rtm/ExecutionContextWorker.cpp	2012-02-03 17:31:23 UTC (rev 2300)
@@ -0,0 +1,472 @@
+// -*- C++ -*-
+/*!
+ * @file ExecutionContextWorker.cpp
+ * @brief ExecutionContextWorker class
+ * @date $Date: 2008-01-14 07:53:01 $
+ * @author Noriaki Ando <n-ando at aist.go.jp>
+ *
+ * Copyright (C) 2006-2008
+ *     Noriaki Ando
+ *     Task-intelligence Research Group,
+ *     Intelligent Systems Research Institute,
+ *     National Institute of
+ *         Advanced Industrial Science and Technology (AIST), Japan
+ *     All rights reserved.
+ *
+ * $Id: ExecutionContextWorker.cpp 2271 2012-01-09 13:32:18Z n-ando $
+ *
+ */
+
+#include <algorithm>
+#include <iostream>
+#include <coil/Time.h>
+#include <coil/TimeValue.h>
+#include <rtm/RTObject.h>
+#include <rtm/RTObjectStateMachine.h>
+#include <rtm/ExecutionContextWorker.h>
+
+#define DEEFAULT_PERIOD 0.000001
+namespace RTC_impl
+{
+  /*!
+   * @if jp
+   * @brief デフォルトコンストラクタ
+   * @else
+   * @brief Default constructor
+   * @endif
+   */
+  ExecutionContextWorker::ExecutionContextWorker()
+    : rtclog("ec_worker"),
+      m_running(false)
+  {
+    RTC_TRACE(("ExecutionContextWorker()"));
+  }
+  
+  /*!
+   * @if jp
+   * @brief デストラクタ
+   * @else
+   * @brief Destructor
+   * @endif
+   */
+  ExecutionContextWorker::~ExecutionContextWorker()
+  {
+    RTC_TRACE(("~ExecutionContextWorker()"));
+  }
+
+  //============================================================
+  // Object reference to EC
+  //============================================================
+  void ExecutionContextWorker::setECRef(RTC::ExecutionContextService_ptr ref)
+  {
+    m_ref = RTC::ExecutionContextService::_duplicate(ref);
+  }
+  RTC::ExecutionContextService_ptr ExecutionContextWorker::getECRef()
+  {
+    return RTC::ExecutionContextService::_duplicate(m_ref);
+  }
+  
+  //============================================================
+  // ExecutionContext
+  //============================================================
+  /*!
+   * @if jp
+   * @brief ExecutionContext 実行状態確認関数
+   * @else
+   * @brief Check for ExecutionContext running state
+   * @endif
+   */
+  CORBA::Boolean ExecutionContextWorker::isRunning()
+  {
+    RTC_TRACE(("is_running()"));
+    return m_running;
+  }
+  
+  /*!
+   * @if jp
+   * @brief ExecutionContext の実行を開始
+   * @else
+   * @brief Start the ExecutionContext
+   * @endif
+   */
+  RTC::ReturnCode_t ExecutionContextWorker::start()
+  {
+    RTC_TRACE(("start()"));
+    Guard m_guard(m_mutex);
+    if (m_running)
+      {
+        RTC_WARN(("ExecutionContext is already running."));
+        return RTC::PRECONDITION_NOT_MET;
+      }
+    // invoke ComponentAction::on_startup for each comps.
+    for (size_t i(0); i < m_comps.size(); ++i)
+      {
+        m_comps[i]->onStartup();
+      }
+    RTC_DEBUG(("%d components started.", m_comps.size()));
+    // change EC thread state
+    m_running = true;
+
+    return RTC::RTC_OK;
+  }
+  
+  /*!
+   * @if jp
+   * @brief ExecutionContext の実行を停止
+   * @else
+   * @brief Stop the ExecutionContext
+   * @endif
+   */
+  RTC::ReturnCode_t ExecutionContextWorker::stop()
+  {
+    RTC_TRACE(("stop()"));
+    Guard m_guard(m_mutex);
+    if (!m_running)
+      {
+        RTC_WARN(("ExecutionContext is already stopped."));
+        return RTC::PRECONDITION_NOT_MET;
+      }
+    // stop thread
+    m_running = false;
+
+    // invoke on_shutdown for each comps.
+    for (size_t i(0); i < m_comps.size(); ++i)
+      {
+        m_comps[i]->onShutdown();
+      }
+    return RTC::RTC_OK;
+  }
+
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントをアクティブ化する
+   * @else
+   * @brief Activate an RT-Component
+   * @endif
+   */
+  RTC::ReturnCode_t
+  ExecutionContextWorker::activateComponent(RTC::LightweightRTObject_ptr comp,
+                                            RTObjectStateMachine*& rtobj)
+  {
+    RTC_TRACE(("activateComponent()"));
+    Guard m_guard(m_mutex);
+    RTObjectStateMachine* obj = findComponent(comp);
+    if (obj == NULL)
+      {
+        RTC_ERROR(("Given RTC is not participant of this EC."));
+        return RTC::BAD_PARAMETER;
+      }
+    RTC_DEBUG(("Component found in the EC."));
+    if (!(obj->isCurrentState(RTC::INACTIVE_STATE)))
+      {
+        RTC_ERROR(("State of the RTC is not INACTIVE_STATE."));
+        return RTC::PRECONDITION_NOT_MET;
+      }
+    RTC_DEBUG(("Component is in INACTIVE state. Going to ACTIVE state."));
+    obj->goTo(RTC::ACTIVE_STATE);
+    rtobj = obj;
+    RTC_DEBUG(("activateComponent() done."));
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントを非アクティブ化する
+   * @else
+   * @brief Deactivate an RT-Component
+   * @endif
+   */
+  RTC::ReturnCode_t
+  ExecutionContextWorker::deactivateComponent(RTC::LightweightRTObject_ptr comp,
+                                              RTObjectStateMachine*& rtobj)
+  {
+    RTC_TRACE(("deactivateComponent()"));
+    Guard m_guard(m_mutex);
+
+    rtobj = findComponent(comp);
+    if (rtobj == NULL)
+      {
+        RTC_ERROR(("Given RTC is not participant of this EC."));
+        return RTC::BAD_PARAMETER;
+      }
+    if (!(rtobj->isCurrentState(RTC::ACTIVE_STATE)))
+      {
+        RTC_ERROR(("State of the RTC is not ACTIVE_STATE."));
+        return RTC::PRECONDITION_NOT_MET;
+      }
+    rtobj->goTo(RTC::INACTIVE_STATE);
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントをリセットする
+   * @else
+   * @brief Reset the RT-Component
+   * @endif
+   */
+  RTC::ReturnCode_t
+  ExecutionContextWorker::resetComponent(RTC::LightweightRTObject_ptr comp,
+                                         RTObjectStateMachine*& rtobj)
+  {
+    RTC_TRACE(("resetComponent()"));
+    Guard m_guard(m_mutex);
+
+    rtobj = findComponent(comp);
+    if (rtobj == NULL)
+      {
+        RTC_ERROR(("Given RTC is not participant of this EC."));
+        return RTC::BAD_PARAMETER;
+      }
+    if (!(rtobj->isCurrentState(RTC::ERROR_STATE)))
+      {
+        RTC_ERROR(("State of the RTC is not ERROR_STATE."));
+        return RTC::PRECONDITION_NOT_MET;
+      }
+    rtobj->goTo(RTC::INACTIVE_STATE);
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントの状態を取得する
+   * @else
+   * @brief Get RT-Component's state
+   * @endif
+   */
+  RTC::LifeCycleState
+  ExecutionContextWorker::getComponentState(RTC::LightweightRTObject_ptr comp)
+  {
+    RTC_TRACE(("getComponentState()"));
+    Guard m_guard(m_mutex);
+    RTObjectStateMachine* rtobj = findComponent(comp);
+    if (rtobj == NULL)
+      {
+        RTC_WARN(("Given RTC is not participant of this EC."));
+        return RTC::CREATED_STATE;
+      }
+    RTC::LifeCycleState state = rtobj->getState();
+    RTC_DEBUG(("getComponentState() = %s done", getStateString(state)))
+    return state;
+  }
+
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントを追加する
+   * @else
+   * @brief Add an RT-Component
+   * @endif
+   */
+  RTC::ReturnCode_t
+  ExecutionContextWorker::addComponent(RTC::LightweightRTObject_ptr comp)
+  {
+    RTC_TRACE(("addComponent()"));
+    if (CORBA::is_nil(comp))
+      {
+        RTC_ERROR(("nil reference is given."));
+        return RTC::BAD_PARAMETER;
+      }
+    try
+      {
+        Guard guard(m_addedMutex);
+        RTC::ExecutionContextService_var ec = getECRef();
+        RTC::ExecutionContextHandle_t id = comp->attach_context(ec);
+        m_addedComps.push_back(new RTObjectStateMachine(id, comp));
+      }
+    catch (CORBA::Exception& e)
+      {
+        (void)(e);
+        RTC_ERROR(("addComponent() failed."));
+        return RTC::RTC_ERROR;
+      }
+    RTC_DEBUG(("addComponent() succeeded."));
+    return RTC::RTC_OK;
+  }
+  
+  RTC::ReturnCode_t ExecutionContextWorker::
+  bindComponent(RTC::RTObject_impl* rtc)
+  {
+    RTC_TRACE(("bindComponent()"));
+    Guard m_guard(m_mutex);
+    if (rtc == NULL)
+      {
+        RTC_ERROR(("NULL pointer is given."));
+        return RTC::BAD_PARAMETER;
+      }
+    RTC::ExecutionContextService_var ec = getECRef();
+    RTC::ExecutionContextHandle_t id = rtc->bindContext(ec);
+    if (id < 0 || id > ECOTHER_OFFSET) 
+      {
+        // id should be owned context id < ECOTHER_OFFSET
+        RTC_ERROR(("bindContext returns invalid id: %d", id));
+        return RTC::RTC_ERROR;
+      }
+    RTC_DEBUG(("bindContext returns id = %d", id));
+    
+    // rtc is owner of this EC
+    RTC::LightweightRTObject_var comp
+      = RTC::LightweightRTObject::_duplicate(rtc->getObjRef());
+    //    RTObjectStateMachine o(id, comp);
+    m_comps.push_back(new RTObjectStateMachine(id, comp));
+    RTC_DEBUG(("bindComponent() succeeded."));
+    return RTC::RTC_OK;
+  }
+  
+  /*!
+   * @if jp
+   * @brief コンポーネントをコンポーネントリストから削除する
+   * @else
+   * @brief Remove the RT-Component from participant list
+   * @endif
+   */
+  RTC::ReturnCode_t
+  ExecutionContextWorker::removeComponent(RTC::LightweightRTObject_ptr comp)
+  {
+    RTC_TRACE(("removeComponent()"));
+    if (CORBA::is_nil(comp))
+      {
+        RTC_ERROR(("nil reference is given."));
+        return RTC::BAD_PARAMETER;
+      }
+
+    Guard guard(m_mutex);
+    RTObjectStateMachine* rtobj = findComponent(comp);
+
+    if (rtobj == NULL)
+      {
+        RTC_ERROR(("no RTC found in this context."));
+        return  RTC::BAD_PARAMETER;
+      }
+    Guard removeGuard(m_removedMutex);
+    m_removedComps.push_back(rtobj);
+
+    return RTC::RTC_OK;
+  }
+
+  void ExecutionContextWorker::updateComponentList()
+  {
+    Guard guard(m_mutex);
+    {    // adding component
+      Guard addedGuard(m_addedMutex);
+      for (size_t i(0); i < m_addedComps.size(); ++i)
+        {
+          m_comps.push_back(m_addedComps[i]);
+          RTC_TRACE(("Component added."));
+        }
+      m_addedComps.clear();
+    }
+    {    // removing component
+      Guard removedGuard(m_removedMutex);
+      for (size_t i(0); i < m_removedComps.size(); ++i)
+        {
+          RTObjectStateMachine* rtobj = m_removedComps[i];
+          RTC::LightweightRTObject_var lwrtobj = rtobj->getRTObject();
+          lwrtobj->detach_context(rtobj->getExecutionContextHandle());
+          CompItr it;
+          it = std::find(m_comps.begin(), m_comps.end(), rtobj);
+          assert(*it == rtobj);
+          m_comps.erase(it);
+          delete rtobj;
+          RTC_TRACE(("Component deleted."));
+        }
+      m_removedComps.clear();
+    }
+  }
+
+  RTObjectStateMachine*
+  ExecutionContextWorker::findComponent(RTC::LightweightRTObject_ptr comp)
+  {
+    for (size_t i(0); i < m_comps.size() ; ++i)
+      {
+        if(m_comps.at(i)->isEquivalent(comp))
+          {
+            return m_comps.at(i);
+          }
+      }
+    return NULL;
+  }
+
+  bool ExecutionContextWorker::
+  isAllCurrentState(ExecContextState state)
+  {
+    Guard gurad(m_mutex);
+    for (size_t i(0); i < m_comps.size(); ++i)
+      {
+        if (!m_comps[i]->isCurrentState(state)) { return false; }
+      }
+    return true; 
+  }
+
+  bool ExecutionContextWorker::
+  isAllNextState(ExecContextState state)
+  {
+    Guard gurad(m_mutex);
+    for (size_t i(0); i < m_comps.size(); ++i)
+      {
+        if (!m_comps[i]->isNextState(state)) { return false; }
+      }
+    return true;
+  }
+
+  bool ExecutionContextWorker::
+  isOneOfCurrentState(ExecContextState state)
+  {
+    Guard gurad(m_mutex);
+    for (size_t i(0); i < m_comps.size(); ++i)
+      {
+        if (m_comps[i]->isCurrentState(state)) { return true; }
+      }
+    return false; 
+  }
+
+  bool ExecutionContextWorker::
+  isOneOfNextState(ExecContextState state)
+  {
+    Guard gurad(m_mutex);
+    for (size_t i(0); i < m_comps.size(); ++i)
+      {
+        if (m_comps[i]->isNextState(state)) { return true; }
+      }
+    return false;
+  }
+
+  void ExecutionContextWorker::invokeWorker()
+  {
+    RTC_PARANOID(("invokeWorker()"));
+    // m_comps never changes its size here
+    size_t len(m_comps.size());
+    for (size_t i(0); i < len; ++i) { m_comps[i]->workerPreDo();  }
+    for (size_t i(0); i < len; ++i) { m_comps[i]->workerDo();     }
+    for (size_t i(0); i < len; ++i) { m_comps[i]->workerPostDo(); }
+    updateComponentList();
+  }
+  
+  void ExecutionContextWorker::invokeWorkerPreDo()
+  {
+    RTC_PARANOID(("invokeWorkerPreDo()"));
+    Guard gurad(m_mutex);
+    size_t len(m_comps.size());
+    for (size_t i(0); i < len; ++i) { m_comps[i]->workerPreDo();  }
+  }
+
+  void ExecutionContextWorker::invokeWorkerDo()
+  {
+    RTC_PARANOID(("invokeWorkerDo()"));
+    Guard gurad(m_mutex);
+    size_t len(m_comps.size());
+    for (size_t i(0); i < len; ++i) { m_comps[i]->workerDo();     }
+  }
+
+  void ExecutionContextWorker::invokeWorkerPostDo()
+  {
+    RTC_PARANOID(("invokeWorkerPostDo()"));
+    Guard gurad(m_mutex);
+    size_t len(m_comps.size());
+    for (size_t i(0); i < len; ++i) { m_comps[i]->workerPostDo(); }
+    updateComponentList();
+  }
+  
+}; // namespace RTC_impl
+

Added: trunk/OpenRTM-aist/src/lib/rtm/ExecutionContextWorker.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/ExecutionContextWorker.h	                        (rev 0)
+++ trunk/OpenRTM-aist/src/lib/rtm/ExecutionContextWorker.h	2012-02-03 17:31:23 UTC (rev 2300)
@@ -0,0 +1,517 @@
+// -*- C++ -*-
+/*!
+ * @file ExecutionContextWorker.h
+ * @brief ExecutionContext's state machine worker class
+ * @date $Date$
+ * @author Noriaki Ando <n-ando at aist.go.jp>
+ *
+ * Copyright (C) 2011
+ *     Noriaki Ando
+ *     Intelligent Systems Research Institute,
+ *     National Institute of
+ *         Advanced Industrial Science and Technology (AIST), Japan
+ *     All rights reserved.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef RTC_EXECUTIONCONTEXTWORKER_H
+#define RTC_EXECUTIONCONTEXTWORKER_H
+
+#include <coil/Mutex.h>
+#include <coil/Condition.h>
+#include <vector>
+
+#include <rtm/idl/RTCSkel.h>
+#include <rtm/SystemLogger.h>
+//#include <rtm/StateMachine.h>
+//#include <rtm/RTObjectStateMachine.h>
+
+#define NUM_OF_LIFECYCLESTATE 4
+
+#ifdef WIN32
+#pragma warning( disable : 4290 )
+#endif
+
+namespace RTC
+{
+  class RTObject_impl;
+};  
+namespace RTC_impl
+{
+  class RTObjectStateMachine;
+  typedef RTC::LightweightRTObject_ptr LightweightRTObject_ptr;
+  typedef RTC::LightweightRTObject_var LightweightRTObject_var;
+  /*!
+   * @if jp
+   * @class PeriodicExecutionContext
+   * @brief PeriodicExecutionContext クラス
+   *
+   * Periodic Sampled Data Processing(周期実行用)ExecutionContextクラス。
+   *
+   * @since 0.4.0
+   *
+   * @else
+   * @class PeriodicExecutionContext
+   * @brief PeriodicExecutionContext class
+   *
+   * Periodic Sampled Data Processing (for the execution cycles)
+   * ExecutionContext class
+   *
+   * @since 0.4.0
+   *
+   * @endif
+   */
+  class ExecutionContextWorker
+  {
+    typedef coil::Guard<coil::Mutex> Guard;
+
+  public:
+    /*!
+     * @if jp
+     * @brief デフォルトコンストラクタ
+     *
+     * デフォルトコンストラクタ
+     * プロファイルに以下の項目を設定する。
+     *  - kind : PERIODIC
+     *  - rate : 0.0
+     *
+     * @else
+     * @brief Default Constructor
+     *
+     * Default Constructor
+     * Set the following items to profile.
+     *  - kind : PERIODIC
+     *  - rate : 0.0
+     *
+     * @endif
+     */
+    ExecutionContextWorker();
+
+
+    /*!
+     * @if jp
+     * @brief デストラクタ
+     *
+     * デストラクタ
+     *
+     * @else
+     * @brief Destructor
+     *
+     * Destructor
+     *
+     * @endif
+     */
+    virtual ~ExecutionContextWorker(void);
+
+    //============================================================
+    // Object reference to EC
+    //============================================================
+    void setECRef(RTC::ExecutionContextService_ptr ref);
+    RTC::ExecutionContextService_ptr getECRef();
+
+    //============================================================
+    // ExecutionContext
+    //============================================================
+    /*!
+     * @if jp
+     * @brief ExecutionContext 実行状態確認関数
+     *
+     * この操作は ExecutionContext が Runnning 状態の場合に true を返す。
+     * Executioncontext が Running の間、当該 Executioncontext に参加し
+     * ている全てのアクティブRTコンポーネントが、ExecutionContext の実
+     * 行種類に応じて実行される。
+     *
+     * @return 状態確認関数(動作中:true、停止中:false)
+     *
+     * @else
+     *
+     * @brief Check for ExecutionContext running state
+     *
+     * This operation shall return true if the context is in the
+     * Running state.  While the context is Running, all Active RTCs
+     * participating in the context shall be executed according to the
+     * context’s execution kind.
+     *
+     * @return Check state function (Running:true、Stopping:false)
+     *
+     * @endif
+     */
+    bool isRunning(void);
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext の実行を開始
+     *
+     * ExecutionContext の実行状態を Runnning とするためのリクエストを
+     * 発行する。ExecutionContext の状態が遷移すると
+     * ComponentAction::on_startup が呼び出される。参加しているRTコンポー
+     * ネントが、初期化されるまで ExecutionContext を開始することはでき
+     * ない。ExecutionContext は複数回開始/停止を繰り返すことができる。
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Start the ExecutionContext
+     *
+     * Request that the context enter the Running state.  Once the
+     * state transition occurs, the ComponentAction::on_startup
+     * operation will be invoked.  An execution context may not be
+     * started until the RT-Components that participate in it have
+     * been initialized.  An execution context may be started and
+     * stopped multiple times.
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    RTC::ReturnCode_t start(void);
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext の実行を停止
+     *
+     * ExecutionContext の状態を Stopped とするためのリクエストを発行す
+     * る。遷移が発生した場合は、ComponentAction::on_shutdown が呼び出
+     * される。参加しているRTコンポーネントが終了する前に
+     * ExecutionContext を停止する必要がある。ExecutionContext は複数回
+     * 開始/停止を繰り返すことができる。
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Stop the ExecutionContext
+     *
+     * Request that the context enter the Stopped state.  Once the
+     * transition occurs, the ComponentAction::on_shutdown operation
+     * will be invoked.  An execution context must be stopped before
+     * the RT components that participate in it are finalized.  An
+     * execution context may be started and stopped multiple times.
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    RTC::ReturnCode_t stop(void);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントをアクティブ化する
+     *
+     * Inactive 状態にあるRTコンポーネントをActive に遷移させ、アクティ
+     * ブ化する。この操作が呼ばれた結果、on_activate が呼び出される。指
+     * 定したRTコンポーネントが参加者リストに含まれない場合は、
+     * BAD_PARAMETER が返される。指定したRTコンポーネントの状態が
+     * Inactive 以外の場合は、PRECONDITION_NOT_MET が返される。
+     *
+     * @param comp アクティブ化対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Activate an RT-component
+     *
+     * The given participant RTC is Inactive and is therefore not
+     * being invoked according to the execution context’s execution
+     * kind. This operation shall cause the RTC to transition to the
+     * Active state such that it may subsequently be invoked in this
+     * execution context.  The callback on_activate shall be called as
+     * a result of calling this operation. This operation shall not
+     * return until the callback has returned, and shall result in an
+     * error if the callback does.
+     *
+     * @param comp The target RT-Component for activation
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    RTC::ReturnCode_t activateComponent(RTC::LightweightRTObject_ptr comp,
+                                        RTObjectStateMachine*& rtobj);
+    RTC::ReturnCode_t waitActivateComplete(RTObjectStateMachine*& rtobj,
+                                           coil::TimeValue timeout = 1.0,
+                                           long int cycle = 1000);
+    /*!
+     * @if jp
+     * @brief RTコンポーネントを非アクティブ化する
+     *
+     * Inactive 状態にあるRTコンポーネントを非アクティブ化し、Inactive
+     * に遷移させる。この操作が呼ばれた結果、on_deactivate が呼び出され
+     * る。指定したRTコンポーネントが参加者リストに含まれない場合は、
+     * BAD_PARAMETER が返される。指定したRTコンポーネントの状態が
+     * Active 以外の場合は、PRECONDITION_NOT_MET が返される。
+     *
+     * @param comp 非アクティブ化対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Deactivate an RT-component
+     *
+     * The given RTC is Active in the execution context. Cause it to
+     * transition to the Inactive state such that it will not be
+     * subsequently invoked from the context unless and until it is
+     * activated again.  The callback on_deactivate shall be called as
+     * a result of calling this operation. This operation shall not
+     * return until the callback has returned, and shall result in an
+     * error if the callback does.
+     *
+     * @param comp The target RT-Component for deactivate
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    RTC::ReturnCode_t deactivateComponent(RTC::LightweightRTObject_ptr comp,
+                                          RTObjectStateMachine*& rtobj);
+    RTC::ReturnCode_t waitDeactivateComplete(RTObjectStateMachine*& rtobj,
+                                             coil::TimeValue timeout = 1.0,
+                                             long int cycle = 1000);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントをリセットする
+     *
+     * Error 状態のRTコンポーネントの復帰を試みる。この操作が呼ばれた結
+     * 果、on_reset が呼び出される。指定したRTコンポーネントが参加者リ
+     * ストに含まれない場合は、BAD_PARAMETER が返される。指定したRTコン
+     * ポーネントの状態が Error 以外の場合は、PRECONDITION_NOT_MET が返
+     * される。
+     *
+     * @param comp リセット対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Reset the RT-component
+     *
+     * Attempt to recover the RTC when it is in Error.  The
+     * ComponentAction::on_reset callback shall be invoked. This
+     * operation shall not return until the callback has returned, and
+     * shall result in an error if the callback does. If possible, the
+     * RTC developer should implement that callback such that the RTC
+     * may be returned to a valid state.
+     *
+     * @param comp The target RT-Component for reset
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    RTC::ReturnCode_t resetComponent(RTC::LightweightRTObject_ptr com,
+                                     RTObjectStateMachine*& rtobj);
+    RTC::ReturnCode_t waitResetComplete(RTObjectStateMachine*& rtobj,
+                                        coil::TimeValue timeout = 1.0,
+                                        long int cycle = 1000);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントの状態を取得する
+     *
+     * 指定したRTコンポーネントの状態(LifeCycleState)を取得する。指定し
+     * たRTコンポーネントが参加者リストに含まれない場合は、
+     * UNKNOWN_STATE が返される。
+     *
+     * @param comp 状態取得対象RTコンポーネント
+     *
+     * @return 現在の状態(LifeCycleState)
+     *
+     * @else
+     *
+     * @brief Get RT-component's state
+     *
+     * This operation shall report the LifeCycleState of the given
+     * participant RTC.  UNKNOWN_STATE will be returned, if the given
+     * RT-Component is not inclued in the participant list.
+     *
+     * @param comp The target RT-Component to get the state
+     *
+     * @return The current state of the target RT-Component(LifeCycleState)
+     *
+     * @endif
+     */
+    RTC::LifeCycleState getComponentState(RTC::LightweightRTObject_ptr comp);
+    const char* getStateString(RTC::LifeCycleState state)
+    {
+      const char* st[] = {
+        "CREATED_STATE",
+        "INACTIVE_STATE",
+        "ACTIVE_STATE",
+        "ERROR_STATE"
+      };
+      return state >= RTC::CREATED_STATE || state <= RTC::ERROR_STATE ?
+        st[state] : "";
+    }
+    /*!
+     * @if jp
+     * @brief RTコンポーネントを追加する
+     *
+     * 指定したRTコンポーネントを参加者リストに追加する。追加されたRTコ
+     * ンポーネントは attach_context が呼ばれ、Inactive 状態に遷移する。
+     * 指定されたRTコンポーネントがnullの場合は、BAD_PARAMETER が返され
+     * る。指定されたRTコンポーネントが DataFlowComponent 以外の場合は、
+     * BAD_PARAMETER が返される。
+     *
+     * @param comp 追加対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Add an RT-component
+     *
+     * The operation causes the given RTC to begin participating in
+     * the execution context.  The newly added RTC will receive a call
+     * to LightweightRTComponent::attach_context and then enter the
+     * Inactive state.  BAD_PARAMETER will be invoked, if the given
+     * RT-Component is null or if the given RT-Component is other than
+     * DataFlowComponent.
+     *
+     * @param comp The target RT-Component for add
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    RTC::ReturnCode_t addComponent(RTC::LightweightRTObject_ptr comp);
+
+    /*!
+     * @if jp
+     * @brief コンポーネントをバインドする。
+     *
+     * コンポーネントをバインドする。
+     *
+     * @param rtc RTコンポーネント
+     * @return ReturnCode_t 型のリターンコード
+     * @else
+     * @brief Bind the component.
+     *
+     * Bind the component.
+     *
+     * @param rtc RT-Component's instances
+     * @return The return code of ReturnCode_t type
+     * @endif
+     */
+    RTC::ReturnCode_t bindComponent(RTC::RTObject_impl* rtc);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントを参加者リストから削除する
+     *
+     * 指定したRTコンポーネントを参加者リストから削除する。削除された
+     * RTコンポーネントは detach_context が呼ばれる。指定されたRTコンポー
+     * ネントが参加者リストに登録されていない場合は、BAD_PARAMETER が返
+     * される。
+     *
+     * @param comp 削除対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Remove the RT-Component from participant list
+     *
+     * This operation causes a participant RTC to stop participating in the
+     * execution context.
+     * The removed RTC will receive a call to
+     * LightweightRTComponent::detach_context.
+     * BAD_PARAMETER will be returned, if the given RT-Component is not 
+     * participating in the participant list.
+     *
+     * @param comp The target RT-Component for delete
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    RTC::ReturnCode_t removeComponent(RTC::LightweightRTObject_ptr comp);
+    RTObjectStateMachine* findComponent(RTC::LightweightRTObject_ptr comp);
+
+    bool isAllCurrentState(RTC::LifeCycleState state);
+    bool isAllNextState(RTC::LifeCycleState state);
+    bool isOneOfCurrentState(RTC::LifeCycleState state);
+    bool isOneOfNextState(RTC::LifeCycleState state);
+
+    void invokeWorker();
+    void invokeWorkerPreDo();
+    void invokeWorkerDo();
+    void invokeWorkerPostDo();
+    
+    
+  protected:
+    void updateComponentList();
+
+
+
+    /*!
+     * @if jp
+     * @brief コンポーネント検索用ファンクタ
+     * @else
+     * @brief Functor to find the component
+     * @endif
+     */
+//    struct find_comp
+//    {
+//      RTC::LightweightRTObject_var m_comp;
+//      find_comp(RTC::LightweightRTObject_ptr comp)
+//        : m_comp(RTC::LightweightRTObject::_duplicate(comp)) {}
+//      bool operator()(RTObjectStateMachine* comp)
+//      {
+//        return comp->isEquivalent(m_comp);
+//      }
+//    };
+
+    //------------------------------------------------------------
+    // member variables
+  protected:
+    /*!
+     * @if jp
+     * @brief ロガーストリーム
+     * @else
+     * @brief Logger stream
+     * @endif
+     */
+    RTC::Logger rtclog;
+
+    RTC::ExecutionContextService_var m_ref;
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext の実行状態
+     * true: running, false: stopped
+     * @else
+     * @brief The running state of ExecutionContext
+     * true: running, false: stopped
+     * @endif
+     */
+    bool m_running;
+
+    /*!
+     * @if jp
+     * @brief コンポーネントの参加者リスト
+     * @else
+     * @brief List of the participating component
+     * @endif
+     */
+    std::vector<RTC_impl::RTObjectStateMachine*> m_comps;
+    mutable coil::Mutex m_mutex;
+    std::vector<RTC_impl::RTObjectStateMachine*> m_addedComps;
+    mutable coil::Mutex m_addedMutex;
+    std::vector<RTC_impl::RTObjectStateMachine*> m_removedComps;
+    mutable coil::Mutex m_removedMutex;
+    typedef std::vector<RTC_impl::RTObjectStateMachine*>::iterator CompItr;
+
+  }; // class PeriodicExecutionContext
+}; // namespace RTC
+
+#ifdef WIN32
+#pragma warning( default : 4290 )
+#endif
+
+#endif // RTC_PERIODICEXECUTIONCONTEXT_H



openrtm-commit メーリングリストの案内