Stackless and Twisted Threaded Example

Copyright (C) 2007 David Wyand
www.gnometech.com



1. About

This application runs Stackless as a separate Twisted thread to demonstrate their coexistence and communication. The Stackless code creates a number of AI space ships that fly around a 2D zone chasing after a target. Each ship has its own flight characteristics. The Twisted code provides a web back end to the simulation. Launch the simulation with:

python main.py

When the application is first started a PYGame window is opened displaying the space ships and the target crosshairs. Each ship is drawn as a red circle with the shade of red indicating the ship's relative maximum speed. An orange line coming from the center of the circle represents the ship's heading.

At the top of the window are the 'seconds per frame' statistics as calculated using a sliding time window. If the PYGame window is closed the simulation will continue to run but without spending time on drawing the display.

The Twisted side of the application provides another view into the simulation in the form of a web page. To access the page locally use:

http://127.0.0.1:8001

The top of the page has three buttons. The 'Quit' button will shutdown the simulation and the PYGame window if it is open. The 'Open Display' button will open the PYGame window if it was closed. The last button allows the user to toggle between a list of ships and a list of tasklets.

The first web page displays the position of the target and each ship at the time the page was loaded. Each ship's simulation ID and name is also provided.

The second web page provides a list of all Stackless tasklets as obtained from the garbage collector. It lists who created the tasklet, what context the tasklet was created under, the tasklet's class, and some additional information that is available from Stackless. The 'main' tasklet is shaded in gray while the current tasklet is shaded in yellow.

Tested with PYGame, Stackless and Twisted for Python 2.4


2. File Descriptions

Below is a list of all included Python files and a functional description for each.

2.1 main.py

The simulation begins here. The communication channels between Stackless and Twisted are set up here as is the Stackless thread. The web page structure and server is then set up and the Twisted reactor is run.

2.2 webpages.py

Builds the two web pages for Twisted based on AI space ship and Tasklet information obtained over the Stakless communication channels.

2.3 comm.py

Helper functions to communicate from Twisted to the Stackless thread.

2.4 stacklessthread.py

Builds the Zone in which the AI space ships fly, and the PYGame window. The game loop is here that continuously steps through all active tasklets. This is based on the CCP derived uthread.Run() method.

2.5 tasklet.py

Defines the Tasklet class that is derived from stackless.tasklet and some helper functions based on the CCP derived uthread.py. This version provides a context string and a reference to the parent game object that is used for the Twisted web page.

2.6 zone.py

Defines the Zone or area in which the AI space ships fly and builds the AI ships themselves. It is also the communications hub for Twisted and the web pages by providing an AI ship list and tasklet list. These lists are safely passed between threads.

2.7 objectdb.py

A database for all game simulation objects, such as the AI space ships. It provides a globally unique identifier for each registered object and allows for object lookup by ID, name or index.

2.8 objectbase.py

The ObjectBase class is the lowest level game simulation object and may be registered with the object database. It defines a message handling system based on Stackless channels.

2.9 movingobject.py

Built upon the ObjectBase class, the MovingObject class adds 2D position and motion. It also provides a default update handler Tasklet to allow the game object to move over time. Demonstrates uthread.BeNice() usage. The object's initial position, maximum speed and maximum force are set randomly to provide some variety.

2.10 target.py

Based on the MovingObject class, the Target class provides all AI space ships a target to travel towards. Its update handler chooses a new position on a randomly timed basis using uthread.Sleep().

2.11 aiobject.py

Based on the MovingObject class, the AIObject class adds a thinking handler Tasklet and steering behavior. The thinking handler Tasklet determines the steering goal on a periodic basis using uthread.Sleep(). The goal is just the position of the Target at the given moment. The steering behavior is a fairly standard seek with imposed steering force and velocity limitations.

2.12 display.py

Based on the ObjectBase class, the Display class sets up the PYGame display to draw the space ships and their Target. A seconds per frame HUD is also provided. Each ship is drawn as a red circle with a line indicating its current heading. The circle's colour intensity is determined by the object's maximum speed. The Target is drawn as a small plus symbol (+).

The advantage of basing the display on ObjectBase is the use of the inherited messaging system to open and close the window. The PYGame window may be closed and the game simulation will continue to run. The window may be opened again using the Open Display button on the web page.

2.13 vector.py

Utility functions to work with 2D vectors as lists

2.14 uthread.py

The Python Microthread Library, version 1.0 as found on the Stackless web site.

2.15 stacklesstwisted2.wpr

Wing IDE project file.


3. Screen Shots


Figure 3.1: PYGame window with AI space ships seeking the target.


Figure 3.2: Web page listing the target and AI space ships' positions.


Figure 3.3: Web page listing all Tasklets and their parent game simulation objects. Tasklets without a parent belong to the Python thread.