Timer.py
Go to the documentation of this file.
00001 #!/usr/bin/env/python
00002 # -*- coding: euc-jp -*-
00003 
00004 ##
00005 # @file Timer.py
00006 # @brief Timer class
00007 # @date $Date: $
00008 # @author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara
00009 #
00010 # Copyright (C) 2007-2008
00011 #     Task-intelligence Research Group,
00012 #     Intelligent Systems Research Institute,
00013 #     National Institute of
00014 #         Advanced Industrial Science and Technology (AIST), Japan
00015 #     All rights reserved.
00016 
00017 
00018 import time
00019 import threading
00020 
00021 import OpenRTM_aist
00022 
00023 
00024 ##
00025 # @if jp
00026 # @class Timer
00027 # @brief Timerクラス
00028 # 
00029 # 登録されたリスナーのコールバック関数を、設定された周期で定期的に呼び出す。
00030 #
00031 # @since 0.4.0
00032 #
00033 # @else
00034 #
00035 # @class Timer
00036 # @brief Timer class
00037 # 
00038 # Invoke the callback function of registered listener periodically
00039 # at the set cycle.
00040 #
00041 # @since 0.4.0
00042 #
00043 # @endif
00044 class Timer:
00045   """
00046   """
00047 
00048   ##
00049   # @if jp
00050   # @brief コンストラクタ
00051   # 
00052   # コンストラクタ
00053   #
00054   # @param self
00055   # @param interval タイマ起動周期
00056   #
00057   # @else
00058   #
00059   # @brief Constructor
00060   # 
00061   # Constructor
00062   #
00063   # @param interval The interval of timer
00064   #
00065   # @endif
00066   def __init__(self, interval):
00067     self._interval = interval
00068     self._running  = False
00069     self._runningMutex = threading.RLock()
00070     self._tasks = []
00071     self._taskMutex = threading.RLock()
00072     self._thread = threading.Thread(target=self.run)
00073     return
00074 
00075   ##
00076   # @if jp
00077   # @brief デストラクタ
00078   # 
00079   # デストラクタ
00080   #
00081   # @else
00082   # @brief Destructor
00083   # 
00084   # Destructor
00085   #
00086   # @endif
00087   #
00088   def __del__(self):
00089     self._running = False
00090     try:
00091       self.join()
00092     except:
00093       pass
00094     self._thread = None
00095 
00096   def join(self):
00097     try:
00098       self._thread.join()
00099       self._thread = threading.Thread(target=self.run)
00100     except:
00101       pass
00102 
00103     return
00104 
00105   ##
00106   # @if jp
00107   # @brief Timer 用のスレッド実行関数
00108   #
00109   # Timer 用のスレッド実行関数。
00110   # 登録されたリスナーのコールバック関数を呼び出す。
00111   #
00112   # @return 実行結果
00113   #
00114   # @else
00115   # @brief Thread execution function for Timer
00116   #
00117   # Thread execution function for Timer.
00118   # Invoke the callback function of registered listener.
00119   #
00120   # @return Execution result
00121   #
00122   # @endif
00123   def run(self):
00124     while self._running:
00125       self.invoke()
00126       if self._interval.tv_sec != 0:
00127         time.sleep(self._interval.tv_sec)
00128       elif self._interval.tv_usec:
00129         time.sleep(self._interval.tv_usec/1000000.0)
00130     return 0
00131 
00132 
00133   ##
00134   # @if jp
00135   # @brief Timer タスク開始
00136   #
00137   # Timer 用新規スレッドを生成し、処理を開始する。
00138   #
00139   # @param self
00140   #
00141   # @brief Start Timer task
00142   #
00143   # Create a new theread for Timer and start processing.
00144   #
00145   # @else
00146   #
00147   # @endif
00148   def start(self):
00149     guard = OpenRTM_aist.ScopedLock(self._runningMutex)
00150     if not self._running:
00151       self._running = True
00152       self._thread.start()
00153     return
00154 
00155 
00156   ##
00157   # @if jp
00158   # @brief Timer タスク停止
00159   #
00160   # @param self
00161   #
00162   # Timer タスクを停止する。
00163   #
00164   # @else
00165   #
00166   # @brief Stop Timer task
00167   #
00168   # Stop Timer task.
00169   #
00170   # @endif
00171   def stop(self):
00172     guard = OpenRTM_aist.ScopedLock(self._runningMutex)
00173     if self._running:
00174       self._running = False
00175       self.join()
00176     return
00177 
00178 
00179   ##
00180   # @if jp
00181   # @brief Timer タスク実行
00182   #
00183   # @param self
00184   #
00185   # 登録された各リスナの起動待ち時間からタイマ起動周期を減算する。
00186   # 起動待ち時間がゼロとなったリスナが存在する場合は、
00187   # コールバック関数を呼び出す。
00188   #
00189   # @else
00190   #
00191   # @brief Invoke Timer task
00192   #
00193   # Subtract the interval of timer from the waiting time for invocation
00194   # of each registered listener.
00195   # If the listener whose waiting time reached 0 exists, invoke the
00196   # callback function.
00197   #
00198   # @endif
00199   def invoke(self):
00200     guard = OpenRTM_aist.ScopedLock(self._taskMutex)
00201     for i in range(len(self._tasks)):
00202       self._tasks[i].remains = self._tasks[i].remains - self._interval
00203       if self._tasks[i].remains.sign() <= 0.0:
00204         self._tasks[i].remains = self._tasks[i].period
00205         self._tasks[i].listener.invoke()
00206     del guard
00207     return
00208 
00209   ##
00210   # @if jp
00211   # @brief リスナー登録
00212   #
00213   # 本 Timer から起動するコールバック関数用のリスナーを起動周期を指定して
00214   # 登録する。
00215   # 同一リスナーが既に登録済みの場合は、リスナーの起動周期を指定した値に
00216   # 更新する。
00217   #
00218   # @param self
00219   # @param listener 登録対象リスナー
00220   # @param tm リスナー起動周期
00221   #
00222   # @return 登録リスナー
00223   #
00224   # @else
00225   #
00226   # @brief Register listener
00227   #
00228   # Register the listener of callback function invoked from this Timer by
00229   # specifying the interval.
00230   # If the same listener has already been regiseterd, the value specified
00231   # the invocation interval of listener will be updated.
00232   # 
00233   #
00234   # @param listener Listener for the registration
00235   # @param tm The invocation interval of listener
00236   #
00237   # @return ID of the registerd listener
00238   #
00239   # @endif
00240   # ListenerId registerListener(ListenerBase* listener, TimeValue tm);
00241   def registerListener(self, listener, tm):
00242     guard = OpenRTM_aist.ScopedLock(self._taskMutex)
00243     for i in range(len(self._tasks)):
00244       if self._tasks[i].listener == listener:
00245         self._tasks[i].period = tm
00246         self._tasks[i].remains = tm
00247         return listener
00248     self._tasks.append(self.Task(listener, tm))
00249     return listener
00250 
00251 
00252   ##
00253   # @if jp
00254   # @brief リスナー登録
00255   #
00256   # コールバック対象オブジェクト、コールバック対象メソッドおよび起動周期を
00257   # 指定してリスナーを登録する。
00258   #
00259   # @param self
00260   # @param obj コールバック対象オブジェクト
00261   # @param cbf コールバック対象メソッド
00262   # @param tm リスナー起動周期
00263   #
00264   # @return 登録リスナー
00265   #
00266   # @else
00267   #
00268   # @brief Register listener
00269   #
00270   # Register listener by specifying the object for callback, the method
00271   # for callback and the invocation interval.
00272   #
00273   # @param obj Target object for callback
00274   # @param cbf Target method for callback
00275   # @param tm The invocation interval of listener
00276   #
00277   # @return ID of the registerd listener
00278   #
00279   #
00280   # @endif
00281   #  template <class ListenerClass>
00282   #  ListenerId registerListenerObj(ListenerClass* obj,
00283   #                                 void (ListenerClass::*cbf)(),
00284   #                                 TimeValue tm)
00285   def registerListenerObj(self, obj, cbf, tm):
00286     return self.registerListener(OpenRTM_aist.ListenerObject(obj, cbf), tm)
00287 
00288 
00289   ##
00290   # @if jp
00291   # @brief リスナー登録
00292   #
00293   # コールバック対象メソッドと起動周期を指定してリスナーを登録する。
00294   #
00295   # @param self
00296   # @param cbf コールバック対象メソッド
00297   # @param tm リスナー起動周期
00298   #
00299   # @return 登録リスナー
00300   #
00301   # @else
00302   #
00303   # @brief Register listener
00304   #
00305   # Register listener by specifying the method for callback and the
00306   # invocation interval.
00307   #
00308   # @param cbf Target method for callback
00309   # @param tm The invocation interval of listener
00310   #
00311   # @return ID of the registerd listener
00312   #
00313   # @endif
00314   # ListenerId registerListenerFunc(void (*cbf)(), TimeValue tm)
00315   def registerListenerFunc(self, cbf, tm):
00316     return self.registerListener(OpenRTM_aist.ListenerFunc(cbf), tm)
00317 
00318 
00319   ##
00320   # @if jp
00321   # @brief リスナー登録解除
00322   #
00323   # 指定したIDのリスナーの登録を解除する。
00324   # 指定したIDのリスナーが未登録の場合、false を返す。
00325   #
00326   # @param self
00327   # @param id 登録解除対象リスナーID
00328   #
00329   # @return 登録解除結果
00330   #
00331   # @else
00332   #
00333   # @brief Unregister listener
00334   #
00335   # Unregister the listener specified by ID.
00336   # If the listener specified by ID is not registerd, false will be returned.
00337   #
00338   # @param id ID of the unregisterd listener
00339   #
00340   # @return Unregistration result
00341   #
00342   # @endif
00343   # bool unregisterListener(ListenerId id);
00344   def unregisterListener(self, id):
00345     guard = OpenRTM_aist.ScopedLock(self._taskMutex)
00346     len_ = len(self._tasks)
00347     for i in range(len_):
00348       idx = (len_ - 1) - i
00349       if self._tasks[idx].listener == id:
00350         del self._tasks[idx]
00351         return True
00352     return False
00353 
00354 
00355   ##
00356   # @if jp
00357   # @class Task
00358   # @brief タスク管理用クラス
00359   # @else
00360   #
00361   # @endif
00362   class Task:
00363     def __init__(self, lb, tm):
00364       self.listener = lb
00365       self.period = tm
00366       self.remains = tm
00367       return


openrtm_aist_python
Author(s): Shinji Kurihara
autogenerated on Thu Aug 27 2015 14:17:28