Difference between revisions of "LlGetNotecardLine"

From Second Life Wiki
Jump to navigation Jump to search
m ("If the requested line is longer then" to "If the requested line is longer than")
(Fixed 1st example which was reporting incorrect number of lines. Added test for missing/unsaved notecard. Tested.)
Line 19: Line 19:
string notecardName = "name of notecard as in object's contents";
string notecardName = "name of notecard as in object's contents";


// first notecard line is line 0
// script-wise, the first notecard line is line 0, the second line is line 1, etc.
integer notecardLine;
integer notecardLine;


say(string inputString)
say(string inputString)
{
{
     llSay(PUBLIC_CHANNEL, inputString);
     llOwnerSay(inputString);
}
}


Line 31: Line 31:
     state_entry()
     state_entry()
     {
     {
        // Check the notecard exists, and has been saved
        if (llGetInventoryKey(notecardName) == NULL_KEY)
        {
            llOwnerSay( "Notecard '" + notecardName + "' missing or unwritten");
            return;
        }
         // say("reading notecard named '" + notecardName + "'.");
         // say("reading notecard named '" + notecardName + "'.");
         notecardQueryId = llGetNotecardLine(notecardName, notecardLine);
         notecardQueryId = llGetNotecardLine(notecardName, notecardLine);
Line 40: Line 46:
         {
         {
             if (data == EOF)
             if (data == EOF)
                 say("Done reading notecard, read " + (string)(notecardLine + 1) + " notecard lines.");
                 say("Done reading notecard, read " + (string) notecardLine + " notecard lines.");
             else
             else
             {
             {
                 // the first line is line 0, the second line is line 1, etc.
                 // bump line number for reporting purposes and in preparation for reading next line
                say(data);
 
                 ++notecardLine;
                 ++notecardLine;
                say( "Line: " + (string) notecardLine + " " + data);
                 notecardQueryId = llGetNotecardLine(notecardName, notecardLine);
                 notecardQueryId = llGetNotecardLine(notecardName, notecardLine);
             }
             }

Revision as of 05:11, 17 December 2012

Summary

Function: key llGetNotecardLine( string name, integer line );
0.1 Forced Delay
10.0 Energy

Requests the line line of the notecard name from the dataserver.
Returns a key that is the handle for a dataserver event response.

• string name a notecard in the inventory of the prim this script is in or a UUID of a notecard
• integer line Line number in a notecard (the index starts at zero).

line does not support negative indexes. If line is past the end of the notecard EOF is returned by the dataserver.

Caveats

  • This function causes the script to sleep for 0.1 seconds.
  • If line is out of bounds the script continues to execute without an error message.
  • If name is missing from the prim's inventory and it is not a UUID or it is not a notecard then an error is shouted on DEBUG_CHANNEL.
  • If name is a UUID then there are no new asset permissions consequences for the object.
    • The resulting object develops no new usage restrictions that might have occurred if the asset had been placed in the prims inventory.
  • If name is a new empty notecard (never saved) then an error "Couldn't find notecard ~NAME~" (~NAME~ being the value of name) will be shouted on the DEBUG_CHANNEL. This is because until a notecard is saved for the first time, it does not exist as an asset only as an inventory placeholder.
  • If notecard contains embedded inventory items (such as textures and landmarks), EOF will be returned, regardless of the line requested.
  • If the requested line is longer than 255 bytes the dataserver will return the first 255 bytes of the line.

Examples

<lsl> key notecardQueryId; string notecardName = "name of notecard as in object's contents";

// script-wise, the first notecard line is line 0, the second line is line 1, etc. integer notecardLine;

say(string inputString) {

   llOwnerSay(inputString);

}

default {

   state_entry()
   {
       // Check the notecard exists, and has been saved
       if (llGetInventoryKey(notecardName) == NULL_KEY)
       {
           llOwnerSay( "Notecard '" + notecardName + "' missing or unwritten");
           return;
       }
       // say("reading notecard named '" + notecardName + "'.");
       notecardQueryId = llGetNotecardLine(notecardName, notecardLine);
   }
   dataserver(key query_id, string data)
   {
       if (query_id == notecardQueryId)
       {
           if (data == EOF)
               say("Done reading notecard, read " + (string) notecardLine + " notecard lines.");
           else
           {
               // bump line number for reporting purposes and in preparation for reading next line
               ++notecardLine;
               say( "Line: " + (string) notecardLine + " " + data);
               notecardQueryId = llGetNotecardLine(notecardName, notecardLine);
           }
       }
   }

}

</lsl>

Useful Snippets

<lsl> ///// // Generic Multi Notecard reader by Brangus Weir // Given freely and published on wiki.secondlife.com // // This script will read three note cards and store the results into three lists. // It can be modified and extended to as many (or few) cards as you'd like to read. //

list gOneCard; // All the lines from from the first card list gTwoCard; // All the lines from from the second card list gThreeCard; // All the lines from from the third card

string gsCardOneName = "One"; //Set these to the name of the invetory item. string gsCardTwoName = "Two"; string gsCardThreeName = "Three";

//Temporary variables for processing string g_sNoteCardName; // Name of the card to be read. list g_lTempLines; // The resulting data pushed into a list integer g_iLine; // The line count for the card reader key g_kQuery; // The key of the card being read


initialize(string _action) {

   // Due to the execution order when using dataserver, this function sets the first card to 
   // be read, and the excetuion finishes when called again with the _action set to "finish".
   if (_action == "") {
       loadNoteCard(gsCardOneName);
   } else if (_action == "finish") {
       // All cards have been read into the lists... now you can do any kind of string
       // manipulations to get the data you need to set your script.
       // But here we will prove that the cards have been read with a loop
       g_lTempLines = []; // lets not forget to delete this global, or it will be dead weight.
       integer len = llGetListLength(gOneCard);  //Always evaluate this once, don't do it
                                                 //INSIDE the for loop like noob programers will.
                                                 //Reduce lag, THINK ABOUT MACHINE CYCLES!
       integer i = 0;
       for (; i< len; ++i)
           llSay(0, llList2String(gOneCard,i));
       len = llGetListLength(gTwoCard);
       for (i = 0; i< len; ++i)
           llSay(0, llList2String(gTwoCard,i));
       len = llGetListLength(gThreeCard);
       for (i = 0; i< len; ++i)
           llSay(0, llList2String(gThreeCard,i));
   }                
                             

}

loadNoteCard( string _notecard ) {

   g_lTempLines = []; //clear the temp lines
   g_sNoteCardName = _notecard;
   g_iLine = 0;
   g_kQuery = llGetNotecardLine(g_sNoteCardName, g_iLine);  
   

}

notecardFinished(string _notecard){

   // Called at the end of each notecard as it is read. The temp results are stored
   // and the next card is commanded to be read.
   if (_notecard == gsCardOneName) {
       gOneCard = g_lTempLines;
       loadNoteCard(gsCardTwoName);
   } else if (_notecard == gsCardTwoName) {
       gTwoCard = g_lTempLines;
       loadNoteCard(gsCardThreeName);
   } else if (_notecard == gsCardThreeName) {
       gThreeCard = g_lTempLines;
       initialize("finish");  // Finally pass execution to finish the initialization.   
   }    

}

default {

   state_entry()
   {
   }
   
   touch_start(integer _num_det){
       initialize("");
   }
    
   dataserver(key _query_id, string _data) 
   {
       if (_query_id == g_kQuery) {
           // this is a line of our notecard
           if (_data != EOF) {    
               g_lTempLines += _data;
               //request a next line
               ++g_iLine;   // increment line count
               g_kQuery = llGetNotecardLine(g_sNoteCardName, g_iLine);
           } else {
               //The notecard has been read 
               //notify end of read
               notecardFinished(g_sNoteCardName);
           }
       }
   }

} </lsl>

<lsl> ///// // Generic Multi Notecard reader by Randur Source // Given freely and published on wiki.secondlife.com // // This script will read all note cards in sequence and dump the results into chat as an example. // It can be modified and extended to do other things to the data. //

integer inventorycnt; integer notecardlinecnt; integer notecardlinenumber; string notecardname; key linenumberid; key lineid;

getnextnotecardlinenumber() {

   // first get the number of lines from the notecard
   inventorycnt++;
   if (inventorycnt < llGetInventoryNumber(INVENTORY_NOTECARD))
   {
       notecardname = llGetInventoryName(INVENTORY_NOTECARD,inventorycnt);
       linenumberid = llGetNumberOfNotecardLines(notecardname);
   }
   else
       llOwnerSay("Done.");

}

getnextnotecardline() {

    // get the next line from the notecard or skip to the next notecard
   notecardlinecnt++;
   if (notecardlinecnt < notecardlinenumber)
       lineid = llGetNotecardLine(notecardname,notecardlinecnt);
   else
       getnextnotecardlinenumber();

}

default {

   touch_start(integer total_number)
   {
       if (llDetectedKey(0) != llGetOwner()) return; // allow owner only
       inventorycnt = -1;
       getnextnotecardlinenumber();
   }
   
   dataserver(key queryid,string data)
   {
       if (queryid == linenumberid) // this was a line number lookup
       {
           linenumberid = NULL_KEY;
           notecardlinenumber = (integer)data;
           if (notecardlinenumber == 0)
               getnextnotecardlinenumber();
           else
           {
               notecardlinecnt = -1;
               getnextnotecardline();
           }
       }
       else if (queryid == lineid) // this was a data line lookup
       {
           lineid = NULL_KEY;
           // Example of what to do with the data:
           // Test for valid avatar names, possibly multiple names on each line, separated by ,
           // and say them in chat to the owner
           list names = llParseString2List(data,[","],[]); // split lines on ,
           integer len = llGetListLength(names); // I wouldn't dare to put this inside the for loop
           integer cnt;
           for (cnt = 0; cnt < len; cnt++)
           {
               string name = llDumpList2String(llParseString2List(llList2String(names,cnt),[" "],[])," "); // remove extra spaces
               if (llGetListLength(llParseString2List(name,[" "],[])) == 2) // check for first + lastname
                   llOwnerSay(notecardname + ": " + name);
           }
           getnextnotecardline();
       }
   }

}

</lsl>

Notes

The notecard read can be no modify, or no modify/no copy.

See Also

Events

•  dataserver

Functions

•  llGetNumberOfNotecardLines

Deep Notes

Signature

function key llGetNotecardLine( string name, integer line );