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