Jump to content

Choosing A Channel


Perrie Juran
 Share

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

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

Recommended Posts


steph Arnott wrote:

Not a lot, It just an over complicated way of getting a channel, which can be hacked by copying the owners uuid, which is a big bonus if that ones intention. I simply do this.
menu_chan	=(integer)llFrand(-10000)-100;

 

It should be pointed out to the casual reader, who may be a novice, that opening listeners requires closing them correctly. Failing to do so will bite you in the end.

 

Study https://wiki.secondlife.com/wiki/Dialog_Menus paying particular attention to the varioius ways one can overlook this and end up with "dangling listeners", which is a Bad Thing©™.

.

Link to comment
Share on other sites


LepreKhaun wrote:


steph Arnott wrote:

Not a lot, It just an over complicated way of getting a channel, which can be hacked by copying the owners uuid, which is a big bonus if that ones intention. I simply do this.
menu_chan	=(integer)llFrand(-10000)-100;

 

It should be pointed out to the casual reader, who may be a novice, that opening listeners requires closing them correctly. Failing to do so will bite you in the end.

 

Study 
paying particular attention to the varioius ways one can overlook this and end up with "dangling listeners", which is a
Bad Thing
©™.

.

I get "There is currently no text in this page" when I follow that link????

Link to comment
Share on other sites

One of my scripts.

