Newbie Q on multiple uses of dataserver event
|
|
Barrington John
Yorkshire guy
Join date: 17 Nov 2007
Posts: 119
|
02-18-2008 05:00
Just cutting my teeth here with LSL, though I'm a reasonably experienced programmer in some other languages.
I have a script in a prim which basically pulls data out of notecards and processes it. So far, it's got a list of filenames and their sizes in lines, using llGetInventoryName() and llGetNumberOfNotecardLines(), and that works fine. It seems that for llGetNumberOfNotecardLines() to work, I need to define a dataserver event to populate the list of file sizes. OK so far.
But I also need to be able to read data from a given line of a given file, using llGetNoteCardLine(). This also triggers the dataserver event to get the data, which I need to use in a different way.
My question is: how can the dataserver event distinguish between the two different types of calls to it, so that it can do the right thing with the data it has? Fortunately, in this case, it can tell from the format of the data it receives which it's dealing with, but that's a kludge, and might not be possible in other cases.
|
|
Whispering Hush
™
Join date: 20 Mar 2007
Posts: 277
|
02-18-2008 05:10
|
|
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
|
02-18-2008 07:31
If you are only doing one thing at a a time, you can set the value of a global variable when you make the dataserver request, which you then check inside the dataserver event handler. e.g. set a global integer variable to 1 for one type of data, 2 for another, and so on.
If you are making multiple asynchronous requests (not waiting for the response from one before you make another), then you'll probably have to keep a global list of query ID's returned by the requesting function, followed by the type of request it is. Then in your dataserver event handler, search the list for the query ID, and if found, check the next list element for the request type it pertains to. Afterward, delete those elements from the list.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
02-18-2008 09:20
From: Deanna Trollop If you are making multiple asynchronous requests (not waiting for the response from one before you make another), then you'll probably have to keep a global list of query ID's returned by the requesting function, followed by the type of request it is. Then in your dataserver event handler, search the list for the query ID, and if found, check the next list element for the request type it pertains to. Afterward, delete those elements from the list. ...or one global variable for each KIND of thing you ask for if you only ask for one of each kind of thing at a time. For example: key noteSizeRequest = NULL_KEY; key noteLineRequest = NULL _KEY; ... noteSizeRequest = llGetNumberOfNotecardLines(...); noteLineRequest = llGetNotecardLine(...); ... dataserver(integer requestId, string data) { if (requestId == noteSizeRequest) { ... } else if (requestId == noteLineRequest) { ... } }
|
|
Barrington John
Yorkshire guy
Join date: 17 Nov 2007
Posts: 119
|
02-18-2008 12:16
Deanna, it's the latter case (multiple asynchronous requests) that's involved.
Thanks everyone - I'd suspected I'd have to do something like that.
Also, I gather that events aren't always triggered in the same order they're queued, so I could make sure that each piece of data corresponds to the correct actual request, a kind of side benefit. I guess I could do that precisely by using three list elements per entry for the type of request: the QueryID; the query type; and a reference to the source data element that initiated the request.
Also, is there a neat way of waiting for the queue to be empty? Something akin to DoEvents() in VB, so I can fire off a bunch of events and then loop, waiting until the queue's empty (or the list of requests is), before continuing processing? I know this can be seen as bad practice, forcing procedural design on an event-driven environment, but IMO it would be handy if used with caution.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
02-18-2008 12:22
you can also use mode switching by a keyword or phrase within the notecard to parse data differently... something like this in the notecard == Avatars == Void Singer Heewee Zetkin Deanna Trollop Whispering Hush Barrington John == End ==
== Values == 1 2 3 4 5 == End ==
then in your script list gLstAvatars; list gLisValues; integer gIntLine; integer gIntMode;
default{ state_entry(){ llGetNotecardLine( "notecard name", gIntLine ); }
dataserver( key vKeyNull, string vStrData ); if (EOF == vStrData){ //-- whatever we do when we're done reading like change states }else{ if (gIntMode){ if ("== End ==" == vStrData){ gIntMode = 0; }else if (1 == gIntMode){ gLstAvatars += (list)vStrData; }else{ gLstValues += (list)((integer)vStrData) } }else if ("== Avatars ==" == vStrData){ gIntMode = 1; }else if ("== Values ==" == vStrData){ gIntMode = 2; } llGetNotecardLine( "notecard name", ++gIntLine ); } } }
obviously you can have more complex handling in your respective modes, allowing data pairs or different parsing, this was just to give an idea of how to set it up.... you can even add a counter to the mode if it should always have X lines of data after the header, and then you wouldn't need an 'end' statement.
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Barrington John
Yorkshire guy
Join date: 17 Nov 2007
Posts: 119
|
02-18-2008 20:00
Sure, Void, there are all sorts of ways of structuring data in a text file (the .INI format comes to mind, and even XML and its friends), but in this project, the data in those notecards needs to be as quick and simple for users to enter as possible - this is a primary consideration. In fact, the structuring of the data inside the notecards wouldn't have made any difference - it was the filenames of the cards and their sizes that needed matching, and then at a later time a specific line of a specific card extracted. The lines themselves are simply lists of values with separators.
Always interesting to see different approaches to different situations, though - thanks.
|
|
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
|
02-18-2008 21:45
From: Barrington John Also, is there a neat way of waiting for the queue to be empty? Sure. At the end of the dataserver event handler, after deleting the list element(s) for the just-processed data response, check if the queue list is empty. If so, switch to another state which contains all the "operational" code. To prevent hangups due to unprocessed events in the queue, you could include a timer set for a reasonable duration within which a response should have been received (say, 10-30 sec... most dataserver requests I've made seem to respond almost immediately, but I don't do it all that often), then run through the queue and re-request anything which hasn't been returned yet (replacing the old query IDs with new ones, of course.)
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
02-19-2008 01:33
actually the point wasn't so much to show distinctions within a notecard, as to show the idea of mode switching.... so you could have a default set mode that applies to each type of request, which could be settable from a notecard, in the script along with (or previous to the call), or some other method... very similar to global switching instead of state changes, which raises another possibility (using different states for different request types)
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Barrington John
Yorkshire guy
Join date: 17 Nov 2007
Posts: 119
|
02-19-2008 17:23
Thanks again to you both. Clearly, this application needs to make more use of state changes than it currently does - this has already shown up in other ways too. Still, I'm writing it to learn LSL, so it's at least achieving its purpose in that respect. 
|