Documentation | ApplicationKit | Looper
SYNOPSIS
Perl
use HaikuR1::Looper qw(B_LOOPER_PORT_DEFAULT_CAPACITY); # define MyLooper subclass here my $looper = MyLooper->new($name); $looper->AddHandler($handler); $looper->Run(); $looper->PostMessage($message, $handler); # looper must be locked before quitting $looper->Unlock(); $looper->Quit();
Python
from HaikuR1.ApplicationKit import Looper, B_LOOPER_PORT_DEFAULT_CAPACITY # define MyLooper subclass here looper = MyLooper(name) looper.AddHandler(handler) looper.Run() looper.PostMessage(message, handler) # looper must be locked before quitting looper.Unlock() looper.Quit()
DESCRIPTION
Exposes the BLooper
object.
For more information on Looper, see the Be Book class description, the Be Book overview, and the Haiku Book class description.
METHODS
Constructor
Creates a Looper.
Perl
my $handler = HaikuR1::Looper->new($initial, $priority, $portCapacity);
Python
handler = Looper(initial, priority, portCapacity)
initial
Optional; can be a Message containing an archived Handler or a native string containing a name for the Looper.
priority
Optional; an integer priority at which the Looper's thread will run; defaults to
B_NORMAL_PRIORITY
. Ignored wheninitial
is a Message; the priority stored in the archive is used intead.portCapacity
An integer, the number of messages the Looper's port will hold; defaults to
B_LOOPER_PORT_DEFAULT_CAPACITY
(currently 200). Ignored wheninitial
is a Message; the capacity stored in the archive is used intead.
Note: Messages from within your own team (= process) are almost always posted directly to the Looper's MessageQueue; only messages from other teams, or replies to messages sent synchronously, or messages posted to the looper's preferred handler, are sent using the port, and unless the Looper is busy doing something else, the loop at the heart of the Looper converts raw messages from the port into Message objects and places them into the queue pretty quickly. So the default is generally sufficient and you probably don't need to worry about this parameter.
Filters
AddCommonFilter
RemoveCommonFilter
SetCommonFilterList
CommonFilterList
These methods maintain the Looper's common filters.
(Incoming Messages are passed through the common filters before the target Handler's filters.)
A MessageFilter may only belong to one object at a time. You cannot add a MessageFilter to an object it already belongs to. (Although you can remove it and then re-add it later.)
The Looper must be locked before changing the filter list. (Although you can
call CommonFilterList
without locking the Looper.)
Perl
$looper->AddCommonFilter($filter); $looper->RemoveCommonFilter($filter); $looper->SetCommonFilterList($filters); $looper->CommonFilterList();
Python
looper.AddCommonFilter(filter) looper.RemoveCommonFilter(filter) looper.SetCommonFilterList(filters) looper.CommonFilterList()
filter
The MessageFilter to add or remove.
filters
A list of MessageFilters, the new list.
Handlers
AddHandler
RemoveHandler
CountHandlers
HandlerAt
IndexOf
PreferredHandler
SetPreferredHandler
These functions do what you expect.
A Handler must belong to a Looper before a Looper can dispatch Messages to the Handler. The Looper must be locked to change or examine its list of Handlers.
RemoveHandler
returns true if the Handler was successfully removed, false
otherwise. (This includes invalid Handler objects and Handlers that do not
belong to the Looper.)
The preferred Handler is used as a target when no Handler target has been specified. Initially, it is empty, and the Looper handles such Messages itself. You can restore it to this default state by setting the empty value as the preferred Handler.
A Handler must already belong to the Looper before it can be set as the preferred Handler. Since the Handler already belongs to the Looper, the Looper does not need to be locked in order to call the preferred Handler methods.
Perl
$looper->AddHandler($handler); $looper->RemoveHandler($handler); $looper->CountHandlers(); $looper->HandlerAt($index); $looper->IndexOf($handler); $looper->PreferredHandler(); $looper->SetPreferredHandler($handler);
Python
looper.AddHandler(handler) looper.RemoveHandler(handler) looper.CountHandlers() looper.HandlerAt(index) looper.IndexOf(handler) looper.PreferredHandler() looper.SetPreferredHandler(handler)
handler
The Handler to add, remove, set as preferred, or determine an index for.
index
An integer, the index to get a Handler for.
Locking
Lock
Unlock
IsLocked
LockWithTimeout
These methods do what you expect. LockWithTimeout
signals an error if it
fails to obtain a lock.
Perl
$looper->Lock(); $looper->Unlock(); $looper->IsLocked(); $looper->LockWithTimeout($timeout);
Python
looper.Lock() looper.Unlock() looper.IsLocked() looper.LockWithTimeout(timeout)
timeout
An integer, the timeout in microseconds.
Messages
CurrentMessage
DetachCurrentMessage
MessageQueue
IsMessageWaiting
These methods do what you expect. CurrentMessage
and DetachCurrentMessage
return Message objects; MessageQueue
returns a MessageQueue object.
The Looper must be locked before calling IsMessageWaiting
.
The Be Book says that detaching a message "is useful if you want to delay the response to the message without tying up the Looper". That is, you can detach it and then repost it in order to delay the processing.
However, the Be Book also warns that "if the message sender is waiting for a synchronous reply, detaching the message and holding on to it will block the sender".
Perl
$looper->CurrentMessage(); $looper->DetachCurrentMessage(); $looper->MessageQueue(); $looper->IsMessageWaiting();
Python
looper.CurrentMessage() looper.DetachCurrentMessage() looper.MessageQueue() looper.IsMessageWaiting()
PostMessage
DispatchExternalMessage
PostMessage
places a Message at the end of the Looper's
MessageQueue, or signals an error.
DispatchExternalMessage
differs from PostMessage
in two important ways:
first, the Message is dispatched immediately without going into the queue;
second, the DispatchMessage hook runs in the caller's
thread, not in the looper's thread.
Because it is running in the caller's thread, the calling thread must Lock the Looper before calling it. It returns a boolean indicating whether sthe Message was detached during the process.
Perl
$looper->PostMessage($message, $handler, $replyTo); $looper->PostMessage($message, $looper, $replyTo); $looper->DispatchExternalMessage($message, $handler);
Python
looper.PostMessage(message, handler, replyTo) looper.PostMessage(message, looper, replyTo) looper.DispatchExternalMessage(message, handler)
message
Either a Message or an integer command, the message to post.
handler
A Handler, the target for the message; if not specified, the Looper itself will be the target; if the empty value is passed, the Looper's preferred Handler will be the target. (An actual handler must be supplied for
DispatchExternalMessage
. UnlikePostMessage
, you may not omit it or pass the empty value.)replyTo
A Handler to receive the reply; if not specified, the reply is sent to
be_app_messenger
.
Quit
Ends the Looper's message loop. The Looper must be locked before calling this function.
Perl
$looper->Quit();
Python
looper.Quit()
Run
Starts the Looper's message loop. The Looper must be locked before calling this function. Returns the thread id of the loop thread or signals an error.
This method can be called as a hook under certain circumstances. For example, if the Show method is called on the Looper subclass Window, and the Window's message loop has not been started, the system will call Window.Run as a hook.
Perl
$looper->Run();
Python
looper.Run()
Team
Returns the team id for the Looper.
Perl
$looper->Team();
Python
looper.Team()
Thread
Returns the thread id for the Looper, or signals an error (for example, if there is no thread yet because you haven't called Run).
Perl
$looper->Thread();
Python
looper.Thread()
HOOKS
DispatchMessage
Dispatches the given message to the given handler. Override this in derived classes to handle your own messages. Always pass any messages you don't handle to Looper's version.
Other than calling the inherited version from your own hook, you never need to call this method yourself. The system will call it as necessary.
Perl
$looper->DispatchMessage($message, $handler);
Python
looper.DispatchMessage(message, handler)
QuitRequested
Asks the Looper if it is ready to quit. Override this in subclasses; return false to tell the caller you're not ready to quit, true to allow quitting. Looper's version returns true.
Perl
$looper->QuitRequested();
Python
looper.QuitRequested()
CLASS METHODS
LooperForThread
Returns the Looper that is running in the given thread.
Perl
HaikuR1::Looper->LooperForThread($thread);
Python
Looper.LooperForThread(thread)
thread
An integer, the thread to get a Looper for.
DEBUGGING METHODS
The following methods are mainly used for debugging.
CountLocks
Counts the number of locks the locking thread holds on the Looper.
Perl
$looper->CountLocks();
Python
looper.CountLocks()
CountLockRequests
Counts the number of lock requests; this includes the thread currently holding the lock, plus all threads waiting to acquire the lock.
Perl
$looper->CountLockRequests();
Python
looper.CountLockRequests()
LockingThread
Returns the id of the thread that currently has the Looper locked, or signals
B_ERROR
if the Looper is not locked.
Perl
$looper->LockingThread();
Python
looper.LockingThread()
Sem
Returns the id of the semaphore that is used to lock the Looper.
Perl
$looper->Sem();
Python
looper.Sem()
ARCHIVABLE INTERFACE
Looper
inherits the methods and hooks of Archivable.
HANDLER INTERFACE
Looper
inherits the methods and hooks of Handler.
CONSTANTS
- B_LOOPER_PORT_DEFAULT_CAPACITY
The default port capacity; currently 200.
SCRIPTING SUITE
The name of Looper's scripting suite is suite/vnd.Be-looper
.
Properties
Handler
B_COUNT_PROPERTIES
gets the number of Handlers in the Looper (does not seem to be working, as of Haiku revision ...) TODO: check this out
Handlers
B_GET_PROPERTY
gets a set of Messengers targeting each of the Looper's Handlers (does not seem to be working, as of Haiku revision ...) TODO: check this out
Specifiers
Handler
B_INDEX_SPECIFIER
,B_REVERSE_INDEX_SPECIFIER
targets the Looper's
index
th Handler, either from the front or the end of the list
Looper also inherits the following suites: