Difference between revisions of "Open Prim Animator/Frame Labels"
(Committing changes made to OPA made over the past year at work) |
(documentation) |
||
Line 1: | Line 1: | ||
<lsl> | <lsl> | ||
getRecordedSnapshots(){ | //! @brief Provides an API to allow animation frames to be "labelled" so they can be called by string instead of integer. | ||
/** | |||
* @author SignpostMarv Martin | |||
*/ | |||
getRecordedSnapshots(){ // short-hand for getting the number of animation frames | |||
llMessageLinked(LINK_THIS,-1,"XDrecordedSnapshots",NULL_KEY); | llMessageLinked(LINK_THIS,-1,"XDrecordedSnapshots",NULL_KEY); | ||
} | } | ||
//! name of the notecard to load the frame labels from. Each label should be on a new line corresponding to the animation frame (first line first frame, second line second frame and so on) | |||
string notecard = "OPA-Frame-Labels"; | string notecard = "OPA-Frame-Labels"; | ||
//! notecard contents | |||
string contents; | string contents; | ||
//! notecard lines | |||
list _contents; | list _contents; | ||
//! dataserver keys for non-sequential loading of notecard lines. | |||
list multithread_fetch = []; | list multithread_fetch = []; | ||
//! dataserver key for fetching the number of notecard lines | |||
key nlq; | key nlq; | ||
//! Yet another vestigial copypasta. | |||
export_string(string _export_string){ | export_string(string _export_string){ | ||
integer s=1000; | integer s=1000; | ||
Line 21: | Line 36: | ||
} | } | ||
//! number of animation frames | |||
integer recordedSnapshots = 0; | integer recordedSnapshots = 0; | ||
//! command to change the current animation frame. | |||
key op_change_frame = "1071f377-8623-4ed3-acc1-d30cabb4524a"; | key op_change_frame = "1071f377-8623-4ed3-acc1-d30cabb4524a"; | ||
default{ | default{ | ||
state_entry(){ | state_entry(){ | ||
integer type = llGetInventoryType(notecard); | integer type = llGetInventoryType(notecard); // check the notecard is in inventory | ||
if(type == INVENTORY_NONE){ | if(type == INVENTORY_NONE){ // if type is INVENTORY_NONE it isn't there. | ||
llOwnerSay("Notecard not found"); | llOwnerSay("Notecard not found"); | ||
}else if(type != INVENTORY_NOTECARD){ | }else if(type != INVENTORY_NOTECARD){ // if type is not INVENTORY_NOTECARD, something else is hogging the name. | ||
llOwnerSay("Inventory item found with name of notecard, but it is not a notecard"); | llOwnerSay("Inventory item found with name of notecard, but it is not a notecard"); | ||
}else{ | }else{ // notecard found, proceeding with parsing process | ||
state num_lines; | state num_lines; | ||
} | } | ||
} | } | ||
changed(integer c){ | changed(integer c){ // rather than resetting the script, we jump straight to the num_lines state if the notecard is now found. | ||
if(c & CHANGED_INVENTORY && llGetInventoryType(notecard) == INVENTORY_NOTECARD){ | if(c & CHANGED_INVENTORY && llGetInventoryType(notecard) == INVENTORY_NOTECARD){ | ||
state num_lines; | state num_lines; | ||
Line 42: | Line 60: | ||
} | } | ||
// state_exit(){ | |||
// llOwnerSay("Notecard found, parsing"); | // llOwnerSay("Notecard found, parsing"); | ||
// } | |||
} | } | ||
state num_lines{ | state num_lines{ // we're using separate states to avoid race conditions with changed inventory etc. | ||
state_entry(){ | state_entry(){ | ||
nlq = llGetNumberOfNotecardLines(notecard); | nlq = llGetNumberOfNotecardLines(notecard); // fire off a request for the notecard lines | ||
} | } | ||
Line 75: | Line 93: | ||
} | } | ||
state mtf{ | state mtf{ // fetch all notecard lines without the delay caused by traditional sequential loading. | ||
state_entry(){ | state_entry(){ | ||
integer i; | integer i; | ||
Line 109: | Line 127: | ||
link_message(integer s, integer n, string m, key i){ | link_message(integer s, integer n, string m, key i){ | ||
if(m == "XDrecordedSnapshots" && n >= 0){ | if(m == "XDrecordedSnapshots" && n >= 0){ // if we're updating the number of animation frames | ||
recordedSnapshots = n; | recordedSnapshots = n; | ||
if(recordedSnapshots == 1){ | if(recordedSnapshots == 1){ // and there's only one frame | ||
llMessageLinked(LINK_THIS,0,"XDplay",NULL_KEY); | llMessageLinked(LINK_THIS,0,"XDplay",NULL_KEY); // play it. | ||
} | } | ||
}else if(i == op_change_frame){ | }else if(i == op_change_frame){ // if we receive a command to change to an animation frame by a named label, | ||
integer frame = llListFindList(_contents,[m]); | integer frame = llListFindList(_contents,[m]); // check the label exists in the notecard contents | ||
if(frame >= 0){ | if(frame >= 0){ // then if the named label does exist, | ||
llMessageLinked(LINK_THIS,frame + 1,"XDshow",NULL_KEY); | llMessageLinked(LINK_THIS,frame + 1,"XDshow",NULL_KEY); // show it. | ||
} | } | ||
} | } |
Revision as of 05:40, 14 December 2011
<lsl> //! @brief Provides an API to allow animation frames to be "labelled" so they can be called by string instead of integer. /**
- @author SignpostMarv Martin
- /
getRecordedSnapshots(){ // short-hand for getting the number of animation frames
llMessageLinked(LINK_THIS,-1,"XDrecordedSnapshots",NULL_KEY);
}
//! name of the notecard to load the frame labels from. Each label should be on a new line corresponding to the animation frame (first line first frame, second line second frame and so on) string notecard = "OPA-Frame-Labels";
//! notecard contents string contents;
//! notecard lines list _contents;
//! dataserver keys for non-sequential loading of notecard lines. list multithread_fetch = [];
//! dataserver key for fetching the number of notecard lines key nlq;
//! Yet another vestigial copypasta. export_string(string _export_string){
integer s=1000; while(llStringLength(_export_string) > s){ llOwnerSay(llGetSubString(_export_string,0,(s-1))); _export_string = llGetSubString(_export_string,s,-1); } if(llStringLength(_export_string) > 0){ llOwnerSay(_export_string); }
}
//! number of animation frames integer recordedSnapshots = 0;
//! command to change the current animation frame. key op_change_frame = "1071f377-8623-4ed3-acc1-d30cabb4524a";
default{
state_entry(){ integer type = llGetInventoryType(notecard); // check the notecard is in inventory if(type == INVENTORY_NONE){ // if type is INVENTORY_NONE it isn't there. llOwnerSay("Notecard not found"); }else if(type != INVENTORY_NOTECARD){ // if type is not INVENTORY_NOTECARD, something else is hogging the name. llOwnerSay("Inventory item found with name of notecard, but it is not a notecard"); }else{ // notecard found, proceeding with parsing process state num_lines; } }
changed(integer c){ // rather than resetting the script, we jump straight to the num_lines state if the notecard is now found. if(c & CHANGED_INVENTORY && llGetInventoryType(notecard) == INVENTORY_NOTECARD){ state num_lines; } }
// state_exit(){ // llOwnerSay("Notecard found, parsing"); // } }
state num_lines{ // we're using separate states to avoid race conditions with changed inventory etc.
state_entry(){ nlq = llGetNumberOfNotecardLines(notecard); // fire off a request for the notecard lines }
dataserver(key q, string m){ if(q == nlq){ integer i; integer j = (integer)m; if(j < 1){ contents = ""; state done_reading; } list k = []; // declaring list k = []; isn't exactly necessary, you could do list k; list l = []; for(i=0;i<j;++i){ // since we don't have the concept of transactions in LSL scripts, we're going to build up these lists separately k += [NULL_KEY]; l += [NULL_KEY]; } _contents = k; // this is where we do the atomic writes due to lack of transactions on variables multithread_fetch = l; // this is where we do the atomic writes due to lack of transactions on variables k = []; // cleaning up the local variable on purpose in case the LSL VM executing this script is inefficient l = []; // cleaning up the local variable on purpose in case the LSL VM executing this script is inefficient state mtf; } }
}
state mtf{ // fetch all notecard lines without the delay caused by traditional sequential loading.
state_entry(){ integer i; integer j=llGetListLength(multithread_fetch); for(i=0;i<j;++i){ multithread_fetch = llListReplaceList(multithread_fetch,[llGetNotecardLine(notecard,i)],i,i); // sets the notecard fetching away } }
dataserver(key q, string m){ integer i = llListFindList(multithread_fetch,[q]); if(i >= 0){ _contents = llListReplaceList(_contents,[m],i,i); // the traditional method of notecard fetching in LSL is single-threaded, getting one line at a time } if(llListFindList(_contents,[NULL_KEY]) == -1){ // since we started out with a NULLL_KEY-filled list, if there aren't any NUL_KEY in the list then we know it's done. caveat scriptor: since key and string types are interchangeable contents = llDumpList2String(_contents,"\n"); state done_reading; } }
state_exit(){ _contents = []; multithread_fetch = []; }
}
state done_reading{
state_entry(){ _contents = llParseString2List(contents, ["\n"],[]);
// llOwnerSay((string)llGetListLength(_contents) + " frame labels found");
getRecordedSnapshots(); }
link_message(integer s, integer n, string m, key i){ if(m == "XDrecordedSnapshots" && n >= 0){ // if we're updating the number of animation frames recordedSnapshots = n; if(recordedSnapshots == 1){ // and there's only one frame llMessageLinked(LINK_THIS,0,"XDplay",NULL_KEY); // play it. } }else if(i == op_change_frame){ // if we receive a command to change to an animation frame by a named label, integer frame = llListFindList(_contents,[m]); // check the label exists in the notecard contents if(frame >= 0){ // then if the named label does exist, llMessageLinked(LINK_THIS,frame + 1,"XDshow",NULL_KEY); // show it. } } }
changed(integer c){ if(c & CHANGED_INVENTORY){ llResetScript(); } }
} </lsl>