Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Multiple threads causing loop chaos =(

Diego Pannotia
Laronzo Fitzgerald
Join date: 14 Nov 2006
Posts: 37
03-08-2007 04:19
Hi there! Having some headachy problems with my loop, here's the explanation, thanks for your patience : )

I've stripped this script down to focus on the element I'm having issues with...

The order of things:

1) XML-RPC string received
2) string mapped to float
3) animation() sends float to Spur()

4) Spur() shouts float to object BASE
5) BASE shouts the same float back to this object
6) float sent to Pulse()
7) Pulse() sends float to Spur()

steps 4 - 7 loop so that Pulse() continues

The problem is that when I send a new message via XML-RPC, and a new float (let's say 6) is sent to Spur(), I get multiple threads! This means that the old float (let's say 1) is still hanging around and we get Pulse() looping on float 1 then 6. If I send another message (let's say 8) it gets added to this queue: 1,6,8

I only want the latest thread to loop! In this example: 8. I want to kill the previous thread/s: 1,6 whenever a new thread is received.

How can I do that!!!!! Really struggling to find the cause/solution.

Huge thanks in advance to you all

Mark.

CODE

key gChannel;

DEBUG(list out)
{
llSay(0, llList2CSV(out));
}

Pulse(float anima)
{
integer i;

list original = llGetPrimitiveParams([PRIM_POINT_LIGHT]);
float c_lev = llList2Float(original, 2);

float dim = c_lev / anima;

for(i=0;i< anima;++i)
{
list original = llGetPrimitiveParams([PRIM_POINT_LIGHT]);
float intense = llList2Float(original, 2);
vector c_c = llList2Vector(original, 1);
float take = intense - dim;

llSetPrimitiveParams([PRIM_POINT_LIGHT, TRUE, c_c, take, 10, 0.75]);
}
for(i=0;i< anima;++i)
{
list original = llGetPrimitiveParams([PRIM_POINT_LIGHT]);
float intense = llList2Float(original, 2);
vector c_c = llList2Vector(original, 1);
float add = intense + dim;

llSetPrimitiveParams([PRIM_POINT_LIGHT, TRUE, c_c, add, 10, 0.75]);
}
Spur(anima);
}

Spur(float an)
{
llShout(-150,(string)an);
}

animation(string ani){
if (ani == "very slow"){ Spur(6); }
if (ani == "slower"){ Spur(5); }
if (ani == "slow"){ Spur(4); }
if (ani == "pulse"){ Spur(3); }
if (ani == "medium"){ Spur(2.75); }
if (ani == "fast"){ Spur(2.5); }
if (ani == "faster"){ Spur(2); }
if (ani == "very fast"){ Spur(1.75); }
if (ani == "crescendo"){ Spur(1.5); }
if (ani == "heartbeat"){ Spur(1);}
}

default
{
state_entry()
{
llOpenRemoteDataChannel();
}
remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval)
{
if (type == REMOTE_DATA_CHANNEL)
{
gChannel = channel;
state waiting;
} else DEBUG(["Unexpected event type", type, channel, message_id, sender, ival, sval]);
}
}

state waiting
{
state_entry()
{
llListen(-160, "base", NULL_KEY, "" );
}

remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval)
{
if (type == REMOTE_DATA_REQUEST)
{
string stringPortionOfReply = "Default Reply";
integer intPortionOfReply = 0;

if (sval){
animation(sval);
}

llRemoteDataReply(channel, message_id, stringPortionOfReply, intPortionOfReply);

} else DEBUG(["Unexpected event type:", type, channel, message_id, sender, ival, sval]);
}

listen(integer channel, string name, key id, string message)
{
Pulse((float)message);
}
}
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
03-08-2007 08:52
Well, think about it for a minute...

You're sending out values in chat which are processed and resent. Chat operates like a queue; IE, while one value is in transit / being processed, another can enter the queue the same way the first did, and then you have two values being repeatedly queued and sent. Your scripts are doing everything they are told to do.

The only way to break the cycle is to stop repeatedly sending out previous values. To be able to do this, you have to be able to tell what is an "old" value, and what is a new one. One suggestion is to make the float negative at the end of the first iteration, and check to see if it is negative where it is received from "base", then set a flag. If you receive another request, then set a "new request" flag. At the end of the loop where you would turn the number negative, check to see if the number was negative and also if there was a new request received. If so, then don't send it out again. If not, make sure it is negative and send it out again, be sure to clear the new request flag either way at that point. Note that you will have to probably use llFabs() so you don't process the number in its negative form.

Another suggestion is to "version" the data by maintaining a counter and sending/processing its value along with the float data. Every time you receive a new value, you increment the counter before sending its value and the float out. When you receive a value, you check to see if it matches the current counter value. If it does, use it and/or send it back out; if not, then don't.
Diego Pannotia
Laronzo Fitzgerald
Join date: 14 Nov 2006
Posts: 37
03-08-2007 16:00
I like the counter suggestion, not entirely sure how to go about it atm but will give it some thought and elaboration would be most appreciated, for now I shall reference a few thinks on the wiki

cheers, Mark