Open Prim Animator/Notecard Import

From Second Life Wiki
< Open Prim Animator
Revision as of 04:59, 14 December 2011 by SignpostMarv Martin (talk | contribs) (committing notecard import script for Open Prim Animator/Import-Export)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

<lsl> string notecard = "Open Prim Animator: Import"; key _notecard; string contents; list _contents; list multithread_fetch = []; key nlq; key import = "6b78fcc8-e147-4105-99a6-ff19b4bf559d"; key export = "7c2ca168-2b64-4836-8727-8e62b78dbd44"; key op_alter_rootScale = "f9d3389e-a78c-43f8-9e35-c11adec112a5"; key op_adjust_link_order_by_names = "e907917f-e5a3-490e-aaac-4596a0dc176d";

list names; list pos; list rot; list size; vector rootScale;

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);
   }

}

default{

   state_entry(){
       if(llGetInventoryType(notecard) == INVENTORY_NOTECARD){
           _notecard = llGetInventoryKey(notecard);
           state num_lines;
       }
   }
   changed(integer c){
       if(c & CHANGED_INVENTORY){
           llResetScript();
       }
   }

}

state num_lines{

   state_entry(){
       nlq = llGetNumberOfNotecardLines(notecard);
   }
   dataserver(key q, string m){
       if(q == nlq){
           integer i;
           integer j = (integer)m;
           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{

   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,"");
           state done_reading;
       }
   }
   state_exit(){
       _contents = [];
       multithread_fetch = [];
   }

}

state done_reading{

   state_entry(){
       integer rs_pos    = llSubStringIndex(contents,"rootscale:");
       integer names_pos = llSubStringIndex(contents,"names:");
       integer pos_pos   = llSubStringIndex(contents,"pos:");
       integer rot_pos   = llSubStringIndex(contents,"rot:");
       integer size_pos  = llSubStringIndex(contents,"size:");
       rootScale  = (vector)llGetSubString(contents, rs_pos + 10, names_pos - 1);
       names      = llParseString2List(llGetSubString(contents,names_pos + 6,pos_pos - 1),["|"],[]);
       pos        = llParseString2List(llGetSubString(contents,pos_pos + 4,rot_pos - 1),["|"],[]);
       rot        = llParseString2List(llGetSubString(contents,rot_pos + 4,size_pos - 1),["|"],[]);
       size       = llParseString2List(llGetSubString(contents,size_pos + 5,-1),["|"],[]);
       contents = ""; // clearing memory up, we don't need the string in memory now.
       integer a = llGetListLength(names);
       integer b = llGetListLength(pos);
       if(b % a || llGetListLength(rot) % a || llGetListLength(size) % a){
           llOwnerSay("List Lengths do not match, possible corrupted notecard (" + llList2CSV([a,llGetListLength(pos),llGetListLength(rot),llGetListLength(size)]) + ")");
       }else{
           llMessageLinked(LINK_THIS,b,"XDimportLength",NULL_KEY);
           llOwnerSay("Do import now");
       }
   }
   changed(integer c){
       if(c & CHANGED_INVENTORY && llGetInventoryKey(notecard) != _notecard){
           llResetScript();
       }
   }
   link_message(integer s, integer n, string m, key k){
       if(m == "XDimportLength" && n == -1){
           integer i;
           integer j=llGetListLength(pos);
           integer l;
           integer namesLength=llGetListLength(names);
           for(i=0;i<j;++i){
               l = llListFindList(names, [llGetLinkName(2 + (i % namesLength))]) + (llFloor(i / namesLength) * namesLength); // this is to fix any bugs caused by link order changes
               llMessageLinked(s,i,llDumpList2String([llList2Vector(pos,l),llList2Rot(rot,l),llList2Vector(size,l)],"|"),import);
           }
           llMessageLinked(s,0,(string)rootScale, op_alter_rootScale);
           llOwnerSay("Done importing");
       }
   }
   touch_start(integer t){
       llMessageLinked(LINK_THIS,0,"XDmenu",NULL_KEY);   
   }

} </lsl> Notecard Import