Package horizons :: Module extscheduler
[hide private]
[frames] | no frames]

Source Code for Module horizons.extscheduler

  1  # ################################################### 
  2  # Copyright (C) 2008-2017 The Unknown Horizons Team 
  3  # team@unknown-horizons.org 
  4  # This file is part of Unknown Horizons. 
  5  # 
  6  # Unknown Horizons is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the 
 18  # Free Software Foundation, Inc., 
 19  # 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 20  # ################################################### 
 21   
 22  import heapq 
 23  import time 
 24   
 25  from horizons.util.python.singleton import ManualConstructionSingleton 
 26   
 27   
28 -class _ExtCallbackObject:
29 """Class used by the ExtScheduler Class to organize callbacks.""" 30
31 - def __init__(self, callback, class_instance, run_in=1, loops=1):
32 """Creates the CallbackObject instance. 33 @param callback: lambda function callback, which is called run_in ticks. 34 @param class_instance: class instance the original function(not the lambda function!) belongs to. 35 @param run_in: int number of ticks after which the callback is called. Standard is 1, run next tick. 36 @param loops: How often the callback is called. -1 = infinite times. Standard is 1, run once. 37 """ 38 self.callback = callback 39 self.class_instance = class_instance 40 self.run_in = run_in 41 self.loops = loops
42
43 - def __str__(self):
44 return "ExtSchedCb(%s on %s)" % (self.callback, self.class_instance)
45
46 - def __lt__(self, other):
47 # make sure that there is always some ordering 48 if self.run_in < other.run_in: 49 return True 50 return id(self) < id(other)
51 52
53 -class ExtScheduler(object, metaclass=ManualConstructionSingleton):
54 """The ExtScheduler is used for time based events that are not part of the simulation(gui, menu, scrolling). 55 To start a timed callback, call add_new_object() to make the TimingThread Class create a CallbackObject for you. 56 @param pump: pump list the scheduler registers itself with. 57 """ 58 59 NOOP = _ExtCallbackObject(lambda: 42 * 1337 - 3.14, None) 60
61 - def __init__(self, pump):
62 super().__init__() 63 self.schedule = [] 64 self.pump = pump 65 self.pump.append(self.tick)
66
67 - def tick(self):
68 """Threads main loop 69 @param tick_id: int id of the tick. 70 """ 71 while self.schedule: 72 elem = self.schedule[0] # heap, first elem is smallest 73 if elem[0] <= time.time(): 74 dont_use = heapq.heappop(self.schedule) 75 assert dont_use is elem 76 obj = elem[1] 77 obj.callback() 78 if obj.loops > 0 or obj.loops is -1: 79 self.add_object(obj) # re-add object 80 else: 81 break
82
83 - def add_object(self, obj):
84 """Adds a new CallbackObject instance to the callbacks list 85 @param object: CallbackObject type object, containing all necessary information 86 """ 87 if obj.loops > 0: 88 obj.loops -= 1 89 # sort by first entry, which is execution time 90 heapq.heappush(self.schedule, [(time.time() + obj.run_in), obj])
91
92 - def add_new_object(self, callback, class_instance, run_in=1, loops=1):
93 """Creates a new CallbackObject instance and calls the self.add_object() function. 94 @param callback: function callback, which is called run_in time. 95 @param class_instance: class instance the function belongs to. 96 @param run_in: float number of seconds after which the callback is called. Standard is 1, run next second. 97 @param loops: How often the callback is called. -1 = infinite times. Standard is 1, run once.""" 98 obj = _ExtCallbackObject(callback, class_instance, run_in, loops) 99 self.add_object(obj)
100
101 - def rem_all_classinst_calls(self, class_instance):
102 """Removes all callbacks from the scheduler that belong to the class instance class_inst. 103 @return: number of removed callbacks""" 104 for tup in self.schedule: 105 if tup[1].class_instance is class_instance: 106 # don't destroy heap 107 tup[1] = self.__class__.NOOP
108
109 - def rem_call(self, instance, callback):
110 """Removes all callbacks of 'instance' that are 'callback' 111 @param instance: the instance that would execute the call 112 @param callback: the function to remove 113 """ 114 for tup in self.schedule: 115 if tup[1].class_instance is instance and tup[1].callback == callback: 116 # don't destroy heap 117 tup[1] = self.__class__.NOOP
118
119 - def __del__(self):
120 self.schedule = [] 121 self.pump.remove(self.tick) 122 self.pump = None
123