Mercurial > parpg-source
comparison bGrease/impl/mode.py @ 65:e856b604b650
Changed "import bGrease" to "import parpg.bGrease".
author | KarstenBock@gmx.net |
---|---|
date | Wed, 21 Sep 2011 16:10:14 +0200 |
parents | ff3e395abf91 |
children |
comparison
equal
deleted
inserted
replaced
64:b73050f98411 | 65:e856b604b650 |
---|---|
34 | 34 |
35 __version__ = '$Id$' | 35 __version__ = '$Id$' |
36 | 36 |
37 import abc | 37 import abc |
38 import pyglet | 38 import pyglet |
39 from bGrease.mode import * | 39 from parpg.bGrease.mode import * |
40 | 40 |
41 class PygletManager(BaseManager): | 41 class PygletManager(BaseManager): |
42 """Mode manager abstract base class using pyglet. | 42 """Mode manager abstract base class using pyglet. |
43 | 43 |
44 The mode manager keeps a stack of modes where a single mode | 44 The mode manager keeps a stack of modes where a single mode |
45 is active at one time. As modes are pushed on and popped from | 45 is active at one time. As modes are pushed on and popped from |
46 the stack, the mode at the top is always active. The current | 46 the stack, the mode at the top is always active. The current |
47 active mode receives events from the manager's event dispatcher. | 47 active mode receives events from the manager's event dispatcher. |
48 """ | 48 """ |
49 | 49 |
50 event_dispatcher = None | 50 event_dispatcher = None |
51 """:class:`pyglet.event.EventDispatcher` object that the | 51 """:class:`pyglet.event.EventDispatcher` object that the |
52 active mode receive events from. | 52 active mode receive events from. |
53 """ | 53 """ |
54 | 54 |
55 def activate_mode(self, mode): | 55 def activate_mode(self, mode): |
56 """Perform actions to activate a node | 56 """Perform actions to activate a node |
57 | 57 |
58 :param mode: The :class: 'Mode' object to activate | 58 :param mode: The :class: 'Mode' object to activate |
59 """ | 59 """ |
60 BaseManager.activate_mode(self, mode) | 60 BaseManager.activate_mode(self, mode) |
61 self.event_dispatcher.push_handlers(mode) | 61 self.event_dispatcher.push_handlers(mode) |
62 | 62 |
63 def deactivate_mode(self, mode): | 63 def deactivate_mode(self, mode): |
64 """Perform actions to deactivate a node | 64 """Perform actions to deactivate a node |
65 | 65 |
66 :param mode: The :class: 'Mode' object to deactivate | 66 :param mode: The :class: 'Mode' object to deactivate |
67 """ | 67 """ |
68 BaseManager.deactivate_mode(self, mode) | 68 BaseManager.deactivate_mode(self, mode) |
69 self.event_dispatcher.remove_handlers(mode) | 69 self.event_dispatcher.remove_handlers(mode) |
70 | 70 |
71 class Manager(PygletManager): | 71 class Manager(PygletManager): |
72 """A basic mode manager that wraps a single | 72 """A basic mode manager that wraps a single |
73 :class:`pyglet.event.EventDispatcher` object for use by its modes. | 73 :class:`pyglet.event.EventDispatcher` object for use by its modes. |
74 """ | 74 """ |
75 | 75 |
76 def __init__(self, event_dispatcher): | 76 def __init__(self, event_dispatcher): |
77 self.modes = [] | 77 self.modes = [] |
78 self.event_dispatcher = event_dispatcher | 78 self.event_dispatcher = event_dispatcher |
79 | 79 |
80 | 80 |
81 class ManagerWindow(PygletManager, pyglet.window.Window): | 81 class ManagerWindow(PygletManager, pyglet.window.Window): |
82 """An integrated mode manager and pyglet window for convenience. | 82 """An integrated mode manager and pyglet window for convenience. |
83 The window is the event dispatcher used by modes pushed to | 83 The window is the event dispatcher used by modes pushed to |
84 this manager. | 84 this manager. |
85 | 85 |
86 Constructor arguments are identical to :class:`pyglet.window.Window` | 86 Constructor arguments are identical to :class:`pyglet.window.Window` |
87 """ | 87 """ |
88 | 88 |
89 def __init__(self, *args, **kw): | 89 def __init__(self, *args, **kw): |
90 super(ManagerWindow, self).__init__(*args, **kw) | 90 super(ManagerWindow, self).__init__(*args, **kw) |
91 self.modes = [] | 91 self.modes = [] |
92 self.event_dispatcher = self | 92 self.event_dispatcher = self |
93 | 93 |
94 def on_key_press(self, symbol, modifiers): | 94 def on_key_press(self, symbol, modifiers): |
95 """Default :meth:`on_key_press handler`, pops the current mode on ``ESC``""" | 95 """Default :meth:`on_key_press handler`, pops the current mode on ``ESC``""" |
96 if symbol == pyglet.window.key.ESCAPE: | 96 if symbol == pyglet.window.key.ESCAPE: |
97 self.pop_mode() | 97 self.pop_mode() |
98 | 98 |
99 def on_last_mode_pop(self, mode): | 99 def on_last_mode_pop(self, mode): |
100 """Hook executed when the last mode is popped from the manager. | 100 """Hook executed when the last mode is popped from the manager. |
101 When the last mode is popped from a window, an :meth:`on_close` event | 101 When the last mode is popped from a window, an :meth:`on_close` event |
102 is dispatched. | 102 is dispatched. |
103 | 103 |
104 :param mode: The :class:`Mode` object just popped from the manager | 104 :param mode: The :class:`Mode` object just popped from the manager |
105 """ | 105 """ |
106 self.dispatch_event('on_close') | 106 self.dispatch_event('on_close') |
107 | 107 |
108 | 108 |
109 class Mode(BaseMode): | 109 class Mode(BaseMode): |
110 """Application mode abstract base class using pyglet | 110 """Application mode abstract base class using pyglet |
111 | 111 |
112 Subclasses must implement the :meth:`step` method | 112 Subclasses must implement the :meth:`step` method |
113 | 113 |
114 :param step_rate: The rate of :meth:`step()` calls per second. | 114 :param step_rate: The rate of :meth:`step()` calls per second. |
115 | 115 |
116 :param master_clock: The :class:`pyglet.clock.Clock` interface used | 116 :param master_clock: The :class:`pyglet.clock.Clock` interface used |
117 as the master clock that ticks the world's clock. This | 117 as the master clock that ticks the world's clock. This |
118 defaults to the main pyglet clock. | 118 defaults to the main pyglet clock. |
119 """ | 119 """ |
120 clock = None | 120 clock = None |
121 """The :class:`pyglet.clock.Clock` instance used as this mode's clock. | 121 """The :class:`pyglet.clock.Clock` instance used as this mode's clock. |
122 You should use this clock to schedule tasks for this mode, so they | 122 You should use this clock to schedule tasks for this mode, so they |
123 properly respect when the mode is active or inactive | 123 properly respect when the mode is active or inactive |
124 | 124 |
125 Example:: | 125 Example:: |
126 | 126 |
127 my_mode.clock.schedule_once(my_cool_function, 4) | 127 my_mode.clock.schedule_once(my_cool_function, 4) |
128 """ | 128 """ |
129 | 129 |
130 def __init__(self, step_rate=60, master_clock=pyglet.clock, | 130 def __init__(self, step_rate=60, master_clock=pyglet.clock, |
131 clock_factory=pyglet.clock.Clock): | 131 clock_factory=pyglet.clock.Clock): |
132 BaseMode.__init__(self) | 132 BaseMode.__init__(self) |
133 self.step_rate = step_rate | 133 self.step_rate = step_rate |
134 self.time = 0.0 | 134 self.time = 0.0 |
135 self.master_clock = master_clock | 135 self.master_clock = master_clock |
136 self.clock = clock_factory(time_function=lambda: self.time) | 136 self.clock = clock_factory(time_function=lambda: self.time) |
137 self.clock.schedule_interval(self.step, 1.0 / step_rate) | 137 self.clock.schedule_interval(self.step, 1.0 / step_rate) |
138 | 138 |
139 def on_activate(self): | 139 def on_activate(self): |
140 """Being called when the Mode is activated""" | 140 """Being called when the Mode is activated""" |
141 self.master_clock.schedule(self.tick) | 141 self.master_clock.schedule(self.tick) |
142 | 142 |
143 def on_deactivate(self): | 143 def on_deactivate(self): |
144 """Being called when the Mode is deactivated""" | 144 """Being called when the Mode is deactivated""" |
145 self.master_clock.unschedule(self.tick) | 145 self.master_clock.unschedule(self.tick) |
146 | 146 |
147 def tick(self, dt): | 147 def tick(self, dt): |
148 """Tick the mode's clock. | 148 """Tick the mode's clock. |
149 | 149 |
150 :param dt: The time delta since the last tick | 150 :param dt: The time delta since the last tick |
151 :type dt: float | 151 :type dt: float |
152 """ | 152 """ |
153 self.time += dt | 153 self.time += dt |
154 self.clock.tick(poll=False) | 154 self.clock.tick(poll=False) |
155 | 155 |
156 @abc.abstractmethod | 156 @abc.abstractmethod |
157 def step(self, dt): | 157 def step(self, dt): |
158 """Execute a timestep for this mode. Must be defined by subclasses. | 158 """Execute a timestep for this mode. Must be defined by subclasses. |
159 | 159 |
160 :param dt: The time delta since the last time step | 160 :param dt: The time delta since the last time step |
161 :type dt: float | 161 :type dt: float |
162 """ | 162 """ |
163 | 163 |
164 class Multi(BaseMulti, Mode): | 164 class Multi(BaseMulti, Mode): |
165 """A mode with multiple submodes. One submode is active at one time. | 165 """A mode with multiple submodes. One submode is active at one time. |
166 Submodes can be switched to directly or switched in sequence. If | 166 Submodes can be switched to directly or switched in sequence. If |
167 the Multi is active, then one submode is always active. | 167 the Multi is active, then one submode is always active. |
168 | 168 |
169 Multis are useful when modes can switch in an order other than | 169 Multis are useful when modes can switch in an order other than |
170 a LIFO stack, such as in "hotseat" multiplayer games, a | 170 a LIFO stack, such as in "hotseat" multiplayer games, a |
171 "wizard" style ui, or a sequence of slides. | 171 "wizard" style ui, or a sequence of slides. |
172 | 172 |
173 Note unlike a normal :class:`Mode`, a :class:`Multi` doesn't have it's own | 173 Note unlike a normal :class:`Mode`, a :class:`Multi` doesn't have it's own |
174 :attr:`clock` and :attr:`step_rate`. The active submode's are used | 174 :attr:`clock` and :attr:`step_rate`. The active submode's are used |
175 instead. | 175 instead. |
176 """ | 176 """ |
177 | 177 |
178 def __init__(self, submodes): | 178 def __init__(self, submodes): |
179 BaseMulti.__init__(self, submodes) | 179 BaseMulti.__init__(self, submodes) |
180 self.time = 0.0 | 180 self.time = 0.0 |
181 | 181 |
182 | 182 |
183 def _set_active_submode(self, submode): | 183 def _set_active_submode(self, submode): |
184 BaseMulti._set_active_submode(self, submode) | 184 BaseMulti._set_active_submode(self, submode) |
185 self.master_clock = submode.master_clock | 185 self.master_clock = submode.master_clock |
186 self.clock = submode.clock | 186 self.clock = submode.clock |
187 | 187 |
188 def clear_subnode(self): | 188 def clear_subnode(self): |
189 """Clear any subnmode data""" | 189 """Clear any subnmode data""" |
190 BaseMulti.clear_subnode(self) | 190 BaseMulti.clear_subnode(self) |
191 self.master_clock = None | 191 self.master_clock = None |
192 self.clock = None | 192 self.clock = None |
193 | 193 |
194 def tick(self, dt): | 194 def tick(self, dt): |
195 """Tick the active submode's clock. | 195 """Tick the active submode's clock. |
196 | 196 |
197 :param dt: The time delta since the last tick | 197 :param dt: The time delta since the last tick |
198 :type dt: float | 198 :type dt: float |
199 """ | 199 """ |
200 self.time += dt | 200 self.time += dt |
201 if self.active_submode is not None: | 201 if self.active_submode is not None: |
202 self.active_submode.clock.tick(poll=False) | 202 self.active_submode.clock.tick(poll=False) |
203 |