Jump to content

PRIM_COLOR vs CHANGED_COLOR.. how to stop the infinite loop?


Honey Puddles
 Share

You are about to reply to a thread that has been inactive for 4297 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

So I've got a real puzzler here.

I made a script, which is supposed to work with another script. that second script, I don't have a lot of control over, but it would be able to hide or show various parts of the linkset, including what I'm going to call "straps and buckles"

Now these straps and buckles, being hidable or showable on demand, presents a problem, in that I have some "lock" prims, which are hidden or shown by the script I'm actually writing. The locks attach to the buckles, and when the buckles are hidden, the locks need to be hidden too, whether the script says it's "locked" or 'unlocked".

So I've written a function, which triggers on CHANGED_COLOR.. it scans the linkset for any strap prims.. and on finding them, determines whether they're visible or invisible, and then acts accordingly to hide or show the locks, based on the current state of the "locked" variable.


That's all working beautifully.. but here's the problem.


When the script I'm writing turns those locks visible or invisible, that linkset change is in fact, triggering the CHANGED_COLOR event again! Which results in my script checking for the presence of the strap prims, checking their visibility, and then checking for lock prims, checking their visibility, comparing that to the locked variable, and if they're the same, it does nothing... ending the loop.


My problem however, is that this process is needlessly "hot". The second check is completely unneccessary.

I've tried changing to a different state to make the changes, I've tried setting a variable "settingLocks" to true while making changes, and then false when done, and filtering the changed event based on that.. but no matter what I try, I just can't seem to get the script to ignore the change.

My workaround (checking the current visibility of the locks before deciding if they need to be changed) is fairly rudimentary..

Is there a better way to go about avoiding this recursion problem?

Link to comment
Share on other sites

When using the settingLocks variable, where are you checking it in the changed event?

integer settingLocks = false;

DoMyStuff()
{
     settingLocks = true;
     some code to change alpha on a child object (triggers change)
     some more code to do this (triggers another change)
     etc
     settingLocks = false;
}

default
{
     changed(integer change)
     {
          if (!settingLocks)
          {
               if (change & CHANGED_COLOR)
               {
                    DoMyStuff;
               }
          }
     }
}

This check in the changed event should always work, so something in your iteration through the linkset triggering it isn't keeping the state of settingLocks consistent. Hard to really get my head around it without seeing some actual code.

Link to comment
Share on other sites

That's pretty much exactly what I tried.. the problem is that for whatever reason, these changed events queue up while the setting is happening, and when I go back and flip the flag to false, and end the function, the changed event fires with the queued changes.

I was shocked that changing states didn't solve the problem, but I suspect there's also some latency between "do thing" and "detect change" that's allowing it to detect the changes after they've ended.

Link to comment
Share on other sites

"That second script, I don't have a lot of control over" is not very clear. Do you have modify permission on it or you don't? If you do, it should be fairly trivial to insert linked messages to send to your script after each llSetAlpha() or llSetLinkAlpha() call. Then you don't need any change event, just go by these linked messages.

Link to comment
Share on other sites


Ela Talaj wrote:

"
That second script, I don't have a lot of control over
" is not very clear. Do you have modify permission on it or you don't? If you do, it should be fairly trivial to insert linked messages to send to your script after each llSetAlpha() or llSetLinkAlpha() call. Then you don't need any change event, just go by these linked messages.

no, I don't have modify permission. I can control what it shows and hides, but I can't control whether it sends linkmessages or not.

Link to comment
Share on other sites

I have some questions, which may help to find a solution:

  1. Are all the prims (I guess you added some to an existing build) linked?
  2. You said, there is a script, that already existed - again, I assume, there was an original build you want to mod and this script was part of the original build - is that script the only one in the original linkset, or is there at least one in each alpha changing prim?
  3. If all is controlled from one script, maybe naming your new hidable prims exactly like on of the original hideable prims will do the trich - using llSetLinkPrimitiveParams, usually don't rely on the link numbers, but look for the prim names
  4. If that doesn't work, you can still follow your old path:

 

  1. on the change event, get the Alpha value of the prim that the original prim changes
  2. compare the Alpha vaue of that prim with your prim - and only change it, if they are not the same - that should do the trichk, if I understand you correctly
Link to comment
Share on other sites

Is there anything preventing you just deleting that original script that you can't modify and re-implementing its functionality in your own original code? I am thinking that the most elegant way to deal with this is using llMessageLinked, and explicitly setting the needed alpha states on or off, with a logical flow that you're entirely in control of. You can group like pieces of the linkset together (buckles and locks go visible/invisible together) with the llMessageLinked function's second integer parameter. It's an arbitrary integer value that can be used to target messages to specific objects in the linkset without explicitly sending to those link numbers. 

Link to comment
Share on other sites

Also, remember that we have link functions now so that we don't HAVE to use linked messages for a lot of prim functions.  What I do:

 

Create a list of the prim numbers that constitute a particular 'part' I want to change visibility/color/etc.

Write a function that takes the list and the new value, and call it as needed.

That function loops over the list, and calls the appropriate llSetLinkWhatever() function as appropriate.....or, if not available in that kind of function, calls llSetLinkPrimitiveParamsFast().

 

Viola!

So in this case, it would be something like:

list prims_for_lock = [ 5,6,7,9,12 ]; // These could change, so you could write a function to populate// the list based on the prim name or description fields ( I scan for// specific prefixes or suffixes in my versions, and name the prims// appropriately.ChangeColorAndAlpha(list prims, vector color, float alpha){    integer i;    for(i=0; i < llGetListLength(prims); i++)    {        // The if's are there so you can call this function and NOT        // change one of the two if needed.  And if you need black, just        // pass in a color of <0.0,0.0,0.001>        if(color != ZERO_VECTOR)            llSetLinkColor(llList2Integer(prims,i),color,ALL_SIDES);        if(alpha > 0.0)            llSetLinkAlpa(llList2Integer(prims,i),alpha,ALL_SIDES);    }}

 

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4297 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...