<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>natewm.com &#187; tutorial</title>
	<atom:link href="http://natewm.com/blog/tag/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://natewm.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 25 Aug 2010 14:56:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Python Message Queues and Publishers</title>
		<link>http://natewm.com/blog/2010/03/05/python-message-queues/</link>
		<comments>http://natewm.com/blog/2010/03/05/python-message-queues/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 01:37:37 +0000</pubDate>
		<dc:creator>Nate</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[message]]></category>
		<category><![CDATA[publisher]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[queue]]></category>
		<category><![CDATA[subscriber]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://natewm.com/blog/?p=127</guid>
		<description><![CDATA[PyWeek is approaching, so I&#8217;ve decided that I will post some cut-and-paste code to hopefully make the process of game development quicker and easier.  Usually I end up needing to rewrite basically the same code over and over again and spend most of the first two days of any competition just implementing basic features. This [...]]]></description>
			<content:encoded><![CDATA[<p>PyWeek is approaching, so I&#8217;ve decided that I will post some cut-and-paste code to hopefully make the process of game development quicker and easier.  Usually I end up needing to rewrite basically the same code over and over again and spend most of the first two days of any competition just implementing basic features.</p>
<p>This first article will feature message queue and publisher classes.  They are quite simple, yet certainly useful.</p>
<h3>Message Queue</h3>
<p>The message queue class is very short and simple.</p>
<pre class="brush:python">class MsgQueue:
    def __init__(self):
        self.messages = []

    def post(self, msg, category, *args):
        self.messages.append((msg, category, args))

    def get(self):
        for msg in self.messages:
            yield msg
        self.messages = []</pre>
<p>Messages can be posted to it and retrieved from it through the &#8216;post&#8217; and &#8216;get&#8217; functions.  The messages that are posted are tuples of message, category, and arguments.  The categories can be used to group messages of similar types together.  For example, in a game there might be a category called &#8216;switches,&#8217; where a message is posted each time a switch in the level is turned on or off.</p>
<p>The &#8216;get&#8217; function is a generator for iterating through the messages then clearing the list of messages.</p>
<pre class="brush:python">#Example Use for MsgQueue
q = MsgQueue()
q.post("red switch on", "switches")
q.post("red switch off", "switches", "with an extra argument")

# elsewhere in a sea of code ...

for msg,category,args in q.get():
    if category == "switches":
        if msg == "red switch on":
            fire_laser_beams("Pew! Pew!")
        elif msg == "red switch off":
            stop_firing_those_lasers()</pre>
<h3>Publisher With Message Queues Subscribers</h3>
<p>Message queues can subscribe to message categories within this message publisher class.</p>
<pre class="brush:python">class MsgPublisher:
    def __init__(self):
        self.categories = {}

    def subscribe(self, subscriber, category='default'):
        if not self.categories.has_key(category):
            self.categories[category] = []

        self.categories[category].append(subscriber)

    def unsubscribe(self, subscriber, category = None):
        if category is None:
            for c in self.categories.itervalues():
                c.remove(subscriber)

        else:
            if self.categories.has_key(category):
                self.categories[category].remove(subscriber)

    def post(self, msg, category='default', *args):
        if self.categories.has_key(category):
            for subscription in self.categories[category]:
                subscription.post(msg, category, *args)</pre>
<p>The method &#8216;subscribe&#8217; is used to subscribe a message queue to a publisher.  Categories are used to group subscriptions so that a single publisher can serve several uses.  A subscribing message queue will need to subscribe to each of these categories separately.  If category is blank &#8216;default&#8217; will be used.</p>
<p>The method &#8216;unsubscribe&#8217; removes a subscribed message queue from it&#8217;s subscription list(s).  If category is &#8216;None&#8217; (default) it will be unsubscribed from all of the categories.</p>
<p>The method &#8216;post&#8217; is used for posting messages to the subscribed message queues.  Each message will be sent to all of the message queues that have subscribed to the specified category.</p>
<pre class="brush:python">#Example use of MsgPublisher
qa = MsgQueue()
qb = MsgQueue()
qc = MsgQueue()

p = MsgPublisher()
p.subscribe(qa)
p.subscribe(qb)
p.subscribe(qb, "new category")
p.subscribe(qc, "new category")

p.post("message")  # sent to qa and qb
p.post("something else", "new category")  # sent to qb and qc

p.unsubscribe(qa)
p.unsubscribe(qb, "new category")  # qb will be removed from "new category"
p.unsubscribe(qb)  # now qb removed from all categories
p.unsubscribe(qc)  # will be removed from all categories</pre>
<h3>Opportunities for Use</h3>
<p>There are many times when speed and direct interaction are not needed but flexibility is.  In a game objects can simply plug in and listen to the messages being sent &#8212; creating an easy and modular system.  Also it is more like asking for things to happen than telling other parts of your program to do things.  These messages can be ignored.</p>
<p>Some instances where message queues and publishers might be useful include: game state changes, abstraction to other systems such as sound, world dynamics, communications between game entities, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://natewm.com/blog/2010/03/05/python-message-queues/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
