comparison src/parpg/grease/impl/world.py @ 27:09b581087d68

Added base files for grease
author KarstenBock@gmx.net
date Tue, 12 Jul 2011 10:16:48 +0200
parents
children
comparison
equal deleted inserted replaced
26:5529dd5644b8 27:09b581087d68
1 #############################################################################
2 #
3 # Copyright (c) 2010 by Casey Duncan and contributors
4 # All Rights Reserved.
5 #
6 # This software is subject to the provisions of the MIT License
7 # A copy of the license should accompany this distribution.
8 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
11 #
12 #############################################################################
13 """Worlds are environments described by a configuration of components, systems and
14 renderers. These parts describe the data, behavioral and presentation aspects
15 of the world respectively.
16
17 The world environment is the context within which entities exist. A typical
18 application consists of one or more worlds containing entities that evolve
19 over time and react to internal and external interaction.
20
21 See :ref:`an example of world configuration in the tutorial <tut-world-example>`.
22 """
23
24 __version__ = '$Id$'
25
26 import itertools
27 import pyglet
28 from pyglet import gl
29 from grease.world import *
30 from grease.impl import Mode
31
32 class World(Mode, BaseWorld):
33 """A coordinated collection of components, systems and entities
34
35 A world is also a mode that may be pushed onto a
36 :class:`grease.mode.Manager`
37
38 :param step_rate: The rate of :meth:`step()` calls per second.
39
40 :param master_clock: The :class:`pyglet.clock.Clock` interface used
41 as the master clock that ticks the world's clock. This
42 defaults to the main pyglet clock.
43 """
44
45 clock = None
46 """:class:`pyglet.clock` interface for use by constituents
47 of the world for scheduling
48 """
49
50 time = None
51 """Current clock time of the world, starts at 0 when the world
52 is instantiated
53 """
54
55 running = True
56 """Flag to indicate that the world clock is running, advancing time
57 and stepping the world. Set running to False to pause the world.
58 """
59
60 def __init__(self, step_rate=60, master_clock=pyglet.clock,
61 clock_factory=pyglet.clock.Clock):
62 Mode.__init__(self, step_rate, master_clock, clock_factory)
63 BaseWorld.__init__(self)
64
65 def activate(self, manager):
66 """Activate the world/mode for the given manager, if the world is already active,
67 do nothing. This method is typically not used directly, it is called
68 automatically by the mode manager when the world becomes active.
69
70 The systems of the world are pushed onto `manager.event_dispatcher`
71 so they can receive system events.
72
73 :param manager: :class:`mode.BaseManager` instance
74 """
75 if not self.active:
76 for system in self.systems:
77 manager.event_dispatcher.push_handlers(system)
78 super(World, self).activate(manager)
79
80 def deactivate(self, manager):
81 """Deactivate the world/mode, if the world is not active, do nothing.
82 This method is typically not used directly, it is called
83 automatically by the mode manager when the world becomes active.
84
85 Removes the system handlers from the `manager.event_dispatcher`
86
87 :param manager: :class:`mode.BaseManager` instance
88 """
89 for system in self.systems:
90 manager.event_dispatcher.remove_handlers(system)
91 super(World, self).deactivate(manager)
92
93 def tick(self, dt):
94 """Tick the mode's clock, but only if the world is currently running
95
96 :param dt: The time delta since the last tick
97 :type dt: float
98 """
99 if self.running:
100 super(World, self).tick(dt)
101
102 def step(self, dt):
103 """Execute a time step for the world. Updates the world `time`
104 and invokes the world's systems.
105
106 Note that the specified time delta will be pinned to 10x the
107 configured step rate. For example if the step rate is 60,
108 then dt will be pinned at a maximum of 0.1666. This avoids
109 pathological behavior when the time between steps goes
110 much longer than expected.
111
112 :param dt: The time delta since the last time step
113 :type dt: float
114 """
115 dt = min(dt, 10.0 / self.step_rate)
116 for component in self.components:
117 if hasattr(component, "step"):
118 component.step(dt)
119 for system in self.systems:
120 if hasattr(system, "step"):
121 system.step(dt)
122
123 def on_draw(self, gl=pyglet.gl):
124 """Clear the current OpenGL context, reset the model/view matrix and
125 invoke the `draw()` methods of the renderers in order
126 """
127 gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
128 gl.glLoadIdentity()
129 BaseWorld.draw_renderers(self)