list corridor = ["10.75", "11.5 D/B", "3 Way R", "3 way L", "3 way L/R", "4 way", "door e/cap"];string msg = "Please make a choice.";key owner_id;integer channel_dialog;integer channel_dialog_handler;integer link_num = 15;integer link_filter = 0;list gDoors = [];default{	changed(integer change)	{		if(change & CHANGED_OWNER)		{			llResetScript();		}	}	state_entry()	{		channel_dialog = (integer)llFrand(-10000)-100;		integer i = llGetNumberOfPrims();//ignore this		while (i)		{			--i;			if (llGetLinkName(i) == "Door1")			{				gDoors += [i];			}		}//upto here, not sure my intention on this	}	touch_start(integer total_number)	{		owner_id = llGetOwner();		llDialog(owner_id, msg, corridor, channel_dialog);		channel_dialog_handler = llListen( channel_dialog, "", owner_id, "");//unless you
// declarre this handler you can not close the listen. llSetTimerEvent(20); } listen(integer channel, string name, key id, string choice) { if (choice == "10.75") { llMessageLinked(link_num,link_filter, "10.75", owner_id); llListenRemove(channel_dialog_handler); } else if (choice == "11.5 D/B") { llMessageLinked(link_num,link_filter, "11.5 D/B", owner_id); llListenRemove(channel_dialog_handler); } else if (choice == "3 Way R") { llMessageLinked(link_num,link_filter, "3 Way R", owner_id); llListenRemove(channel_dialog_handler); } else if (choice == "3 way L") { llMessageLinked(link_num,link_filter, "3 Way L", owner_id); llListenRemove(channel_dialog_handler); } else if (choice == "3 way L/R") { llMessageLinked(link_num,link_filter, "3 Way L/R", owner_id); llListenRemove(channel_dialog_handler); } else if (choice == "4 way") { llMessageLinked(link_num,link_filter, "4 Way", owner_id); llListenRemove(channel_dialog_handler); } else if (choice == "door e/cap") { llMessageLinked(link_num,link_filter, "Door E/Cap", owner_id); llListenRemove(channel_dialog_handler); } else { llListenRemove(channel_dialog_handler); } } timer() { //TIME?S UP! llListenRemove(channel_dialog_handler); llSetTimerEvent(0.0); //Stop the timer from being called repeatedly }}

 

Link to comment
Share on other sites

I commend you on your progress with LSL, you've come a long way over the past months. I feel you're ready now to begin learning to refactor code (http://en.wikipedia.org/wiki/Code_refactoring ).Gaining this skill will make your code more compact, easier to read and maintain, less error prone and allow larger, more complex programs.

Refactoring LSL is relatively easy once you get the hang of it. It's mainly looking for big chunks of code and examining it for ways it could be collapsed into a tighter solution that would accomplish the same thing. One does this first by finding identical or nearly alike lines of code and trying to see how they might be consolidated. Let us consider your listen() event handler you have in the above posting and see how it could be strengthened using this technique:

    listen(integer channel, string name, key id, string choice)    {        if (choice == "10.75")        {            llMessageLinked(link_num,link_filter, "10.75", owner_id);            llListenRemove(channel_dialog_handler);        }        else if (choice == "11.5 D/B")        {            llMessageLinked(link_num,link_filter, "11.5 D/B", owner_id);            llListenRemove(channel_dialog_handler);        }        else if (choice == "3 Way R")        {            llMessageLinked(link_num,link_filter, "3 Way R", owner_id);            llListenRemove(channel_dialog_handler);        }        else if (choice == "3 way L")        {            llMessageLinked(link_num,link_filter, "3 Way L", owner_id);            llListenRemove(channel_dialog_handler);        }        else if (choice == "3 way L/R")        {            llMessageLinked(link_num,link_filter, "3 Way L/R", owner_id);            llListenRemove(channel_dialog_handler);        }        else if (choice == "4 way")        {            llMessageLinked(link_num,link_filter, "4 Way", owner_id);            llListenRemove(channel_dialog_handler);        }        else if (choice == "door e/cap")        {            llMessageLinked(link_num,link_filter, "Door E/Cap", owner_id);            llListenRemove(channel_dialog_handler);        }        else        {            llListenRemove(channel_dialog_handler);        }    }

 

 The first step is easy, you've repeated the line "llListenRemove(channel_dialog_handler);" throughout. Simply consolidating that one line is going to shorten things very much:

     listen(integer channel, string name, key id, string choice)    {        // Remove listener and turn off timer        llListenRemove(channel_dialog_handler);        llSetTimerEvent(0.0);                if (choice == "10.75")        {            llMessageLinked(link_num,link_filter, "10.75", owner_id);        }        else if (choice == "11.5 D/B")        {            llMessageLinked(link_num,link_filter, "11.5 D/B", owner_id);        }        else if (choice == "3 Way R")        {            llMessageLinked(link_num,link_filter, "3 Way R", owner_id);        }        else if (choice == "3 way L")        {            llMessageLinked(link_num,link_filter, "3 Way L", owner_id);        }        else if (choice == "3 way L/R")        {            llMessageLinked(link_num,link_filter, "3 Way L/R", owner_id);        }        else if (choice == "4 way")        {            llMessageLinked(link_num,link_filter, "4 Way", owner_id);        }        else if (choice == "door e/cap")        {            llMessageLinked(link_num,link_filter, "Door E/Cap", owner_id);        }        else        {        }    }

 

Now, that refactored 8 lines into 2. It could've been just 1 except I realized when I removed all those repeats, that timer needed to be reset as well or it would needlessly trigger about a minute later. It would've been much worse if I had realized that and NOT refactored, I'd have ADDED "llSetTimerEvent(0.0);" eight times, making my event handler longer still and increasing my chance of error.

Examining the if-else chain remaining reveals a few things that show the need for refactoring. First, literals are being repeated. A literal is a string that is written out in your code and, when used, the characters that make up the string all must be stored within your program. In other words, the literal "10.75" is being stored in three places within your program, first in declaration and assignment of list corridor, then in your conditional test if (choice == "10.75") and finally in the following link message. This redundancy adds to your code size as well as making it harder to maintain and more error prone.

Second, all your if-else tests are doing the exact same thing, checking to see if choice matches a button. And then nearly all end up relaying choice on to another script. Nearly all, some are changing the capitalization in the literal. Not sure what's that about, but if we change a few of the button choices to consistently match what you want to send along, we can much shorten it.

// New global definition and the only literals neededlist corridor = ["10.75", "11.5 D/B", "3 Way R", "3 Way L", "3 Way L/R", "4 Way", "Door E/Cap"];// ...    // refactored event handler     listen(integer channel, string name, key id, string choice)    {        // Remove listener and turn off timer        llListenRemove(channel_dialog_handler);        llSetTimerEvent(0.0);                // check to make sure choice is on the list        if(~llListFindList(corridor, [choice]))        {            llMessageLinked(link_num,link_filter, choice, owner_id);        }        else        {            // something other than the list has come in            // respond or ignore as appropriate here        }    }

 Anyway, that's my thoughts on refactoring to get you started. It's a useful and productive skill to have and I hope you'll consider learning it, it's the natural next step. It'll make your code much tighter and, in the long run, end up saving you time and energy.

  • Like 1
Link to comment
Share on other sites


steph Arnott wrote:

OK I get all that, but the remove handler and  timer at the start, does the timer end only when a choice is made, that confusing me.

ADDED: Hmm on the external editor it switches the timer off at choice, i dont get that as it is before that if.

Using llSetTimerEvent(0.0); immediately after the llListenRemove() effectively cancels the timer without it ever being triggered. You want to do that because it's no longer required.

 

They're outside of the if() block because the original code had a llListenRemove() within the last else of the chain, so no matter what triggered the event, the handle would be closed.

 

I prefer to clear the open listen and the timer at the start of the listen event handler. But that's only because I'm scatter-brained and might forget it otherwise. :)

 

Unsure what "external editor" refers to.

Link to comment
Share on other sites

OK, i doing what you said, just simple stuff for now.

link_message(integer sender_number, integer number, string msg, key id)	{		if((number == Link_Filter_9) && (msg == "Email"))		{			llMessageLinked(Link_num, Link_Filter_8, "yesRezz", owner_key);			llEmail((string)gObject_key+"@lsl.secondlife.com","demat","demat");		}		else if((number == Link_Filter_9) && (msg == "closedoor"))		{			llEmail((string)gObject_key+"@lsl.secondlife.com","CloseDoor","CloseDoor");		}	}

 

link_message(integer sender_number, integer number, string msg, key id)	{		if(number == Link_Filter_9)		{			if(msg == "Email")			{				llMessageLinked(Link_num, Link_Filter_8, "yesRezz", owner_key);				llEmail((string)gObject_key+"@lsl.secondlife.com","demat","demat");			}			else if(msg == "closedoor")			{				llEmail((string)gObject_key+"@lsl.secondlife.com","CloseDoor","CloseDoor");			}		}

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3806 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...