Qelems

Your object’s methods may be called at interrupt level. More...

+ Collaboration diagram for Qelems:

Typedefs

typedef void * t_qelem
 A qelem.
 

Functions

void * qelem_new (void *obj, method fn)
 Create a new Qelem. More...
 
void qelem_set (void *q)
 Cause a Qelem to execute. More...
 
void qelem_unset (void *q)
 Cancel a Qelem's execution. More...
 
void qelem_free (void *x)
 Free a Qelem object created with qelem_new(). More...
 
void qelem_front (void *x)
 Cause a Qelem to execute with a higher priority. More...
 

Detailed Description

Your object’s methods may be called at interrupt level.

This happens when the user has Overdrive mode enabled and one of your methods is called, directly or indirectly, from a scheduler Clock function. This means that you cannot count on doing certain things—like drawing, asking the user what file they would like opened, or calling any Macintosh toolbox trap that allocates or purges memory—from within any method that responds to any message that could be sent directly from another Max object. The mechanism you’ll use to get around this limitation is the Qelem (queue element) structure. Qelems also allow processor-intensive tasks to be done at a lower priority than in an interrupt. As an example, drawing on the screen, especially in color, takes a long time in comparison with a task like sending MIDI data.

A Qelem works very much like a Clock. You create a new Qelem in your creation function with qelem_new and store a pointer to it in your object. Then you write a queue function, very much like the clock function (it takes the same single argument that will usually be a pointer to your object) that will be called when the Qelem has been set. You set the Qelem to run its function by calling qelem_set().

Often you’ll want to use Qelems and Clocks together. For example, suppose you want to update the display for a counter that changes 20 times a second. This can be accomplished by writing a Clock function that calls qelem_set() and then reschedules itself for 50 milliseconds later using the technique shown in the metronome example above. This scheme works even if you call qelem_set() faster than the computer can draw the counter, because if a Qelem is already set, qelem_set() will not set it again. However, when drawing the counter, you’ll display its current value, not a specific value generated in the Clock function.

Note that the Qelem-based defer mechanism discussed later in this chapter may be easier for lowering the priority of one-time events, such as opening a standard file dialog box in response to a read message.

If your Qelem routine sends messages using outlet_int() or any other of the outlet functions, it needs to use the lockout mechanism described in the Interrupt Level Considerations section.

Function Documentation

void qelem_free ( void *  x)

Free a Qelem object created with qelem_new().

Typically this will be in your object's free funtion.

Parameters
xThe Qelem to destroy.
void qelem_front ( void *  x)

Cause a Qelem to execute with a higher priority.

This function is identical to qelem_set(), except that the Qelem's function is placed at the front of the list of routines to execute in the main thread instead of the back. Be polite and only use qelem_front() only for special time-critical applications.

Parameters
xThe Qelem whose function will be executed in the main thread.
void* qelem_new ( void *  obj,
method  fn 
)

Create a new Qelem.

The created Qelem will need to be freed using qelem_free(), do not use freeobject().

Parameters
objArgument to be passed to function fun when the Qelem executes. Normally a pointer to your object.
fnFunction to execute.
Returns
A pointer to a Qelem instance. You need to store this value to pass to qelem_set().
Remarks
Any kind of drawing or calling of Macintosh Toolbox routines that allocate or purge memory should be done in a Qelem function.
void qelem_set ( void *  q)

Cause a Qelem to execute.

Parameters
qThe Qelem whose function will be executed in the main thread.
Remarks
The key behavior of qelem_set() is this: if the Qelem object has already been set, it will not be set again. (If this is not what you want, see defer().) This is useful if you want to redraw the state of some data when it changes, but not in response to changes that occur faster than can be drawn. A Qelem object is unset after its queue function has been called.
void qelem_unset ( void *  q)

Cancel a Qelem's execution.

If the Qelem's function is set to be called, qelem_unset() will stop it from being called. Otherwise, qelem_unset() does nothing.

Parameters
qThe Qelem whose execution you wish to cancel.
  Copyright © 2015, Cycling '74