-
Notifications
You must be signed in to change notification settings - Fork 0
inline events
Sometimes using the event handler model can be inconvenient and lead to distored code. These built-in functions can lead to simpler code when dealing with such situations.
Note: Inline event handling just involves some built-in functions, therefore no xmroption statement is needed.
xmrEventCallHandler (list ev)
ev = event to be processed
ev[0] = (integer) event code (XMREVENTCODE_<eventname>, eg,
XMREVENTCODE_touch_start)
ev[1..n] = call parameters to the event, if any
- The event handler is called immediately and when that event handler completes, xmrEventCallHandler() returns to its caller. Contrast with xmrEventEnqueue() which places the event in the event queue for processing after the current event handler completes.
list xmrEventDequeue (float timeout, integer rm1, integer rm2,
integer bm1, integer bm2)
timeout = maximum number of seconds to wait
rm1,rm2 = if an event is queued that matches these mask bits, the
script is woken, that event is dequeued and returned to the
caller. the normal event handler defined in the current
state for the event is not executed.
bm1,bm2 = if an event is queued that matches these mask bits, the
script is woken, that event is dequeued and its normal event
handler for the current statis is executed. then the script
resumes waiting for what's left of the timeout or for another
event to be queued.
returns empty list: no event was queued that matched rm1,rm2 and the
timeout was reached
else: list giving parameters of the event, same format as
is passed to xmrEventCallHandler()
-
Scripts should use
XMREVENTMASKn_<eventname>symbols for the mask arguments, where n is 1 or 2 for mask1 or mask2 arguments. The list[0] return argument can be decoded by usingXMREVENTCODE_<eventname>symbols. -
If all masks are zero, the call ends up acting like llSleep.
-
If an event is enabled in both rm1,rm2 and bm1,bm2, the rm1,rm2 bit action takes precedence, ie, the event is returned. This allows a simple specification -1 for both bm1,bm2 arguments to indicate that all events not enabled to be returned by the rm1,rm2 argumetns should be handled in the background.
-
Any events not listed in either rm1,rm2 or bm1,bm2 arguments will be queued for later processing (subject to normal queue limits).
-
Background event handlers execute as calls from within XMREventDequeue, they do not execute as separate threads. Thus any background event handlers must return before the call to xmrEventDequeue will return.
-
If a background event handler changes state (eg, via 'state' statement), the state is immediately changed and the script-level xmrEventDequeue call does not return.
-
For returned events, the detect parameters are overwritten by the returned event. For background events, the detect parameters are saved and restored.
-
Scripts must contain dummy event handler definitions for any event types that may be returned by XMREventDequeue(), to let the runtime know that the script is capable of processing that event type. Otherwise, the event may not be queued to the script.
XMREVENTCODE_attach
XMREVENTCODE_state_exit
XMREVENTCODE_timer
XMREVENTCODE_touch
XMREVENTCODE_collision
XMREVENTCODE_collision_end
XMREVENTCODE_collision_start
XMREVENTCODE_control
XMREVENTCODE_dataserver
XMREVENTCODE_email
XMREVENTCODE_http_response
XMREVENTCODE_land_collision
XMREVENTCODE_land_collision_end
XMREVENTCODE_land_collision_start
XMREVENTCODE_at_target
XMREVENTCODE_listen
XMREVENTCODE_money
XMREVENTCODE_moving_end
XMREVENTCODE_moving_start
XMREVENTCODE_not_at_rot_target
XMREVENTCODE_not_at_target
XMREVENTCODE_touch_start
XMREVENTCODE_object_rez
XMREVENTCODE_remote_data
XMREVENTCODE_at_rot_target
XMREVENTCODE_run_time_permissions
XMREVENTCODE_touch_end
XMREVENTCODE_state_entry
XMREVENTCODE_changed
XMREVENTCODE_link_message
XMREVENTCODE_no_sensor
XMREVENTCODE_on_rez
XMREVENTCODE_sensor
XMREVENTCODE_http_request
XMREVENTMASK1_attach
XMREVENTMASK1_state_exit
XMREVENTMASK1_timer
XMREVENTMASK1_touch
XMREVENTMASK1_collision
XMREVENTMASK1_collision_end
XMREVENTMASK1_collision_start
XMREVENTMASK1_control
XMREVENTMASK1_dataserver
XMREVENTMASK1_email
XMREVENTMASK1_http_response
XMREVENTMASK1_land_collision
XMREVENTMASK1_land_collision_end
XMREVENTMASK1_land_collision_start
XMREVENTMASK1_at_target
XMREVENTMASK1_listen
XMREVENTMASK1_money
XMREVENTMASK1_moving_end
XMREVENTMASK1_moving_start
XMREVENTMASK1_not_at_rot_target
XMREVENTMASK1_not_at_target
XMREVENTMASK1_touch_start
XMREVENTMASK1_object_rez
XMREVENTMASK1_remote_data
XMREVENTMASK1_at_rot_target
XMREVENTMASK1_run_time_permissions
XMREVENTMASK1_touch_end
XMREVENTMASK1_state_entry
XMREVENTMASK2_changed
XMREVENTMASK2_link_message
XMREVENTMASK2_no_sensor
XMREVENTMASK2_on_rez
XMREVENTMASK2_sensor
XMREVENTMASK2_http_request
yoption advflowctl;
yoption trycatch;
default {
state_entry ()
{
/*
* Send request to a webserver.
*/
key reqid = llHTTPRequest ("http://dreamnation.net/", [], "");
/*
* Wait here up to 30 seconds for the reply.
* If any other events come in meanwhile, process them as background
* calls.
*/
while (1) {
list reply = xmrEventDequeue (30.0, XMREVENTMASK1_http_response,
0, -1, -1);
if (llGetListLength (reply) == 0) {
llOwnerSay ("timed out waiting for reply");
break;
}
integer eventcode = (integer)reply[0];
if (eventcode != XMREVENTCODE_http_response) {
// fatal error - should never happen
throw "bad event code " + eventcode;
}
key request_id = (key)reply[1];
if (request_id != reqid) {
// got reply for somthing else, ignore and look again
continue;
}
integer status = (integer)reply[2];
list metadata = (list)reply[3];
string body = (string)reply[4];
llOwnerSay ("reply body: " + body);
break;
}
}
/*
* This dummy event handler must be present so the runtime knows this script
* can handle http_response events.
*/
http_response (key request_id, integer status, list metadata, string body)
{
throw "should never get here";
}
/*
* These event handlers will get called by xmrEventDequeue if the event is
* received while waiting for the reply from the webserver.
*
* They also get called normally once the start_entry() event handler
* completes.
*/
touch_start (integer num_detected)
{
llOwnerSay ("touched!");
}
changed (integer change)
{
llOwnerSay ("changed!");
}
} yoption advflowctl;
yoption trycatch;
default {
state_entry ()
{
/*
* Tell runtime to queue all messages on channel 0 to us.
*/
llListen (0, "", NULL_KEY, "");
while (1) {
/*
* Tell xmrEventDequeue() to wait up to 5 seconds per call for one
* of the events listed in the rm1,rm2 arguments. Meanwhile, if
* any events listed in the bm1,bm2 arguments are received, process
* them via the normal event handlers.
*/
list ev = xmrEventDequeue (5.0,
XMREVENTMASK1_touch_start | XMREVENTMASK1_listen,
XMREVENTMASK2_changed,
-1, -1); // -1,-1 means everything else
if (llGetListLength (ev) == 0) {
llOwnerSay ("nothing happened in the past five seconds");
continue;
}
integer eventcode = (integer)ev[0];
switch (eventcode) {
case XMREVENTCODE_touch_start: {
integer num_detected = (integer)ev[1];
llOwnerSay ("touched " + num_detected + " time(s)");
break;
}
case XMREVENTCODE_listen: {
integer channel = (integer)ev[1];
string name = (string)ev[2];
key id = (key)ev[3];
string message = (string)ev[4];
llOwnerSay ("Heard from " + name + "(" + id + ") on " +
channel + ": " + message);
break;
}
case XMREVENTCODE_changed: {
integer change = (integer)ev[1];
llOwnerSay ("something changed: " + change);
break;
}
default: {
// fatal error - should never happen
throw "don't know why I got event " + eventcode;
}
}
}
}
/*
* These dummy handlers must be present so the runtime knows the script
* wants these events to be queued to the script. But they never get
* called because the xmrEventDequeue() has them listed in its rm1,rm2
* mask arguments.
*/
touch_start (integer num_detected)
{
throw "should never get to the regular touch_start() handler";
}
listen (integer channel, string name, key id, string message)
{
throw "should never get to the regular listen() handler";
}
changed (integer change)
{
throw "should never get to the regular changed() handler";
}
/*
* Since this event is not listed in the rm1,rm2 arguments but is listed in
* the bm1,bm2 arguments, it will be called normally in the background by
* xmrEventDequeue() whenever this event is received.
*/
collision_start (integer num_detected)
{
llOwnerSay ("collided with " + num_detected + " thing(s)");
}
}
xmrEventEnqueue (list ev)
ev = event to be enqueued, see xmrEventCallHandler()
Note:
- The event is queued to execute along with any other events that might be pending, subject to event queuing limits, and executes after the current event handler completes. Contrast with xmrEventCallHandler(), which directly calls the event handler immediately.
xmrEventLoadDets (list dp)
dp = as returned by xmrEventSaveDets()
list xmrEventSaveDets ()
returns list giving detect params for current event