(A note on security: Boodler has none. If your computer is connected to
the Internet, any machine on the Internet can send events to Boodler.
As a precaution, therefore, Boodler does not listen for events
unless you use the --listen
option.
If you want to use sound events, but want to exclude the outside world
from sending them, you should use some kind of firewall hardware or software.
Boodler uses port 31863; a firewall that blocks that port will block
Boodler events.)
(Another option is to give the --port
option and specify
an absolute pathname instead of a port number. This causes Boodler to
listen on a Unix domain socket, instead of an Internet network socket.
Unix domain sockets only work within a single machine, not between
different machines, and you can use standard Unix file protections to
limit access to the socket.)
To listen for events, you create a special type of agent. This agent sits on a channel and waits, but it is not scheduled for a particular time. Instead, it listens for a particular type of event. When an event of that type arrives, the agent runs immediately. (Well, actually there's a small delay.)
A listening agent, unlike a normal agent, does not shut down after it runs once. It continues listening, and runs once every time an appropriate event is received.
More than one agent can be posted to listen for a particular type of event. When that event arrives, all the agents run simultaneously. Also, a particular agent can be posted to listen for several types of events.
class Example(EventAgent): name = 'listening example' watch_events = 'go' def receive(self, event): self.sched_note('environ/droplet-plink.aiff')The agent is a member of
EventAgent
, which is a subclass
of Agent
which has been specialized for event-listening.
Note that there is no run()
method; instead, there
is a receive()
method, which takes an extra argument for
the event.
The class also has an extra attribute:
watch_events
. This must contain the type of event to watch
for.
You can now type:
python boodler.py --listen bootest.ExampleBoodler will start up, but you will hear nothing. (Don't forget the
--listen
argument, or else you'll see
an "event listening disabled" error.)
When an EventAgent
starts up, it posts itself to listen
for its watch_events
. In other words, the
EventAgent
class has a default run()
implementation
which looks like this:
def run(self): self.post_agent(self)This is usually what you want -- when the agent is scheduled (either from the command line, or by another agent) it should begin waiting for events. (You can, of course, override the
run()
if you want the agent to do something more complicated.)
At any rate, our agent is still waiting patiently.
To send an event, use the boomsg.py
program:
python boomsg.py goThis sends a simple message
('go')
to a listening Boodler
process -- by default, on the same machine. To send a message to a
different machine, you would say:
python boomsg.py --hostname machine.addr.net goYou can also use the
--port
argument to specify a network
port number, or (if the --port
value is an absolute pathname)
a Unix domain socket. Note that --hostname
is ignored for
Unix domain sockets.
class Example(EventAgent): name = 'listening example' watch_events = 'play' def receive(self, event): snd = event[1] self.sched_note(snd)This listener listens for a
'play'
event. The agent
then extracts the name of a sound from the second element of the tuple,
and plays the sound. So you could type:
python boomsg.py play environ/droplet-plink.aiff...or name any other sound in the library. You can also check
event
to discriminate between types
of events, if your agent watches for more than one type.
class Example(EventAgent): name = 'listening example' watch_events = ['droplet', 'heartbeat'] def receive(self, event): if (event[0] == 'droplet'): self.sched_note('environ/droplet-plink.aiff') if (event[0] == 'heartbeat'): self.sched_note('environ/heartbeat.aiff')In this example,
watch_events
is a list of strings, rather
than a single string. (It could also be a function which returns a
string, or a list of strings.) The agent accepts both 'droplet'
and 'heartbeat'
events, and plays each as a different sound.
boomsg.py
to send events.
The protocol is simply a direct TCP/IP connection to port 31863.
(telnet
will work fine.)
Each (nonempty) line sent is an event.
The line is broken up into strings at space characters;
the resulting tuple becomes the event.
You can keep the connection open, and send many messages in a row, if you want. Unix, Mac, or DOS linebreaks will all work.