Prev
Up
Next
devguide-25.html
User Interface
devguide.html
Developer's Guide
devguide-27.html
File Format
Message Passing
In a Model-View-Controller architecture like the one used in Skencil,
the model has to inform the views when the data has changed and the
views have to be updated. Often there can be several views for one model
object and it is desirable to implement the model in such a way that it
doesn't have to know how many and what types of view there actually are
at any one point in time. Still, the views have to be informed by the
model that they should update themselves whenever the model changes. In
Skencil this is achieved through a generic message passing mechanism
similar to the signals used in Qt or GTK.
Concepts
Messages
are generated by
publishers
and consist of a
message type
represented by a string and an arbitrary number of
arguments. The message type is also called a
channel
.
Program parts that want to receive messages subscribe to a channel of a
particular publisher by passing a callable object, often a bound
instance method, and optionally some additional arguments to the
publisher.
When the publisher issues a message all subscribers of the relevat
channel of the publisher all called with the message arguments and the
additional subscriber specific arguments.
The heart of this mechanism is the
#N4
Connector
class,
whose instances manage all connections between publishers and
subscribers. This way, a publisher that has no subscribers does not use
any resources.
The connector module has one global
Connector
instance and some
of its methods are available as globals.
There are two additional classes for publisher objects.
#N11
Publisher
provides methods to subscribe to and unsubscribe from
channels of the object.
#N18
QueueingPublisher
allows the
publisher to accumulate messages in a queue with identical messages
queued only once and release them all at once.
Most objects that send messages are derived from one of these publisher
objects and in most circumstances their methods are used to connect to
their channels. The connector is rarely used directly.
The Class
Connector
Connect(
publisher
,
channel
,
subscriber
,
args
)
Connect the
subscriber
, i.e. a callable object and
additional arguments
args
, to a
channel
of a
publisher
.
The
publisher
can be any object, though most of the time
it's a
#N11
Publisher
instance. Skencil uses the
None
object as a publisher for global messages.
args
are subscriber specific arguments as a tuple.
The same subscriber may be registered multiple times but it is
only stored once in the list of subscribers. Two subscribers are
considered equal if the callable object and the arguments are
equal.
Disconnect(
publisher
,
channel
,
subscriber
,
args
)
Disconnect
subscriber
from
publisher
's
channel
.
The arguments have the same meaning as in
#N5
Connect
and again the combination of
subscriber
and
args
is used to identify one particular subscriber.
If the subscriber isn't connected to the channel, raise a
ConnectorError
exception.
Issue(
publisher
,
channel
, *
args
)
Issue a message on a
channel
of
publisher
.
The third and all following arguments are passed through to all
subscribers as message arguments. The arguments the subscribers
are called with is the concatenation of the message arguments
and the subscriber specific arguments.
RemovePublisher(
publisher
)
Remove all subscribers from all channels of
publisher
. It
is safe to call this in a __del__ method.
HasSubscribers(
publisher
)
Return true iff
publisher
has any subscribers.
Note that the connector does not hold references to the publisher.
Publishers are identified by their id. This makes it possible to
automatically disconnect all subscribers of a publisher in a publisher's
__del__ method. This does not work however, if e.g. the publisher is
itself a subscriber because the connector has to own the references to
the subcribers.
The Class
Publisher
The class
Publisher
serves as a base class for classes that send
messages. It provides convenience methods to subscribe to and
unsubscribe from channels. It also removes all subscriptions
automatically when instances are deleted through the
__del__
method.
Subscribe(
channel
,
subscriber
, *
args
)
Subscribe
subscriber
to self's
channel
with the rest
of the positional arguments as the subscriber specific
parameters. See
#N5
Connect
for more details.
Unsubscribe(
channel
,
subscriber
, *
args
)
Unsubscribe
subscriber
to self's
channel
with the
rest of the positional arguments as the subscriber specific
parameters. See
#N6
Disconnect
for more details.
issue(
channel
, *
args
)
If the instance variable
ignore_issue
is false, issue the
message described by the second and the following arguments on
channel
channel
, otherwise, do nothing.
ignore_issue
defaults to false.
ignore_issue
will be
removed in 0.8.
Destroy()
Remove all subscribers of all of self's channels. See
#N8
RemovePublisher
for more details.
__del__()
Remove all subscribers of all of self's channels. See
#N8
RemovePublisher
for more details.
The Class
QueueingPublisher
Sometimes it's useful to put messages in a queue and issue them all in
one go after a complex operation is finished. The class
QueueingPublisher
provides such a queue and the following
methods:
queue_message(
channel
, *
args
)
Put message for channel
channel
in the queue. The rest of the
arguments are treated just as in
#N14
issue
If the messge is already queued remove it and put it at the end.
This is done to make certain that no channel gets called twice
between two calls to flush_message_queue. If the order of channel
invocation is important two or more queues should be used.
Note, that this can be very inefficient if a lot of different
messages are queued before the queue is flushed because each new
message is compared with all messages in the queue sequentiually. A
dictionary could speed this up considerably if the order in which
the messages are issued isn't important and if the messages can be
used as dictionary keys. Especially the latter is not always the
case, so this isn't done by defalt.
flush_message_queue()
Issue all queued messages until the queue is empty. The process is
repeated because issueing messages might result in new messages
being queued. This can theoretically result in an infinite loop.
clear_message_queue()
Discard all queued messages.
devguide-25.html
User Interface
devguide.html
Developer's Guide
devguide-27.html
File Format
Prev
Up
Next
