def setup(self, interval, action, msgPackParams, cancelLastTimer=True): ''' 启动计时器 interval 倒计时的时间, 单位: 秒 action table_call命令下(params中)的action值 msgPackParams 传递的其他的参数数据集合dict, 可以在doTableCall中的msg中使用msg.getParam(key)来取得其中的参数 ''' if self._fttimer and cancelLastTimer: self._fttimer.cancel() self._interval = interval userId = msgPackParams.get('userId', 0) clientId = msgPackParams.get('clientId', None) assert (isinstance(userId, int)) assert (isinstance(action, (unicode, str))) if clientId != None: assert (isinstance(clientId, (unicode, str))) msg = MsgPack() msg.updateParam(msgPackParams) msg.setCmdAction('table_call', action) msg.setParam('gameId', self._table.gameId) msg.setParam('roomId', self._table.roomId) msg.setParam('tableId', self._table.tableId) msg.setParam('userId', userId) msg.setParam('clientId', clientId) self._fttimer = FTTimer(interval, self._onTimeOut, msg)
def __init__(self, argd): self.argd = argd self._alive = False if self.argd['ntimeId'] == NOTIFY_TIME_ATONCE_ID: self.startTimer = FTTimer(0, self.start) ftlog.hinfo('Notify.__init__ atonce', self.argd) else: ntime = [0, 1] if self.argd['ntimeId'] == NOTIFY_TIME_TIMER_ID: try: dtList = self.argd['ntime'].split('|') ntime = map(int, dtList[1].split(':')) except: ftlog.warn('Notify.__init__.NOTIFY_TIME_TIMER_ID error') ntime = map(int, '00:01'.split(':')) else: ntime = map(int, self.argd['ntime'].split(':')) hm = map(int, getNowTimeStr().split(':')) interval = (ntime[0] * 60 * 60 + ntime[1] * 60) - (hm[0] * 60 * 60 + hm[1] * 60) ftlog.hinfo('Notify.__init__ begin:', ntime, hm, interval, (ntime[0] * 60 * 60 + ntime[1] * 60), (hm[0] * 60 * 60 + hm[1] * 60)) if interval > 0: self.startTimer = FTTimer(interval, self.start) ftlog.hinfo('Notify.__init__ end:', interval, self.argd)
class DizhuPlayerErdayiMatch(DizhuPlayer): def __init__(self, room, userId, isAI, matchUserInfo): super(DizhuPlayerErdayiMatch, self).__init__(room, userId) self.matchUserInfo = matchUserInfo self.rank = 0 self.isAI = isAI self.waitReason = WaitReason.UNKNOWN self.ai = None self._timer = None if self.isAI: self.ai = AIPlayer(self) def startTimer(self, delay, func, *args, **kw): assert(self.isAI) self.cancelTimer() self._timer = FTTimer(delay, functools.partial(func, *args, **kw)) def cancelTimer(self): if self._timer: self._timer.cancel() self._timer = None def doActiveOutCard(self): assert(self.isAI) return self.ai.doActiveOutCard() def doPassiveOutCard(self): assert(self.isAI) return self.ai.doPassiveOutCard()
class SeatBase(object): def __init__(self, table, seatIndex, seatId): # 属于哪个桌子 self._table = table # 座位index self._seatIndex = seatIndex # seatId self._seatId = seatId # 该座位的玩家 self._player = None # 下一个座位 self._next = None # 该座位定时器 self._timer = None @property def table(self): return self._table @property def tableId(self): return self._table.tableId @property def seatId(self): return self._seatId @property def seatIndex(self): return self._seatIndex @property def state(self): return self._state @property def player(self): return self._player @property def next(self): return self._next @property def userId(self): return self._player.userId if self._player else 0 def startTimer(self, delay, func, *args, **kw): self.cancelTimer() self._timer = FTTimer(delay, functools.partial(func, *args, **kw)) def cancelTimer(self): if self._timer: self._timer.cancel() self._timer = None
def start(self): self.startTimer.cancel() if self.argd['rmTag'] == 1: ftlog.hinfo('Notify.start error because be removed', self.argd['uuid']) return self._alive = True self.endTimer = FTTimer(NOTIFY_TIMER_LIFE, self.end) ftlog.hinfo('Notify.start', NOTIFY_TIMER_LIFE, self.argd['uuid'])
def _notifyRobotSigninMatch(self, signer): if self._logger.isDebug(): self._logger.warn('TYGroupMatchRoom._notifyRobotSigninMatch', 'userId=', signer.userId, 'instId=', signer.inst) if self.roomConf.get('hasrobot'): startConf = self.match.matchConf.start if self.roomConf['robotUserMaxCount'] == -1: if startConf.isTimingType(): minsize = startConf.userMinCount else: minsize = startConf.userCount - 2 else: minsize = self.roomConf['robotUserMaxCount'] if signer.inst.signerCount >= minsize: return mo = MsgPack() mo.setCmd('robotmgr') mo.setAction('callmatch') mo.setParam('gameId', self.gameId) mo.setParam('roomId', self.bigRoomId) mo.setParam('robotCount', 4) router.sendRobotServer(mo, signer.userId) func = functools.partial(self._notifyRobotSigninMatch, signer) FTTimer(15, func)
def saveRecord(self, needUpload=True): """保存当前局的纪录 """ key = "" if needUpload == True and self.fileName: absoluteFileName = self.fileName.split("/")[-1] # 生成txt文件 fw_obj = open(absoluteFileName, 'w') fw_obj.write(json.dumps(self.msgs)) fw_obj.close() # 压缩为zip self.txt2zip(absoluteFileName, '%s.%s' % (absoluteFileName, 'zip')) # 上传zip数据 fr_obj = open('%s.%s' % (absoluteFileName, 'zip'), 'r') data = fr_obj.read() fr_obj.close() key = '%s.%s' % (self.fileName, 'zip') FTTimer(SCANRATE, self.upload, key, data, 1) # 删除文件 if os.path.exists(absoluteFileName): os.remove(absoluteFileName) if os.path.exists('%s.%s' % (absoluteFileName, 'zip')): os.remove('%s.%s' % (absoluteFileName, 'zip')) # ftlog.debug("MJCreateTableRecordMsg:saveRecord========", key, data) self.reset() return key
def doHeartBeat(self): if self._state == self.STATE_IDLE: return FTTimer(1, self.doHeartBeat) if len(self.users) == 0: return if ftlog.is_debug(): ftlog.debug("<<", self.baseLogStr(), caller=self) # ftlog.debug("|first user, enter time, now, wait_time:", self.users.keys()[0], self.users[self.users.keys()[0]], time.time(), self.wait_time) if self._state == self.STATE_LOOP: if len(self.users) >= self.n_start: self._tryStartNewTable(self.n_start) return if time.time() - self.users[self.users.keys() [0]]["enterTime"] < self.wait_time: return if len(self.users) >= self.minTriggerLen: self._tryStartNewTable(self.minTriggerLen) return if TYPlayer.isRobot(self.users.keys()[0]): return if len(self.room._roomUsers) < self.n_start: self.notifyRobot()
def enqueue(self, model): ftlog.debug('AsyncReporter.enqueue', 'model.urlType=', model.urlType, 'model.params=', model.params) self._changed = True self._dao.append(model.toJson()) if not self._timer: self._timer = FTTimer(0, self._onTimer)
def startTable(self, table): ''' 让桌子开始 ''' ftlog.info('MatchTableControllerTest.startTable matchId=', self.match.matchId, 'tableId=', table.tableId) timeout = random.randint(1, 5) FTTimer(timeout, self._winlose, table)
def _doServertHeartBeat(): ''' 每秒钟一次的心跳事件广播, 执行之后间隔一秒再次启动, 即: 这个每秒心跳是个大约值,非准确值 ''' event = EventHeartBeat() event.count = event.count + 1 globalEventBus.publishEvent(event) FTTimer(1, _doServertHeartBeat)
def sendGameWinRes(self, delay=0): mpRes = self.createMsgPackRes("table_call", 'game_win') if delay: func = functools.partial(self.sendToAllTableUser, mpRes) FTTimer(delay, func) else: self.sendToAllTableUser(mpRes)
def testSuit(self): testStartTime = 0 # seconds testStartTime += 1 for _ in xrange(1): FTTimer(testStartTime, self.testReconnect) testStartTime += 1 for _ in xrange(1): FTTimer(testStartTime, self.testQuickStart) testStartTime += 1 for _ in xrange(1): FTTimer(testStartTime, self.testQuickEnterRoom) testStartTime += 1 for _ in xrange(1): FTTimer(testStartTime, self.testQuickEnterTable)
def keepAlive(mysql_pool_map): global _keep_count, _keep_alive_seconds # ftlog.debug('MYSQL keepAlive', len(mysql_pool_map), _keep_count) _keep_count += 1 if _keep_count == 1 : if len(mysql_pool_map) > 0 : FTTimer(_keep_alive_seconds, _keepAlive, mysql_pool_map) return sqlstr = 'select %d' % (_keep_count) for dbkey in mysql_pool_map.keys() : conn = mysql_pool_map[dbkey] try: defertool.setDefaultCallback(conn.runQuery(sqlstr), __file__, ftlog.getMethodName(), sqlstr) except: ftlog.error('ERROR MYSQL of', dbkey, 'has connection error ! close !! ') FTTimer(_keep_alive_seconds, _keepAlive, mysql_pool_map)
def callLater(delay, func, *args, **keywords): ''' 用FTTimer实现的callLater ''' if ftlog.is_debug(): ftlog.debug('args', args) ftlog.debug('timedelay', delay) ftlog.debug('callable', callable(func)) func = functools.partial(func, *args, **keywords) return FTTimer(delay, func)
def saveRecord(self): """保存当前局的纪录 """ if not self.resMsgs: return data = self.compress() fname = self.getKey() + "_" + str(self.table.gamePlay.gameSeq) func = functools.partial(self.uploadTableRecord, fname, data, 1) FTTimer(UPLOAD_INTERVAL, func) self.clear()
def _onLuckyMoneyPublish(self): if self.publishTimer: self.publishTimer.cancel() self.publishTimer = None # 计算下一次发布红包的剩余秒数 seconds = self._calculateNextSeconds() if seconds >= 0: self.publishTimer = FTTimer(seconds, self._onLuckyMoneyPublish) # 获取当前所在的红包开放时间段,为None则代表当前不处于开放时间段 duration = self.openList.getCurrentDurationItem() if ftlog.is_debug(): ftlog.debug('LuckyMoneyPublisher._onLuckyMoneyPublish', 'poolId=', self.poolId, 'seconds=', seconds, 'currentDuration.start', duration and duration.start) if not duration: return # 当前时间段的期号 issueNumber = duration.getIssueNumber() # 此期红包是否已经发布(多进程情况下,争夺红包发布权,只有一个能返回True) isNotPublished = LuckyMoneyOperator.setPublisheFlagByIssueNumber( self.poolId, issueNumber) if isNotPublished: # 获取红包生成的配置 prizesConf = Tool.dictGet(self.clientConf, 'config.server.prizes', []) # 生成红包列表数据 prizeList = LuckyMoneyGenerator.generate(prizesConf) # 先清空数据库的红包池,防止上一期未抢完的红包污染 LuckyMoneyOperator.clearLuckyMoneys(self.poolId) # 将新生成的红包数据发布到数据库中红包池里 ok = LuckyMoneyOperator.publishLuckyMoneys(self.poolId, prizeList) if not ok: LuckyMoneyOperator.clearPublisheFlagByIssueNumber( self.poolId, issueNumber) FTTimer(5, self._onLuckyMoneyPublish) ftlog.info('LuckyMoneyPublisher._onLuckyMoneyPublish:publish', 'poolId=', self.poolId, 'issueNumber=', issueNumber, 'isNotPublished=', isNotPublished, 'currentDuration.start=', duration and duration.start, 'publishLuckyMoneys—ok=', ok)
def __startFinalTableLater(self): self.state = self.MTT_STATE_FINALS now = datetime.now() finalTableStartTime = now + timedelta(seconds=self.matchPlugin.timedeltaStartFinalTable) if ftlog.is_debug(): ftlog.info("__startFinalTableLater |roomId, finalTableStartTime:", self.roomId, finalTableStartTime, caller=self) self.__sendFinalTableInfo(finalTableStartTime) FTTimer(self.matchPlugin.timedeltaStartFinalTable, self.scheduler.startLoop)
def _onTimer(self): try: self._timer = None newInterval = self._target() if newInterval is not None: self._interval = newInterval except: self._logger.error() self._interval = 1 if self._state == Heartbeat.ST_START: self._timer = FTTimer(self._interval, self._onTimer)
def __initMatch(self): return # 游轮赛已下线 self.matchPlugin = gdata.games()[self.gameId].getLtsMatchPlugin() self.matchPlugin.initMatchConfs(self.gameId) serverType = gdata.serverType() if serverType == gdata.SRV_TYPE_TABLE: endTimestamp = self.matchPlugin.match_room_confs[ self.bigRoomId]["end_timestamp"] FTTimer(endTimestamp - int(time.time()) + 5, self._checkMatchEnd)
def doSomeLogic2(self): ftlog.info("MyProto do some logic in tasklet") #test redis aio ftsvr.doRedis("user01", "SET", "zx", 1) #Testing doHttp... #code, page = ftsvr.doHttp("GET", "http://www.google.com", # {'User-Agent': ['Twisted']}) #test connect timeout #code, page = ftsvr.doHttp("GET", "http://news.sina.com.cn/", # {'User-Agent': ['Twisted']}, '', 15, 0.1) #test request timeout #page = ftsvr.doHttp("GET", "http://news.sina.com.cn/sssss", # {'User-Agent': ['Twisted']}) #test 404 code, page = ftsvr.doHttp("POST", "http://127.0.0.1:8003/", {'User-Agent': ['Twisted']}, "HAHAHA") print code, page print "HTTP", code, len(page), page log_data = struct.pack("64s", "HAHAHA") ftlog.sendHttpLog("user01", "chip", log_data) #pipeline需要加锁,否则结果可能混乱,框架中已经加了lock,参见ftsvr代码 count = 1000 pipecount = 100 st = time.time() for x in xrange(count / pipecount): if x % 100 == 0: ftlog.info(x) pl = ftsvr.getRedisPipe("user01") for y in xrange(pipecount): pl.set("zx", 1) result = ftsvr.doRedisPipe(pl) if len(result) != pipecount: ftlog.debug("ERRORPIPELINE") ftlog.info("SetPerS:", count / (time.time() - st)) #test ftagent and udpquery ftlog.debug(ftcon.getConf("server"), caller=self) ftlog.debug(ftsvr.getTaskRunArg()) ftlog.debug(ftsvr.doUdpQuery("LO01", "abcdefgh")) ftlog.debug(ftagent.query("GA01", "TCPTCPSENDBYAGENT")) #test cron _tstr = time.strftime('%Y%m%d', time.localtime()) cron2 = FTCron( '{"times_in_day":{"first":"15:00","interval":5, "count":32},\ "days":{"first":"%s", "interval":"2m", "count":10}}' % (_tstr)) ftlog.debug(cron2.getTimeList(), cron2.getDaysList()) ftlog.debug("SEC=", cron2.getTodayNextLater()) #test timer tr = FTTimer(3, self.timerFunc, 1, 2, 3, aaa=111)
def testTimer(self): print "call %s" % getMethodName() def fun1(x): print "call %s" % getMethodName() print x * 10 func = functools.partial(fun1, 1) timer = FTTimer(1, func) stackless.tasklet(mainloop)() stackless.run()
def testSuit(self): ftlog.debug("=" * 30) testStartTime = 0 # seconds # testStartTime +=1 # for _ in xrange(10): # FTTimer(testStartTime, self.asyncTestQuickStartPlayerSelectTable) testStartTime += 1 for _ in xrange(10): FTTimer(testStartTime, self.asyncTestRoomQuickStart) ftlog.debug("=" * 30)
def asyncTestSuit(self): ftlog.debug("=" * 30) testStartTime = 0 # seconds # testStartTime +=1 # for _ in xrange(1): # FTTimer(testStartTime, self.asyncTest3PlayerMatch) testStartTime += 1 for _ in xrange(1): FTTimer(testStartTime, self.asyncTest3PlayerMatchWithRobot) ftlog.debug("=" * 30)
def asyncTestSuit(self): ftlog.debug("=" * 30) testStartTime = 0 # seconds # testStartTime +=1 # for _ in xrange(1): # FTTimer(testStartTime, self.asyncTestOldTable) testStartTime += 1 for _ in xrange(1): FTTimer(testStartTime, self.asyncTestDoSit) ftlog.debug("=" * 30)
def loginGame(userId, gameId, clientId, iscreate, isdayfirst): ''' 用户登录一个游戏, 游戏自己做一些其他的业务或数据处理 例如: 1. IOS大厅不发启动资金的补丁, 2. 麻将的记录首次登录时间 3. 游戏插件道具合并至大厅道具 ''' ftlog.debug('dizhu.loginGame->', userId, gameId, clientId, iscreate, isdayfirst) dizhutask._onUserLogin(gameId, userId, clientId, iscreate, isdayfirst) # if not (iscreate or hallstartchip.needSendStartChip(userId, gameId)): # hallbenefits.benefitsSystem.sendBenefits(gameId, userId, pktimestamp.getCurrentTimestamp()) if iscreate: dizhu_login_reward.sendLoginReward(gameId, userId, clientId, iscreate, isdayfirst) FTTimer(0, functools.partial(processUserBehavior, userId))
def upload(self): """ 如果上传失败,每隔2*n的时间重试一次,重试4次 """ key = stackless.getcurrent()._fttask.run_argl[0] data = stackless.getcurrent()._fttask.run_argl[1] times = stackless.getcurrent()._fttask.run_argl[2] ret, _ = majiang_conf.uploadVideo(key, data) if ret == 0: ftlog.debug("MJCreateTableRecordMsg: upload the record success!!!") if ret != 0 and times <= 16: times = times * 2 FTTimer(SCANRATE * times, self.upload, key, data, times)
def doHeartBeat(self): if self._state == self.STATE_IDLE: return FTTimer(1, self.doHeartBeat) if len(self.users) > 0: if ftlog.is_debug(): ftlog.debug("<<", self.baseLogStr(), caller=self) # ftlog.debug("|first user, enter time, now, wait_time:", self.users.keys()[0], self.users[self.users.keys()[0]], time.time(), self.wait_time) if self._state == self.STATE_LOOP: if len(self.users) >= self.n_start: self._tryStartNewTable(self.n_start)
def doMatchEnd(self): ftlog.info("<< |roomId:", self.roomId, caller=self) # TODO: 向所有人发送 todotask,提示比赛已结束 rankingKey = self.matchPlugin.rankingKey(self.bigRoomId) # 更新翅膀,发奖励 userIds = daobase.executeRankCmd('ZREVRANGE', rankingKey, 0, -1) self.matchPlugin.rewardUsers(userIds, self) # 重新计算比赛时间 self.matchPlugin.refreshMatchStartTime( self.bigRoomId, self.matchConf["openTime"].get("minutes", 60)) endTimestamp = self.matchPlugin.match_room_confs[ self.bigRoomId]["end_timestamp"] FTTimer(endTimestamp - int(time.time()) + 5, self._checkMatchEnd)
def notifyMatchStartDelayReport_(self): argl = FTTasklet.getCurrentFTTasklet().run_argl datas = argl[0] userIds = datas['userIds'] roomId = datas['roomId'] sequence = datas['sequence'] index = datas['index'] self._logger.info('PlayerNotifierDizhu.notifyMatchStartDelayReport_', 'index=', index, 'total=', len(userIds)) nindex = self.notifyMatchStartDelayReport(userIds, roomId, sequence, index) if nindex < 0: self._logger.info( 'PlayerNotifierDizhu.notifyMatchStartDelayReport_ end') else: datas['index'] = nindex FTTimer(0.1, self.notifyMatchStartDelayReport_, datas)
class RoomTimer(object): def __init__(self, room): self._fttimer = None # 计时器对象 self._interval = 0 # 倒计时时间,单位: 秒 self._room = room def _onTimeOut(self): msg = stackless.getcurrent()._fttask.run_argl[0] self._room.on_match_event(msg) def setup(self, interval, msg, cancelLastTimer=True): if self._fttimer and cancelLastTimer: self._fttimer.cancel() self._interval = interval self._fttimer = FTTimer(interval, self._onTimeOut, msg) def cancel(self): ''' 取消当前的计时器 ''' if self._fttimer : self._fttimer.cancel() self._fttimer = None self._interval = 0 def reset(self, interval): ''' 重置当前的计时器 ''' if self._fttimer: self._fttimer.reset(interval) self._interval = interval def getInterval(self): ''' 取得当前计时器的倒计时时间 ''' if self._fttimer: return self._interval else: return 0 def getTimeOut(self): ''' 取得当前计时器的剩余的倒计时时间, 若没有开始倒计时, 那么返回0 ''' if self._fttimer : self._fttimer.getTimeOut() return 0.0
def _scheduleTimer(self): if self._state == Heartbeat.ST_START: interval = 0 if self._postTaskList else self._interval self._timer = FTTimer(interval, self._onTimeout)
class Heartbeat(object): ST_IDLE = 0 ST_START = 1 ST_STOP = 2 def __init__(self, target, interval): self._target = target self._state = Heartbeat.ST_IDLE self._count = 0 self._postTaskList = [] self._timer = None self._interval = interval self._logger = Logger() self._init = False def start(self): assert (self._state == Heartbeat.ST_IDLE) self._state = Heartbeat.ST_START self._timer = FTTimer(0, self._onInit) def stop(self): if self._state != Heartbeat.ST_STOP: self._state = Heartbeat.ST_STOP if self._timer: self._timer.cancel() self._timer = None @property def count(self): return self._count def postCall(self, func, *args, **kwargs): self.postTask(functools.partial(func, *args, **kwargs)) def postTask(self, task): if self._state != Heartbeat.ST_STOP: self._postTaskList.append(task) if self._init and self._timer: self._timer.cancel() self._timer = FTTimer(0, self._onTimeout) def _onInit(self): try: self._timer = None interval = self._target.onInit() if interval: self._interval = interval self._scheduleTimer() except: self._logger.error('Heartbeat._onInit') def _onTimeout(self): try: self._timer = None self._count += 1 self._processPostTaskList() interval = self._target.onHeartbeat() if interval is not None: self._interval = interval except: self._interval = 1 self._logger.error('Heartbeat._onTimeout') self._scheduleTimer() def _scheduleTimer(self): if self._state == Heartbeat.ST_START: interval = 0 if self._postTaskList else self._interval self._timer = FTTimer(interval, self._onTimeout) def _processPostTaskList(self): taskList = self._postTaskList self._postTaskList = [] for task in taskList: try: task() except: self._logger.error('task=', task)
def start(self): assert (self._state == Heartbeat.ST_IDLE) self._state = Heartbeat.ST_START self._timer = FTTimer(0, self._onInit)
def postTask(self, task): if self._state != Heartbeat.ST_STOP: self._postTaskList.append(task) if self._init and self._timer: self._timer.cancel() self._timer = FTTimer(0, self._onTimeout)
class TYTableTimer(object): ''' 桌子使用的专用的计时器, 当计时器触发时, 触发桌子的同步方法:doTableCall ''' def __init__(self, table): self._table = table # 桌子对象 self._fttimer = None # 计时器对象 self._interval = 0 # 倒计时时间,单位: 秒 def _onTimeOut(self): ''' 计时器到时, 触发table的doTableCall方法 ''' msg = stackless.getcurrent()._fttask.run_argl[0] seatId = msg.getParam('seatId') if seatId == None: seatId = 0 userId = msg.getParam('userId') if userId == None: userId = 0 assert (isinstance(userId, int)) assert (isinstance(seatId, int)) action = msg.getParam('action') clientId = runcmd.getClientId(msg) self._table.doTableCall(msg, userId, seatId, action, clientId) def setup(self, interval, action, msgPackParams, cancelLastTimer=True): ''' 启动计时器 interval 倒计时的时间, 单位: 秒 action table_call命令下(params中)的action值 msgPackParams 传递的其他的参数数据集合dict, 可以在doTableCall中的msg中使用msg.getParam(key)来取得其中的参数 ''' if self._fttimer and cancelLastTimer: self._fttimer.cancel() self._interval = interval userId = msgPackParams.get('userId', 0) clientId = msgPackParams.get('clientId', None) assert (isinstance(userId, int)) assert (isinstance(action, (unicode, str))) if clientId != None: assert (isinstance(clientId, (unicode, str))) msg = MsgPack() msg.updateParam(msgPackParams) msg.setCmdAction('table_call', action) msg.setParam('gameId', self._table.gameId) msg.setParam('roomId', self._table.roomId) msg.setParam('tableId', self._table.tableId) msg.setParam('userId', userId) msg.setParam('clientId', clientId) self._fttimer = FTTimer(interval, self._onTimeOut, msg) def cancel(self): ''' 取消当前的计时器 ''' if self._fttimer: self._fttimer.cancel() self._fttimer = None def reset(self, interval): ''' 重置当前的计时器 ''' self._interval = interval self._fttimer.reset(interval) def getInterval(self): ''' 取得当前计时器的倒计时时间 ''' return self._interval def getTimeOut(self): ''' 取得当前计时器的剩余的倒计时时间, 若没有开始倒计时, 那么返回0 ''' if self._fttimer: time = self._fttimer.getTimeOut() if time < 0 or time > 3600: time = 0 return time return 0
def setup(self, interval, msg, cancelLastTimer=True): if self._fttimer and cancelLastTimer: self._fttimer.cancel() self._interval = interval self._fttimer = FTTimer(interval, self._onTimeOut, msg)