Difference between revisions of "EasyDialog"
Pazako Karu (talk | contribs) m |
Pazako Karu (talk | contribs) (Undo revision 1216959 by Pazako Karu (talk) brainfart) Tag: Undo |
||
(5 intermediate revisions by the same user not shown) | |||
Line 3: | Line 3: | ||
Take on high-security dialogs the easy way! | Take on high-security dialogs the easy way! | ||
Simplifies listens and contextual information greatly into gets and sets. Each dialog uses a new listen, a new channel, and listens only to the originator of the dialog. Any use of a dialog will trigger self-clean garbage collection of old listens and values. | Simplifies listens and contextual information greatly into gets and sets. Each dialog uses a new listen, a new channel, and listens only to the originator of the dialog. Any use of a dialog will trigger self-clean garbage collection of old listens and values. | ||
Caveats: If the last person to dialog chose to Ignore or close without a getDialog response, 1 listen event will remain in queue and active until another person touches it. This is not generally a problem, and this will be rare. If this trivial amount of lag is a problem (its a very specific listen, least possible lag), run cleanDialogs() on a timer after click events or after special events like reset. | |||
Example use case below. | Example use case below. | ||
< | <syntaxhighlight lang="lsl2"> | ||
list DIALOG_DATA; | list DIALOG_DATA; | ||
setDialog(key id, string caption, list buttons, integer context) // Creates a listen and a dialog | setDialog(key id, string caption, list buttons, integer context) // Creates a listen and a dialog | ||
Line 30: | Line 32: | ||
return context; // Return the context | return context; // Return the context | ||
} | } | ||
</ | cleanDialogs() | ||
{ // Removes our listens and clears data | |||
integer index; // Time, Id, Listen, Context | |||
for (index = 2; index < llGetListLength(DIALOG_DATA); index+=4) | |||
llListenRemove((integer)DIALOG_DATA[index]); | |||
DIALOG_DATA=[]; | |||
} | |||
</syntaxhighlight> | |||
= Example use = | = Example use = | ||
Context is useful for creating sub-menus without complicating the listen logic. As you can have a precheck of context, you can keep simple "Yes" and "No" answers, rather than the often-used trope of including special characters with each menu option. No additional variables or flags are necessary. | Context is useful for creating sub-menus without complicating the listen logic. As you can have a precheck of context, you can keep simple "Yes" and "No" answers, rather than the often-used trope of including special characters with each menu option. No additional variables or flags are necessary. | ||
< | |||
Think of 'context' the same as a 'listen handle', except it is set when you call a dialog, so you know the source and <b>context</b> of what your listen is handling. | |||
<syntaxhighlight lang="lsl2"> | |||
integer context_pancake = 1; | integer context_pancake = 1; | ||
integer context_pie = 2; | integer context_pie = 2; | ||
Line 45: | Line 57: | ||
listen(integer channel, key id, string message) | listen(integer channel, key id, string message) | ||
{ | { | ||
integer context = getDialog(id); | integer context = getDialog(id); // This gets our context number back, and cleans up the listen event | ||
if(context == context_pancake) // | if (context == context_pancake) // Do they like pancakes? | ||
{ | { // Notice here we know the dialog is about pancakes, so we can use Yes/No exactly | ||
if (message == "Yes") | if (message == "Yes") | ||
llRegionSayTo(llGetOwner(), 0, "Glad to hear it!"); | llRegionSayTo(llGetOwner(), 0, "Glad to hear it!"); | ||
Line 53: | Line 65: | ||
setDialog(llGetOwner(), "Sorry, how about pie?", ["Yes", "No"], context_pie); | setDialog(llGetOwner(), "Sorry, how about pie?", ["Yes", "No"], context_pie); | ||
} | } | ||
else if (context == context_pie) // They like pie | else if (context == context_pie) // They didn't like pancakes, how about pie? (sub-menu from "No" earlier) | ||
{ | { // And here we know the dialog is about pie. | ||
if (message == "Yes") | if (message == "Yes") | ||
llRegionSayTo(llGetOwner(), 0, "Pie is my second favorite!"); | llRegionSayTo(llGetOwner(), 0, "Pie is my second favorite!"); | ||
Line 62: | Line 74: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> |
Latest revision as of 15:45, 31 July 2024
Free to use in any context for any reason. Provided by Pazako Karu
Take on high-security dialogs the easy way! Simplifies listens and contextual information greatly into gets and sets. Each dialog uses a new listen, a new channel, and listens only to the originator of the dialog. Any use of a dialog will trigger self-clean garbage collection of old listens and values.
Caveats: If the last person to dialog chose to Ignore or close without a getDialog response, 1 listen event will remain in queue and active until another person touches it. This is not generally a problem, and this will be rare. If this trivial amount of lag is a problem (its a very specific listen, least possible lag), run cleanDialogs() on a timer after click events or after special events like reset.
Example use case below.
list DIALOG_DATA;
setDialog(key id, string caption, list buttons, integer context) // Creates a listen and a dialog
{ getDialog(id); // Clean up beforehand
if (llList2Integer(DIALOG_DATA, -3) > llGetTime()) // Clear old
{ integer i;
for (i = 0; i < llGetListLength(DIALOG_DATA); i++)
llListenRemove((integer)DIALOG_DATA[i+2]);
DIALOG_DATA = []; // If the last timed out, all are invalid
}
integer channel = -(integer)llFrand(DEBUG_CHANNEL);
DIALOG_DATA += [llGetTime()+60, id, llListen(channel, llKey2Name(id), id, ""), context]; // Time, ID, Listen Handle, context
llDialog(id, caption, buttons, channel);
}
integer getDialog(key id)
{ integer index = llListFindList(DIALOG_DATA, [id]); // Finds the dialog, if it exists
integer context = (integer)DIALOG_DATA[index+2]; // Context that the dialog was sent in, integer
if (~index) // If it does...
{ llListenRemove(llList2Integer(DIALOG_DATA, index+1)); // Remove the listen
DIALOG_DATA = llDeleteSubList(DIALOG_DATA, index-1, index+1); // Free the memory
}
else context = -1; // If it doesn't exist, return nothing
return context; // Return the context
}
cleanDialogs()
{ // Removes our listens and clears data
integer index; // Time, Id, Listen, Context
for (index = 2; index < llGetListLength(DIALOG_DATA); index+=4)
llListenRemove((integer)DIALOG_DATA[index]);
DIALOG_DATA=[];
}
Example use
Context is useful for creating sub-menus without complicating the listen logic. As you can have a precheck of context, you can keep simple "Yes" and "No" answers, rather than the often-used trope of including special characters with each menu option. No additional variables or flags are necessary.
Think of 'context' the same as a 'listen handle', except it is set when you call a dialog, so you know the source and context of what your listen is handling.
integer context_pancake = 1;
integer context_pie = 2;
default
{
state_entry()
{
setDialog(llGetOwner(), "Do you like pancakes?", ["Yes", "No"], context_pancake);
}
listen(integer channel, key id, string message)
{
integer context = getDialog(id); // This gets our context number back, and cleans up the listen event
if (context == context_pancake) // Do they like pancakes?
{ // Notice here we know the dialog is about pancakes, so we can use Yes/No exactly
if (message == "Yes")
llRegionSayTo(llGetOwner(), 0, "Glad to hear it!");
else if (message == "No")
setDialog(llGetOwner(), "Sorry, how about pie?", ["Yes", "No"], context_pie);
}
else if (context == context_pie) // They didn't like pancakes, how about pie? (sub-menu from "No" earlier)
{ // And here we know the dialog is about pie.
if (message == "Yes")
llRegionSayTo(llGetOwner(), 0, "Pie is my second favorite!");
else if (message == "No")
llRegionSayTo(llGetOwner(), 0, "I guess we dont have much in common :(");
}
}
}