On Mon, Nov 29, 2010 at 12:24 AM, Paul Solt <[email protected]> wrote:
> Is there an easy way to use a background worker thread for the complex
> calculations in cocos2d/pyglet? I would ideally like to do work off
the GUI thread, but I am not sure on how to do it.
> I have an issue with frames missing in animations if I perform complex
> calculations before triggering an animation. I'm currently running
> this code on Mac OS X 10.6.5. Here's the basic structure of the
> offending code.
>
> 1. Do complex calculation (~1 second to run)
> 2. Animate result
>
> I'm expecting the calculation to finish before invoking the animation,
> but that's not the case.
I'm sure the calculation finish before the animation starts, python is not a
parallel language.
> It appears that the animation starts soon
> after the complex calculation starts.
I think you see stuttering when the animation begins, and then you deduce
the complex calculation has not ended
> After performing a complex
calculation the animation that follows will be missing frames of
animation. It may skip or stutter before resuming normal animation
speed.
>
The stuttering can be produced by some aftereffects of the heavy
calculations.
I can think of two ways:
1. The complex calculation don't let pyglet get control for a long time.
Pyglet tries to schedule itself to satisfy the desired framerate and
schedule_interval requests, and tries to reduce the differences between
desired calling times and real calling times. Probably the adaptive parts in
pyglet.clock and pyglet.app get confused by the long time it was blocked and
multiple messages waiting in the application queue, needing some frames
after the calculation ends to stabilize.
The basic solution would be to not block pyglet so much time.
2. Garbage collection. Less likely, but possible. If your complex
calculation allocates lot of memory or a big number of objects, which are
unreferenced after the calc terminates, a slow garbage collection can kick
in.
>
> Here's an example:
> Key press = animation
> Mouse press = calculation + animation
>
> import sys
> import os
> sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
> from time import time
> import cocos
>
> class HelloWorld(cocos.layer.Layer):
> is_event_handler = True
>
> def on_key_press (self, key, modifiers):
> """This function is called when a key is pressed.
> 'key' is a constant indicating which key was pressed.
> 'modifiers' is a bitwise or of several constants indicating
> which
> modifiers are active at the time of the press (ctrl,
> shift, capslock, etc.)
> """
> print "Key pressed:", key
>
> #animate
> self.label.do(cocos.actions.FadeIn(1) +
> cocos.actions.RotateBy(360,1) +
> cocos.actions.ScaleBy(2, 2) +
> cocos.actions.ScaleBy(1/2.0, 1))
>
>
> def calc(self):
> print "Long Calc"
> start = time()
> for i in range(4000000):
> j = i * 13743
> end = time()
> print "Total Calc Time", (end - start)
>
> def on_mouse_press (self, x, y, buttons, modifiers):
> """This function is called when any mouse button is pressed
>
> (x, y) are the physical coordinates of the mouse
> 'buttons' is a bitwise or of pyglet.window.mouse constants
> LEFT, MIDDLE, RIGHT
> 'modifiers' is a bitwise or of pyglet.window.key modifier
> constants
> (values like 'SHIFT', 'OPTION', 'ALT')
> """
> posX, posY = cocos.director.director.get_virtual_coordinates
> (x, y)
> print "Mouse Pressed: ", posX, ",", posY
>
> # Do complex calculation that takes ~1 second to complete
> self.calc()
>
> #animate
> self.label.do(cocos.actions.FadeIn(1) +
> cocos.actions.RotateBy(360,1) +
> cocos.actions.ScaleBy(2, 2) +
> cocos.actions.ScaleBy(1/2.0, 1))
>
> def __init__(self):
> super( HelloWorld, self ).__init__()
>
> # a cocos.text.Label is a wrapper of pyglet.text.Label
> # with the benefit of being a cocosnode
> self.label = cocos.text.Label('Hello, World!',
> font_name='Times New Roman',
> font_size=32,
> anchor_x='center', anchor_y='center')
>
> self.label.position = 320,240
> self.add( self.label )
>
> if __name__ == "__main__":
> # director init takes the same arguments as pyglet.window
> cocos.director.director.init()
> hello_layer = HelloWorld ()
> main_scene = cocos.scene.Scene (hello_layer)
> cocos.director.director.run (main_scene)
>
Clicking the mouse I see
1. a time without changes
2. followed by a smooth animation.
windows xp here, running cocos trunk r1065, pyglet 1.1.4
I remember some older pyglet having problems with time.
--
claudio
--
You received this message because you are subscribed to the Google Groups
"cocos2d discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/cocos-discuss?hl=en.