Haiku API Bindings
Looper
Not logged in

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)

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()

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)

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)

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)

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)

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

The default port capacity; currently 200.

SCRIPTING SUITE

The name of Looper's scripting suite is suite/vnd.Be-looper.

Looper also inherits the following suites: