Monday, November 12, 2007

Building Games in Small Pieces - The Scheduler

I've just uploaded fibra to the cheeseshop. This is another small piece of code which I find very useful in developing simulations and games.

Fibra is the scheduler I used in ICCARUS to simulate concurrency. It uses Python generators as 'tasklets' which are iterated cooperatively. It does a job which is very similar to another library I've written, but is different in that it is very light weight, and uses a plugin system to provide extra functionality, such as sleeping, deferring execution, spawning into a real thread etc. To achieve this, it uses new Python 2.5 generator methods, so I decided to split it out of the older nanothreads module and create a new package.

Usually, I have a global scheduler available in the game, so any part of the code can defer a function call, or install a new tasklet. I usually iterate the scheduler just after I handle GUI events.

It's nothing new, its been done before, but I imagine with the right plugins, it could achieve much of what people want when they talk about concurrent Python.

This is a simple example:

import fibra
import fibra.plugins.sleep

def sleeper(x):
while True:
print x
yield x

def normal():
while True: yield None


s = fibra.Schedule()
#tell the schedule that Sleep, float and int objects should be
#handled by the SleepPlugin
s.register_plugin(fibra.plugins.sleep.SleepPlugin(), (fibra.plugins.sleep.Sleep, float, int))
#the SleepPlugin provides a new method which lets us defer
#as tasklets start for X seconds.
s.defer(4, sleeper(0.5))
#install a sleep tasks that will only iterate once ever 2 seconds
s.install(sleeper(2))
#install a normal task that will iterate on every tick
s.install(normal())
#iterate the scheduler
while True:
s.tick()

No comments:

Popular Posts