How does INVENTORY_CHANGED get triggered?
|
|
Monica Balut
Beam-Me
Join date: 18 Feb 2007
Posts: 311
|
01-12-2008 16:37
If I add 100 landmarks from my personal inventory to an object's all at once, I get close to 100 INVENTORY_CHANGED events that get triggered. They seem to come in at a steady interval.
On the other hand, if I remove 100 landmarks from the object's inventory all at once, the behavior of the INVENTORY_CHANGED event seems very different. A couple of events get triggered, then a pause and a couple more. I never get more than 8 that get triggered all total.
Why the different behavior? I would think the changed event getting triggered has to do with the way the object synchronizes with the asset servers but I don't really know that much about this. Can someone explain how this works and why it behaves differently when adding than when taking away.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-12-2008 17:36
I don't know when it decides to tell you about changes, or when it might condense multiple additions/removals into one event. But I also wouldn't count on the behavior staying the same in the future. The event generally just tells you that inventory has changed, and it is up to you to figure out how if that is important. It can be a pain, but usually you can figure out how to reasonably remember and compare the bits that are significant to your application if you think about it a bit.
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
01-12-2008 18:30
I don't think you can even count on getting a single CHANGED_INVENTORY event when items are removed by script. See https://jira.secondlife.com/browse/SVC-304.
|
|
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
|
01-12-2008 18:44
This event is a bit flaky, I think. In addition to what Qie says, it also get a INVENTORY_CHANGED event whenever a script gets recompiled. Kinda annoying, IMO.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-12-2008 19:12
the behavior is supposed to be any item added (it treats them all as single adds), any saved changes (note cards, scripts, recompiles are considered changes). deletions can be done bulk so they only get one... that's the logic anyways
_____________________
| | . "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... | - 
|
|
Monica Balut
Beam-Me
Join date: 18 Feb 2007
Posts: 311
|
01-12-2008 20:44
Here's what I'm trying to accomplish. I want the object to automatically reconfigure itself whenever landmarks have been added or removed from it. I can easily trigger that from the changed event in the active state. Once triggered, I move to the DoConfiguration state. That state farms out the actual reading and parsing to script B which notifies the main script when it is done. I have to do this for memory limitation issues. It is possible that up to 100 landmarks could be added or removed from the object in a batch, or the user could make further changes before configuration is done. Because the inventory changes are brought in slowly by the asset servers, I need to be able to have the DoConfiguration restart itself if the inventory changes while in that state. I would like to minimize the restarts as much as possible and also minimize the false starts ( believing it is done when there are still more changes to come). After experimentation, here's what I've come up with. I'd appreciate comments on how to improve it.
SetTimer(float time) { llSetTimerEvent(0.0); llSetTimerEvent(time); }
state DoConfiguration { // this farms out reading the landmarks to Script B state_entry() { OwnerSay("Starting coniguration"); llResetOtherScript("ScriptB"); llSleep(0.1); llMessageLinked(LINK_THIS,110,"",null_key); // do landmark config in script B }
link_message(integer sender, integer Numb, string Str, key id) { if (Numb == 111) // Landmark config done message from script B { integer processedLM = (integer) ((string) id); // the number of landmarks that script B processed integer currentLM = llGetInventoryNumber(INVENTORY_LANDMARK); //Script B will ensure at least a 5 sec delay between these two numbers if (processedLM == currentLM) { // assume configuration is done //process what is returned from script B here state active; } else { // immediately stop script B and trigger it to restart in 8 sec llResetOtherScript("ScriptB"); SetTimer(8.0); } } } changed(integer change) { if (change & CHANGED_INVENTORY) { // immediately stop script B and trigger it to restart in 8 sec llResetOtherScript("ScriptB"); SetTimer(8.0); } } timer() { llSetTimerEvent(0.0); llMessageLinked(LINK_THIS,110,"",null_key); // do landmark config in script B llOwnerSay("Restarting configuration"); } }
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-12-2008 21:29
Certainly you get a changed event with INVENTORY_CHANGED when a script is recompiled or a notecard saved. While after these changes there may be a script/notecard with the same name still in inventory, it is actually a different script/notecard with a new UUID and different content. That's the kind of thing you may want to know about. 
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-12-2008 22:24
I did something like this, I just called llSetTimerEvent( 3.0 ) each time a changed event is triggered, then in the timer swap to your state that reads the prims inventory... you need to reread all items because like hewee pointed out the name may be the same but the contents could be changed... as long as the events come in faster than 3 secs it keeps getting put off
_____________________
| | . "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... | - 
|
|
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
|
01-13-2008 10:18
From: Hewee Zetkin Certainly you get a changed event with INVENTORY_CHANGED when a script is recompiled or a notecard saved. While after these changes there may be a script/notecard with the same name still in inventory, it is actually a different script/notecard with a new UUID and different content. That's the kind of thing you may want to know about.  Yep, I understand why it says something changed when a script gets recompiled. I still find it annoying - don't see much reason why a script would want to know about that. (which I also understand doesn't mean that _nobody_ would want to know.. just that I haven't found a use for it)
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-13-2008 18:59
From: Sindy Tsure Yep, I understand why it says something changed when a script gets recompiled. I still find it annoying - don't see much reason why a script would want to know about that. (which I also understand doesn't mean that _nobody_ would want to know.. just that I haven't found a use for it) because it treats recompiles as a new script... the normal recompile occurs on changes in the script, making it a new item... granted it may be the exact same code, but for safety (and to track changes in how the compiler works) it needs to treat even the same script code as unique because changes to how the compiler interprets it could mean changes in script behavior.... plus it's simpler to just treat them all as new
_____________________
| | . "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... | - 
|
|
Monica Balut
Beam-Me
Join date: 18 Feb 2007
Posts: 311
|
01-13-2008 19:52
Besides, in many situations I would want it to do what it does in INVENTORY_CHANGED when I recompile the script. Like in the case I described above, I trigger a reading of configuration information. When I recompile the script, I want it to reconfigure itself. I'd hate to do that as a separate step.
Like usual, Void does an excellent job at explaining the way it works under the hood.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-13-2008 23:03
er thanks... =)
_____________________
| | . "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... | - 
|
|
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
|
01-14-2008 09:52
heyas;
ive been working on an item that stores new notecards on inventory drop (well, ive been using changed_inventory, since im the one dropping them in.) i dont know if i can help, but i put in an anti-spam routine, and here's what i found.
basic outline: inventory_change triggers a sorting routine, sorting routine checks how many new notecards were dropped if > x, it deletes them all as spam and sleeps the script for 6 seconds. (otherwise, it hands them to a storage prim, then deletes them from its own prim.)
so i go and throw in more than x notecards. here's what happens:
1: first notecard triggers changed_inventory, sort routine finds one new card and processes it.
2: the changed_inventory has been triggered again (by the second or more?? cards) , the sort routine finds too many and deletes them and sleeps.
3: sometimes, if there are a lot of notecards over the target, the process is triggered again. for example, if X is 5, and i throw in 14 cards, i'll get a batch of 1, then a batch of 7, then a batch of 6.
what i dont know is: how long it takes for how large of a stack to get in between changed_inventory events. (keep in mind that deleting the spam, and the notecard process, which passes the new notecard to another prim are ALSO triggering changed_inventory events!)
i dont know how many changed_inventory events are getting queued. like, if i drop in 20 cards, does it get queued 20 times, and my sorter only notices it when cards are added? (its trained to skip other inventory changes).
you could probably add a global counter, and increment it every inventory change, then toss in 100 landmarks. see what the counter comes out to. that sounds helpful, i might try it, if i get time.
wish there were an event queue-clearing function :/
void... are you saying that delaying the script clears the changed event queue, or are you saying that switching states clears it? dang it, and i was almost done with my script....!
_____________________
Why Johnny Can't Rotate: http://forums.secondlife.com/showthread.php?t=94705
|
|
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
|
01-14-2008 10:08
From: Void Singer because it treats recompiles as a new script... the normal recompile occurs on changes in the script, making it a new item... granted it may be the exact same code, but for safety (and to track changes in how the compiler works) it needs to treat even the same script code as unique because changes to how the compiler interprets it could mean changes in script behavior.... plus it's simpler to just treat them all as new I think Sindy is saying that it's not useful to her because scripts, in general, don't really start up in a predictable way - it's not defined who runs first if you reset-all-scripts on an object. Scripts within an object that need to talk to each other probably have some sort of start-up protocol to say I'm-here or Send-me-data or whatever. From that point of view, the inventory change event when a script recompiles is just noise and can be annoying if other scripts in the object are watching for other inventory changes and might have to re-parse notecard configs.
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!! - Go here: http://jira.secondlife.com/browse/SVC-1224- If you see "if you were logged in.." on the left, click it and log in - Click the "Vote for it" link on the left
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-14-2008 12:58
Here's an interesting one. Way back when we had an in-world bug report tool, I submitted a report on this. I have no idea if it has ever been fixed, but I doubt it. Maybe someone could test it and open a JIRA issue if it is still present.
If you rename a script, a 'changed' event with the CHANGED_INVENTORY flag is raised. If another script examines the inventory names during this event, they will see the script under the new name. If the script that has been renamed tests its own name right away with llGetScriptName() during the event, it will see the old name (so it actually sees NO change to prim inventory). But if a delay is introduced in the script--like just adding a 'llSleep(1.0)' before testing llGetScriptName(), then the correct name will be returned afterward.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-15-2008 02:11
From: Meade Paravane I think Sindy is saying that it's not useful to her because scripts, in general, don't really start up in a predictable way - it's not defined who runs first if you reset-all-scripts on an object. actually if you do it from the menu I do believe they start up in the same order they apear in prim inventory... can't remember what the difference is for multiple prims, at least that's what the script reset window reports... if you restart them from another script it's a simple matter to customize your order since you have to specify them one at a time... From: someone Scripts within an object that need to talk to each other probably have some sort of start-up protocol to say I'm-here or Send-me-data or whatever. From that point of view, the inventory change event when a script recompiles is just noise and can be annoying if other scripts in the object are watching for other inventory changes and might have to re-parse notecard configs. true enough, it is a pita but not a frequent occurance (since you can't recompile a script from another) PS bug reporting is still available from the ui (well it is in the nicholaz client)
_____________________
| | . "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... | - 
|
|
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
|
Test Results:
01-16-2008 10:51
heyas;
so i put in the changed_inventory global variable counter and did my notecard-spam-dropping test.
what came out was one changed_inventory event for each batch of cards. (ie: 1 for the first card, 1 for the next 7 or so, and one more for the next 7 or so.)
which works for me, but.... not what i expected.
|
|
Zynx Zabelin
Registered User
Join date: 14 Sep 2007
Posts: 2
|
01-16-2008 12:13
Heres how I would do it. I would make two arrays A and B, every time the event is triggered the inventory of the object is dumped to B and then its length (number of objects in the array) compared with A, after being compared B replaces A. That way you know how many items have been moved each time.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
01-16-2008 13:27
From: Zynx Zabelin Heres how I would do it. I would make two arrays A and B, every time the event is triggered the inventory of the object is dumped to B and then its length (number of objects in the array) compared with A, after being compared B replaces A. That way you know how many items have been moved each time. Good idea except that there are no arrays in LSL.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
|
01-16-2008 13:56
From: Jesse Barnett Good idea except that there are no arrays in LSL. I think he meant a list.. If you're only comparing before/after counts, that's not even needed - just remember the previous count as an int..
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!! - Go here: http://jira.secondlife.com/browse/SVC-1224- If you see "if you were logged in.." on the left, click it and log in - Click the "Vote for it" link on the left
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-16-2008 14:45
From: Jesse Barnett Good idea except that there are no arrays in LSL. I'm not sure what the point of that statement is. It is pretty obvious that when someone refers to an "array" in the context of LSL, they actually mean an LSL list. In fact, LSL lists fit well enough the general computer science notion of an array: a set of elements that is indexable (by integer values, nonetheless). That indexing is even done in a random-access fashion that I believe takes constant time. It is immaterial whether that indexing is done with a square bracket, a curly brace, or what looks like or may even be a function call. LSL may not have general purpose multi-dimensional arrays, but that's a sub-case. Let's just be contructive and try to help people come up with solutions and scripting skills. Jumping on someone's phrasiology when the meaning is obvious probably isn't going to help much. Instead it will likely just discourage them from continuing to learn.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
01-16-2008 16:12
From: Hewee Zetkin I'm not sure what the point of that statement is. It is pretty obvious that when someone refers to an "array" in the context of LSL, they actually mean an LSL list. I try not to assume anything. If someone says array then I take that literally until thier statement is corrected. New people to LSL with expirience in other languages ask frequently here where the arrays are at. As to the rest, you really need to go back and look through my 1400 + posts to this forum to see that I don't "jump" on people. I was simply correcting the mistake.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
01-16-2008 16:33
From: Meade Paravane If you're only comparing before/after counts, that's not even needed - just remember the previous count as an int.. That would be the way I would do it: changed(integer change) { if (change & CHANGED_INVENTORY) { integer count_a = llGetInventoryNumber(INVENTORY_LANDMARK); integer count_b; if(count_a != count_b) { // immediately stop script B and trigger it to restart in 8 sec llResetOtherScript("ScriptB"); SetTimer(8.0); count_b = count_a; } } }
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
01-16-2008 19:35
Looks like 6 of one and half dozen of the other. Tested 30 itinerations and came up with results like this:
"[19:30] 1 listen, 7 if test's for keys: Testing channel 599 1 listen w/ if test's against multiple listens for each key [19:30] 7 listens with different keys: Testing channel 599 1 listen w/ if test's against multiple listens for each key [19:30] Object: 0.064595 [19:30] 7 listens with different keys: Testing channel 599 1 listen w/ if test's against multiple listens for each key [19:30] 1 listen, 7 if test's for keys: Testing channel 599 1 listen w/ if test's against multiple listens for each key [19:30] Object: 0.064525"
Sometimes the single listen/multiple if's was faster and then other times multiple listens keyed for different keys was faster. So whichever way you want to do it.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Monica Balut
Beam-Me
Join date: 18 Feb 2007
Posts: 311
|
01-16-2008 20:31
See my code above. I've been using this and it's working fine both when you add or subrtact items. Essentially it does what Jesse recommends ( check if the total # of items has changed) as well as check for inventory change. If you do both, you're pretty much covered.
|