Timer.py

説明を見る。
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
00022 
00023 
00024 ##
00025 # @if jp
00026 # @class ScopedLock
00027 # @brief ScopedLock クラス
00028 #
00029 # 排他処理用ロッククラス。
00030 #
00031 # @since 0.4.0
00032 #
00033 # @else
00034 #
00035 # @endif
00036 class ScopedLock:
00037   def __init__(self, mutex):
00038     self.mutex = mutex
00039     self.mutex.acquire()
00040 
00041   def __del__(self):
00042     self.mutex.release()
00043 
00044 
00045 
00046 ##
00047 # @if jp
00048 # @class Timer
00049 # @brief Timerクラス
00050 # 
00051 # 登録されたリスナーのコールバック関数を、設定された周期で定期的に呼び出す。
00052 #
00053 # @since 0.4.0
00054 #
00055 # @else
00056 #
00057 # @endif
00058 class Timer:
00059   """
00060   """
00061 
00062 
00063 
00064   ##
00065   # @if jp
00066   # @brief コンストラクタ
00067   # 
00068   # コンストラクタ
00069   #
00070   # @param self
00071   # @param interval タイマ起動周期
00072   #
00073   # @else
00074   #
00075   # @endif
00076   def __init__(self, interval):
00077     self._interval = interval
00078     self._running  = False
00079     self._runningMutex = threading.RLock()
00080     self._tasks = []
00081     self._taskMutex = threading.RLock()
00082     self._thread = threading.Thread(target=self.run)
00083 
00084 
00085   ##
00086   # @if jp
00087   # @brief Timer タスク実行
00088   #
00089   # Timer 用新規スレッドから定期的に登録されたリスナーのメソッドを呼び出す。
00090   #
00091   # @param self
00092   #
00093   # @else
00094   #
00095   # @endif
00096   def run(self):
00097     while self._running:
00098       if self._interval.tv_sec != 0:
00099         time.sleep(self._interval.tv_sec)
00100       time.sleep(self._interval.tv_usec/1000000.0)
00101       self.invoke()
00102     return 0
00103 
00104 
00105   ##
00106   # @if jp
00107   # @brief Timer タスク開始
00108   #
00109   # Timer 用新規スレッドを生成し、処理を開始する。
00110   #
00111   # @param self
00112   #
00113   # @else
00114   #
00115   # @endif
00116   def start(self):
00117     guard = ScopedLock(self._runningMutex)
00118     if not self._running:
00119       self._running = True
00120       self._thread.start()
00121 
00122 
00123   ##
00124   # @if jp
00125   # @brief Timer タスク停止
00126   #
00127   # @param self
00128   #
00129   # Timer タスクを停止する。
00130   #
00131   # @else
00132   #
00133   # @endif
00134   def stop(self):
00135     guard = ScopedLock(self._runningMutex)
00136     self._running = False
00137 
00138 
00139   ##
00140   # @if jp
00141   # @brief Timer タスク実行
00142   #
00143   # @param self
00144   #
00145   # 登録された各リスナの起動待ち時間からタイマ起動周期を減算する。
00146   # 起動待ち時間がゼロとなったリスナが存在する場合は、
00147   # コールバック関数を呼び出す。
00148   #
00149   # @else
00150   #
00151   # @endif
00152   def invoke(self):
00153     for i in range(len(self._tasks)):
00154       self._tasks[i].remains = self._tasks[i].remains - self._interval
00155       if self._tasks[i].remains.sign <= 0:
00156         self._tasks[i].listener.invoke()
00157         self._tasks[i].remains = self._tasks[i].period
00158 
00159 
00160   ##
00161   # @if jp
00162   # @brief リスナー登録
00163   #
00164   # 本 Timer から起動するコールバック関数用のリスナーを起動周期を指定して
00165   # 登録する。
00166   # 同一リスナーが既に登録済みの場合は、リスナーの起動周期を指定した値に
00167   # 更新する。
00168   #
00169   # @param self
00170   # @param listener 登録対象リスナー
00171   # @param tm リスナー起動周期
00172   #
00173   # @return 登録リスナー
00174   #
00175   # @else
00176   #
00177   # @endif
00178   def registerListener(self, listener, tm):
00179     guard = ScopedLock(self._taskMutex)
00180     for i in range(len(self._tasks)):
00181       if self._tasks[i].listener == listener:
00182         self._tasks[i].period = tm
00183         self._tasks[i].remains = tm
00184         return listener
00185     self._tasks.append(self.Task(listener, tm))
00186     return listener
00187 
00188 
00189   ##
00190   # @if jp
00191   # @brief リスナー登録
00192   #
00193   # コールバック対象オブジェクト、コールバック対象メソッドおよび起動周期を
00194   # 指定してリスナーを登録する。
00195   #
00196   # @param self
00197   # @param obj コールバック対象オブジェクト
00198   # @param cbf コールバック対象メソッド
00199   # @param tm リスナー起動周期
00200   #
00201   # @return 登録リスナー
00202   #
00203   # @else
00204   #
00205   # @endif
00206   def registerListenerObj(self, obj, cbf, tm):
00207     return self.registerListener(OpenRTM.ListenerObject(obj, cbf), tm)
00208 
00209 
00210   ##
00211   # @if jp
00212   # @brief リスナー登録
00213   #
00214   # コールバック対象メソッドと起動周期を指定してリスナーを登録する。
00215   #
00216   # @param self
00217   # @param cbf コールバック対象メソッド
00218   # @param tm リスナー起動周期
00219   #
00220   # @return 登録リスナー
00221   #
00222   # @else
00223   #
00224   # @endif
00225   def registerListenerFunc(self, cbf, tm):
00226     return self.registerListener(OpenRTM.ListenerFunc(cbf), tm)
00227 
00228 
00229   ##
00230   # @if jp
00231   # @brief リスナー登録解除
00232   #
00233   # 指定したIDのリスナーの登録を解除する。
00234   # 指定したIDのリスナーが未登録の場合、false を返す。
00235   #
00236   # @param self
00237   # @param id 登録解除対象リスナーID
00238   #
00239   # @return 登録解除結果
00240   #
00241   # @else
00242   #
00243   # @endif
00244   def unregisterListener(self, id):
00245     guard = ScopedLock(self._taskMutex)
00246     len_ = len(self._tasks)
00247     for i in range(len_):
00248       idx = (len_ - 1) - i
00249       if self._tasks[idx].listener == id:
00250         del self._tasks[idx]
00251         return True
00252     return False
00253 
00254 
00255   ##
00256   # @if jp
00257   # @class Task
00258   # @brief タスク管理用クラス
00259   # @else
00260   #
00261   # @endif
00262   class Task:
00263     def __init__(self, lb, tm):
00264       self.listener = lb
00265       self.period = tm
00266       self.remains = tm

OpenRTMに対してMon Mar 17 15:11:06 2008に生成されました。  doxygen 1.5.4