~jtaylor/ubuntu/oneiric/soya/fix-780305

« back to all changes in this revision

Viewing changes to idler.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Dequènes (Duck)
  • Date: 2005-01-30 09:55:06 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050130095506-f21p6v6cgaobhn5j
Tags: 0.9.2-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
 
"""soya.idler
19
 
 
20
 
This module provide a main loop for Soya, with FPS regulation. It is a simplified
21
 
version of the Py2Play idler ; if you want to use Py2Play in addition to Soya,
22
 
you should rather use the Py2Play idler.
23
 
 
24
 
The following global module attributes are noticeable:
25
 
 
26
 
 - ROUND_DURATION: The duration of a round. Round is the idler's time unit. The idler calls
27
 
   successively begin_round(), advance_time() (possibly several times) and end_round(); it
28
 
   is granted that ALL rounds correspond to a period of duration ROUND_DURATION (though
29
 
   the different period may not be regularly spread over time).
30
 
   Default is 0.030.
31
 
 
32
 
 - MIN_FRAME_DURATION: minimum duration for a frame. This attribute can be used to limit
33
 
   the maximum FPS to save CPU time; e.g. FPS higher than 30-40 is usually useless.
34
 
   Default is 0.025, which limits FPS to 40 in theory and to about 33 in practice
35
 
   (I don't know why there is a difference between theory and practice !).
36
 
 
37
 
 - IDLER: a reference to the last created idler."""
38
 
 
39
 
import time
40
 
import soya
41
 
 
42
 
ROUND_DURATION     = 0.030
43
 
MIN_FRAME_DURATION = 0.020
44
 
 
45
 
IDLER = None
 
18
import warnings
 
19
warnings.warn("The content of this module is now in the soya module.", DeprecationWarning)
 
20
 
 
21
from soya import Idler
 
22
 
46
23
STOPPED = 0
47
24
PLAYING = 1
48
25
 
49
 
class Idler:
50
 
  """Idler
51
 
 
52
 
A main loop with FPS regulation.
53
 
 
54
 
Interesting attributes:
55
 
 
56
 
 - next_round_tasks: a list of callable (taking no arg) that will be called once, just
57
 
   after the beginning of the next round.
58
 
 
59
 
 - scene: the scene associated to this idler."""
60
 
  
61
 
  def __init__(self, scene = None):
62
 
    """Idler(scene) -> Idler
63
 
 
64
 
Creates a new idler for scene SCENE."""
65
 
    self.next_round_tasks = []
66
 
    self.fps   = 0.0
67
 
    self.state = STOPPED
68
 
    self.scene = scene
69
 
    
70
 
    global IDLER
71
 
    IDLER = self
72
 
    
73
 
  def start(self):
74
 
    """Idler.start()
75
 
 
76
 
Starts idling with a new thread."""
77
 
    import thread
78
 
    thread.start_new_thread(self.idle, ())
79
 
    
80
 
  def stop (self):
81
 
    """Idler.stop()
82
 
 
83
 
Stops idling. The stopping may not occur immediately, but at the end of the next iteration."""
84
 
    self.state = STOPPED
85
 
    
86
 
  def idle(self):
87
 
    """Idler.idle()
88
 
 
89
 
Starts idling with the current thread. This method doesn't finish, until you call Idler.stop()."""
90
 
    self.state = PLAYING
91
 
    self.time = last_fps_computation_time = time.time()
92
 
    self.time_since_last_round = 0.0
93
 
 
94
 
    self.begin_round()
95
 
    
96
 
    nb_frame = 0
97
 
    while self.state >= PLAYING:
98
 
      nb_frame = 0
99
 
      while (self.state >= PLAYING) and (nb_frame < 80):
100
 
        nb_frame = nb_frame + 1
101
 
        
102
 
        while 1: # Sleep until at least MIN_FRAME_DURATION second has passed since the last frame
103
 
          current = time.time()
104
 
          delta = current - self.time
105
 
          
106
 
          if delta > MIN_FRAME_DURATION: break
107
 
          time.sleep(MIN_FRAME_DURATION - delta)
108
 
          
109
 
        self.time = current
110
 
        
111
 
        while self.time_since_last_round + delta > ROUND_DURATION: # Start a new frame
112
 
          spent_time = ROUND_DURATION - self.time_since_last_round
113
 
          
114
 
          self.advance_time(spent_time / ROUND_DURATION) # Complete the previous round
115
 
          self.end_round()                               # Ends the previous round
116
 
          
117
 
          self.begin_round()                             # Prepare the following round
118
 
          
119
 
          if self.next_round_tasks:
120
 
            for task in self.next_round_tasks: task()
121
 
            self.next_round_tasks = []
122
 
            
123
 
          delta = delta - spent_time
124
 
          self.time_since_last_round = 0
125
 
          
126
 
        self.advance_time(delta / ROUND_DURATION) # start the current round
127
 
        self.time_since_last_round = self.time_since_last_round + delta
128
 
        
129
 
        self.render()
130
 
        
131
 
      current = time.time()
132
 
      self.fps = nb_frame / (current - last_fps_computation_time)
133
 
      last_fps_computation_time = current
134
 
      
135
 
  def begin_round(self):
136
 
    """Idler.begin_round()
137
 
 
138
 
Called by Idler.idle when a new round begins; default implementation delegates to Idler.scene.begin_round."""
139
 
    if self.scene: self.scene.begin_round()
140
 
    
141
 
  def end_round(self):
142
 
    """Idler.end_round()
143
 
 
144
 
Called by Idler.idle when a round is finished; default implementation delegates to Idler.scene.end_round."""
145
 
    if self.scene: self.scene.end_round()
146
 
    
147
 
  def advance_time(self, proportion):
148
 
    """Idler.advance_time()
149
 
 
150
 
Called by Idler.idle when a piece of a round has occured; default implementation delegates to Idler.scene.advance_time.
151
 
PROPORTION is the proportion of the current round's time that has passed (1.0 for an entire round)."""
152
 
    if self.scene:
153
 
      soya.advance_time(proportion) # for C coded stuff
154
 
      self.scene.advance_time(proportion)
155
 
    
156
 
  def render(self):
157
 
    """Idler.render()
158
 
 
159
 
Called by Idler.idle when rendering is needed; default implementation calls soya.render."""
160
 
    soya.render()
161
 
    
162