Join us in Outworldz at www.outworldz.com:9000 or follow us:

Search dozens of selected web sites for OpenSim and LSL script

New! Script Meta-Search will search thousands of scripts here and at other sites for LSL or Opensim scripts.
Loading

Want to add a script or a project? Upload it and a half million people will see it and your name here this year.

Home   Show All
Category: Contributor: Creator
Menu ButtonAbstractionLayer  

ButtonAbstractionLayer

Button-Abstraction-Layer.lsl

Category: Menu
By : Francisco V. Saldana
Created: 2010-01-10 Edited: 2010-01-10
Worlds: Second Life

the Zip file

Download all files for ButtonAbstractionLayer
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. ButtonAbstractionLayer_1.lsl
1
2
3 // ButtonAbstractionLayer
4 // This script is responsible for monitoring touchable linked prims ("buttons")
5 // It also implements the ability to toggle button availability
6 // via its enableButton and disableButton link_message events.
7
8 // Copyright (C) 2005-2006 Francisco V. Saldana
9 //
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License
12 // as published by the Free Software Foundation; either version 2
13 // of the License, or (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 //
24 // Francisco V. Saldana can be contacted using his email account
25 // username: dressedinblue, at domain: gmail.com
26 // and in Second Life by IMming Christopher Omega
27
28
29 // Library functions:
30
31 // Replaces the list elements in dest with elements in src, starting at start.
32 // For example, if dest was [A, B, C, D], src was [E, F] and start was 1,
33 // the list returned would be [A, E, F, D].
34 // If llGetListLength(src) + start > llGetListLength(dest), the returned list length
35 // will be greater then dest list's length.
36
37 string NULL = "";
38 list replaceListSlice(list dest, list src, integer start)
39 {
40 if(llGetListEntryType(dest, start - 1) == TYPE_INVALID)
41 {
42 integer len;
43 for(len = llGetListLength(dest); len < start; len++)
44 {
45 dest += NULL;
46 }
47 }
48 integer srcLen = llGetListLength(src);
49 return llListInsertList(llDeleteSubList(dest, start, start + srcLen - 1), src, start);
50 }
51
52 integer wildcardPatternMatches(string str, string pattern)
53 {
54 string firstChar = llGetSubString(pattern, 0, 0);
55 string lastChar = llGetSubString(pattern, -1, -1);
56
57 if(firstChar == "%")
58 {
59 if(lastChar == "%")
60 {
61 pattern = llGetSubString(pattern, 1, -2);
62 return llSubStringIndex(str, pattern) != -1;
63 }
64
65 else
66 {
67 pattern = llDeleteSubString(pattern, 0, 0);
68 return llSubStringIndex(str, pattern) == llStringLength(str) - llStringLength(pattern);
69 }
70 }
71
72 else if(lastChar == "%")
73 {
74 pattern = llGetSubString(pattern, 0, -2);
75 return llSubStringIndex(str, pattern) == 0;
76 }
77
78 else
79 {
80 return str == pattern;
81 }
82 }
83
84 list enabledButtonNamePatterns = [];
85 integer numPatterns = 0;
86
87 integer isEnabled(string buttonName)
88 {
89 integer patternIndex = 0;
90
91 for (patternIndex = 0; patternIndex < numPatterns; patternIndex++)
92 {
93 string pattern = llList2String(enabledButtonNamePatterns, patternIndex);
94 if(wildcardPatternMatches(buttonName, pattern))
95 {
96 return TRUE;
97 }
98 }
99 return FALSE;
100 }
101
102 // ============ llDetected* Related ============
103 integer DETECTED_KEY = 1002;
104 integer DETECTED_LINK_NUMBER = 1003;
105 integer DETECTED_NAME = 1004;
106 integer DETECTED_POS = 1006;
107 integer DETECTED_ROT = 1007;
108
109 list collectDetectedData(integer toucher)
110 {
111 return [
112 DETECTED_KEY, llDetectedKey(toucher),
113 DETECTED_LINK_NUMBER, llDetectedLinkNumber(toucher),
114 DETECTED_NAME, llDetectedName(toucher),
115 DETECTED_POS, llDetectedPos(toucher),
116 DETECTED_ROT, llDetectedRot(toucher)
117 ];
118 }
119 // =============================================
120
121 list curFilter = [];
122
123 // This function must be executed in a touch_start event.
124 // it compares values in the curFilter list with values
125 // from the llDetected* functions, to see if the toucher is not
126 // filtered.
127 integer isTouchAllowed(integer toucher)
128 {
129 if(curFilter == [])
130 {
131 return TRUE;
132 }
133
134 integer filterIndex;
135
136 filterIndex = llListFindList(curFilter, [(string) DETECTED_KEY]);
137 if(filterIndex != -1)
138 {
139 if(llList2String(curFilter, filterIndex + 1) != (string) llDetectedKey(toucher))
140 return FALSE;
141 }
142
143 filterIndex = llListFindList(curFilter, [(string) DETECTED_NAME]);
144 if(filterIndex != -1)
145 {
146 if(llList2String(curFilter, filterIndex + 1) != (string) llDetectedName(toucher))
147 return FALSE;
148 }
149
150 return TRUE;
151 }
152
153 // ========== For method invocation ==========
154 string randomStr(string chars, integer len)
155 {
156 integer numChars = llStringLength(chars);
157 string ret;
158 integer i;
159 for (i = 0; i < len; i++)
160 {
161 integer randIndex = llFloor(llFrand(numChars));
162 ret += llGetSubString(chars, randIndex, randIndex);
163 }
164 return ret;
165 }
166
167 string SEPERATOR_CHARS = "`~!@#$%^&*()-_+[]{}|'";/?.>,<";
168 integer SEPERATOR_LEN = 3;
169 string dumpList2String(list src)
170 {
171 // Generate a seperator not present in any of the
172 // elements in the list.
173 string chars = (string) src; // Squashes all elements together.
174 string seperator;
175 do
176 {
177 seperator = randomStr(SEPERATOR_CHARS, SEPERATOR_LEN);
178 }
179 while(llSubStringIndex(chars, seperator) != -1);
180 return seperator + llDumpList2String(src, seperator);
181 }
182
183 list parseStringKeepNulls(string src)
184 {
185 // The seperator should be the first SEPERATOR_LEN
186 // characters in the string.
187 return llParseStringKeepNulls(llDeleteSubString(src, 0, SEPERATOR_LEN - 1),
188 [llGetSubString(src, 0, SEPERATOR_LEN - 1)], []);
189 }
190
191 callMethod(integer callId, string methodName, list parameters)
192 {
194 dumpList2String(parameters), methodName);
195 }
196
197 returnValue(string methodName, integer methodIdentifyer, list value)
198 {
199 llMessageLinked(LINK_THIS, methodIdentifyer,
200 dumpList2String(value), methodName + "_ret");
201 }
202 // =============================================
203
204 trigger_buttonPressed(string buttonName, list detectedData)
205 {
206 callMethod(0, "buttonPressed", [buttonName, dumpList2String(detectedData)]);
207 }
208
209 trigger_buttonReleased(string buttonName, list detectedData)
210 {
211 callMethod(0, "buttonReleased", [buttonName, dumpList2String(detectedData)]);
212 }
213
214 trigger_reregisterButtons()
215 {
216 callMethod(0, "reregisterButtons", []);
217 }
218
219 trigger_pong(string moduleName)
220 {
221 callMethod(0, "pong", [moduleName]);
222 }
223
224 string this;
225 default
226 {
228 {
229 this = llGetScriptName();
230 trigger_reregisterButtons();
232 }
233
234 link_message(integer sender, integer num, string parameters, key methodName)
235 {
236 if(methodName == "addButtonListener")
237 {
238 list paramList = parseStringKeepNulls(parameters);
239 // addButtonListener(string buttonNamePattern)
240 string buttonNamePattern = llList2String(paramList, 0);
241
242 if(llListFindList(enabledButtonNamePatterns, [buttonNamePattern]) == -1)
243 {
244 enabledButtonNamePatterns += buttonNamePattern;
245 numPatterns = llGetListLength(enabledButtonNamePatterns);
246 }
247
248 }
249
250 else if(methodName == "removeButtonListener")
251 {
252 list paramList = parseStringKeepNulls(parameters);
253 // removeButtonListener(string buttonNamePattern)
254 string buttonNamePattern = llList2String(paramList, 0);
255 integer patternIndex = llListFindList(enabledButtonNamePatterns, [buttonNamePattern]);
256
257 if(patternIndex != -1)
258 {
259 enabledButtonNamePatterns = llDeleteSubList(enabledButtonNamePatterns, patternIndex, patternIndex);
260 numPatterns = llGetListLength(enabledButtonNamePatterns);
261 }
262 }
263
264 else if(methodName == "touchFilter")
265 {
266 list paramList = parseStringKeepNulls(parameters);
267 // Method signature:
268 // touchFilter(list rules)
269 // Rules is a list of DETECTED_* values that we
270 // use to filter touch_start events.
271 list rules = parseStringKeepNulls(llList2String(paramList, 0));
272 curFilter = rules;
273 }
274
275 else if(methodName == "ping")
276 {
277 list paramList = parseStringKeepNulls(parameters);
278 // Method signature:
279 // ping(string moduleName)
280 string moduleName = llList2String(paramList, 0);
281 if(moduleName == this)
282 trigger_pong(this);
283 }
284 }
285
286 touch_start(integer total_number)
287 {
288 // In case of griefers who spam touch a button to try and make the terminal
289 // ignore the user, search through the list of touchers until the script finds
290 // one that the touchfilter will accept.
291 integer i;
292 for(i = 0; i < total_number; i++)
293 {
294 if(isTouchAllowed(i))
295 {
296 integer linkNumber = llDetectedLinkNumber(i);
297 string linkName = llGetLinkName(linkNumber);
298
299 if(isEnabled(linkName))
300 {
301 trigger_buttonPressed(linkName, collectDetectedData(i));
302 }
303 return;
304 }
305 }
306 }
307
308 touch_end(integer total_number)
309 {
310 integer i;
311 for(i = 0; i < total_number; i++)
312 {
313 if(isTouchAllowed(i))
314 {
315 integer linkNumber = llDetectedLinkNumber(i);
316 string linkName = llGetLinkName(linkNumber);
317
318 if(isEnabled(linkName))
319 {
320 trigger_buttonReleased(linkName, collectDetectedData(i));
321 }
322 return;
323 }
324 }
325 }
326 } // end

Back to the Best Free Tools in Second Life and OpenSim.