Jump to content

Very Keynes

Resident
  • Posts

    19
  • Joined

  • Last visited

Reputation

1 Neutral

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. You may find the DBMS System I created back in 2008 useful in your application. It allows you to do things like this: string table = "guests";list columns = ["name", "duration"];table = dbCreate( table, columns );llSay(0, "using Table " + table); The documentation is here: https://docs.google.com/document/pub?id=1VTy2MiJBfPyebKzDAbNNVcAbfIr_F9Wn8ijHVnRP_lk and the code is in the old archived library here: https://www.google.co.za/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CDgQFjAB&url=http%3A%2F%2Fforums-archive.secondlife.com%2F54%2F4a%2F290413%2F1.html&ei=IjHlUM7FKtO7hAflj4HwBA&usg=AFQjCNEz2ULNFM62Iw9ly7LWctqONBkrQw&bvm=bv.1355534169,d.ZG4&cad=rjt or publicly posted and easy to read here: http://www.free-lsl-scripts.com/cgi/freescripts.plx?ID=1542 I have more up to date versions of the code that include datetime functions, key compression and matrix access, but with the demise of the old LSL Library I gave up on posting updates. Call me in world if the base code helps and you are interested in the updates. Cheers V
  2. Then the following snippets should do it for you: Sended --> llReginSay(NetCh, llList2CSV( [ llGetPos(), llGetRot() ])); Reciver: listen(integer channel, string name, key id, string message) { llMessageLinked(LINK_THIS, 0, message, id); } Linked Script: link_message(integer sender_number, integer number, string message, key id) { list data = llCSV2List(message); vector pos = llList2Vector(data, 0); rotation rot = llList2Rot(data, 1); key sender = id; } you could also use the same chain to get the data into the HUD.
  3. You could just use llCSV2List if the message is comma separated, it is faster and more memory efficient and it properly preserves vectors and rotations. To really know if you have the correct parser set up we would need to see an example of the string it has to parse. Cheers V
  4. The OP's Function has a couple of things that the replys have overlooked. The first is that it returns a real Boolean result that equates to the TRUE and FALSE constants of LSL the ~ opperator does not. This can be very important when you are manipulating several flags in a single integer or any other form of bitwise function. It also has a serious failing in that it can only find a String in the Target List which limits its usability. The equivalent function that I have used for the past few years is: integer inList(list data, list find){return !!~llListFindList(data, find);} It still returns a real Boolean result and has the advantage that any data type can be found. The disadvantage is that the "find" parameter must be cast to a list by using (list)find or [find] in the calling statement. If you are using the preprocessor in the 3rd party Viewers (Only tested with Phoenix / Firestorm) then you can use: #define inList(a,b) (!!~llListFindList(a, )) It has the advantage of being able to find any data type in the list without having to cast find, it still returns a proper TRUE/FALSE (1/0) result, uses less memory, is faster and can be included in the code but will only be compiled if and when it is used. Cheers V
  5. I am not sure what error you got so I tried it out with an alt to see how it would work for a new install. Here then is how to set it up and test it for those who wish to try it: You can set it up from the login page or when you are already logged in. Setting the options: From the Login page Select;: Viewer --> Preferences If you are logged in Select : Avatar --> Preferences Next select : Firestorm --> Build Tick the Box: Enable LSL preprocessor The others are up to you but I highly recommend Script optimizer be ticked. Testing: To test the Example library, create an inventory folder for Scripts if you don't already have one. Create a Subfolder for libraries, call them whatever you wish In the libraries subfolder create a new script and rename it to vk_timers open vk_timers and paste the library code from the first post in this thread. Press save. You will get an error (is that the error you saw Alicia?) which is to be expected as the library is not a complete LSL script. Ignore it and close the window. Drop back down to your Scripts folder and create a new script (in a sub folder if you wish). Call it anything you like but paste the example code from the first post of this thread. Hit save and this time it should compile without errors. Create a prim and drag the script into it, it should start chatting the test messages. If you open the script and look at the Preprocessed tab you can see how the two Files have been merged into one. Note in particular (if you selected the Script optimizer option) that only the code actually needed has been merged not the entire library. Taking it further: One of the options was: #includes from local disk If you select that and create a path on you local PC to save Library in, you can eliminate the Error seen above as there is no need to create the library scripts with the built in editor. Just save your library files into that folder as simple text files and they will be read by the preprocessor whenever you create a new script. That includes Creating new scripts in Objects as well as in Inventory. I have my Libraries folder under C:\LSLEditor\Libraries but you can create it anywhere you like. I hope that helps others to try it out, it really is worth the effort, Cheers V
  6. Thanks Innula, I have been using version 2.40 and when I use "Check for update..." in the Help Menu it reporst that as the current version. I bet I am not the only person that is 6 releases behind the current version if the Update button is broken. Thanks for the link, I am now up to date again. Cheers V
  7. Yes, I have had that problem myself, editing the wrong listing, but I think the benefits far out weigh that problem. I tend to do all my editing in LSLEditor anyway, which is now so out of date I can nolonger rely on the syntax checker, but these are two powerful user supported tools that combined overcome many issues in the official editor that we have learnt to live with for the past 6 years or more. I think we are likely to see the minor problems in the phoenix editor and the LSLEditor get fixed a lot sooner than we will see the official editor gain anywhere near the functionality and features offered by the community versions. One of the really interesting aspects of the preprocessor, that may contribute to the difficulty of cross referencing the source script, is the optimisation. It only includes lines of code from both the library file and the source that are actually used. In the example I gave the library provides for 8 Timers and several utility functions but if only 4 timers are used it will only generate code for 4 and if the utility functions are not used, no code will be generated for them. Combine that with the fact that you can properly define constants, rather than having to assign them to variables, and you get incredible memory savings over code generated by the native Official LSL editor. So yes, its a pain, but the incentive to use it, and maybe reread the source a few times before hitting the save button, beats anything LL have given us since day one in terms of the all important editor interface. Cheers V [Edited to correct the spelling of the Spell Check Function]
  8. I have seen very little written about the LSL preprocessor in Phoenix / Firestorm browsers apart from a mention in the Firestorm Release notes and the WIKI entry here: http://wiki.secondlife.com/wiki/User:Toy_Wylie/Phoenix/Preprocessor So I decided to give it a try for myself. My conclusion, after only playing with it for a short while, is WOW how did we ever live without it. I think we need to push LL to include it in the official viewer, it is the best thing to happen for LSL development since the release of MONO. You can use the WIKI entry above to read more about it but I decided to create an example to show it at work and, hopefully, provide a small library that others may find useful. Several people have posted multiple timer implementations and whilst all effective, they can be difficult to understand and use for the less experienced LSL Scripters. Here I present my take on Multiple timers but using the power of the preprocessor to not only make it easier to use but also add the ability to trigger any user defined function that the scripter wishes, rather than a single event. Here is an example of a script using the “vk_timers.lsl” library : // // Initialise the Library // #define MaxTimers 4 // The number of timers you wish to create (maximum is 8) #define TimeBase 1.0 // The tick rate in seconds (or fractions of if desierd) // // define the Functions to be called by each timer // #define timer1 ATask(); // can be any fuction name you desire #define timer2 AnotherTask(); // can be any fuction name you desire #define timer3 YetAnotherTask(); // can be any fuction name you desire #define timer4 AndAnotherTask(); // can be any fuction name you desire // // inclde the library itself // #include "vk_timers.lsl" // // Everything up to this pont could go into a header file // and replaced with a single line: // // #include "Timers.h" // //----------------------------------------------------------------------------- // create the Actual functions you named above // the order and placement is not important //----------------------------------------------------------------------------- ATask() { llSay(0, "Task 1 triggerd and will not repeat"); } //----------------------------------------------------------------------------- AnotherTask() { llSay(0, "Task 2 triggerd and will repeat in "+(string)RemainingTime(2)+" seconds"); } //----------------------------------------------------------------------------- YetAnotherTask() { llSay(0, "30 seconds is up"); } //----------------------------------------------------------------------------- AndAnotherTask() { llSay(0, "tick"); } //----------------------------------------------------------------------------- // write the rest of your code //----------------------------------------------------------------------------- default { //----------------------------------------------------------------------------- state_entry() { // Setup the timers using SetTimer(Timer Number, Number of Ticks, Repeat?); SetTimer(1, 15, FALSE); // Timer 1 is a single shot SetTimer(2, 10, TRUE); // Timer 2 will repeat every 10 seconds SetTimer(3, 30, FALSE); // SetTimer(4, 60, TRUE); // // When ready Start the timers StartTimers(); } //----------------------------------------------------------------------------- timer() { vkTimers(MaxTimers); // // Statements that need to execute every tick can go here // } //----------------------------------------------------------------------------- } and here is the Library itself: #ifndef VK_TIMERS #define VK_TIMERS //_____________________________________________________________________________ // // Author: Very Keynes // Script: vk_timers.lsl // Version: 1.0 // Created: 2012-09-28 // Modified: //----------------------------------------------------------------------------- // Description: // //_____________________________________________________________________________ // list vk_timers; //----------------------------------------------------------------------------- StartTimers(){llSetTimerEvent(TimeBase);} StopTimers(){llSetTimerEvent(0.0);} //----------------------------------------------------------------------------- SetTimer(integer num, integer val, integer repeat) { if(repeat)vk_timers = llListReplaceList(vk_timers, [val, val], num *= 2, num + 1); else vk_timers = llListReplaceList(vk_timers, [val, -1], num *= 2, num + 1); } //----------------------------------------------------------------------------- StopTimer(integer num) { vk_timers = llListReplaceList(vk_timers, [-1, -1], num *= 2, num + 1); } //----------------------------------------------------------------------------- integer RemainingTime(integer num) { return llList2Integer(vk_timers, (num - 1) * 2); } //----------------------------------------------------------------------------- DoTimer(integer x) { if(0 == x){return;} // // This is where the real majic happens // #ifdef timer1 else if(1 == x){timer1} #endif // #ifdef timer2 else if(2 == x){timer2} #endif // #ifdef timer3 else if(3 == x){timer3} #endif // #ifdef timer4 else if(4 == x){timer4} #endif // #ifdef timer5 else if(5 == x){timer5} #endif // #ifdef timer6 else if(6 == x){timer6} #endif // #ifdef timer7 else if(7 == x){timer7} #endif // #ifdef timer8 else if(8 == x){timer8} #endif // } //----------------------------------------------------------------------------- vkTimers(integer x) { integer y; integer z; for(x = 0; x < MaxTimers; x++) { y = x * 2; z = llList2Integer(vk_timers, y); if(z > 0)vk_timers = llListReplaceList(vk_timers, [z - 1], y, y); else if(z == 0) { vk_timers = llListReplaceList(vk_timers, [llList2Integer(vk_timers, (y) + 1)], y, y); DoTimer(x + 1); } } } //_____________________________________________________________________________ // #endif //VK_TIMERS Try it, using the Preprocessor will change the way you think about LSL development, and I hope you find my example library useful too :) [edit] I have posted instructions on how to setup and test this in another message later in the thread. Cheers V [edited for spelling]
  9. Here is an alternative version based on the Region Corner. Despite the risk of the value changing I may use it to eliminate the HTTP: calls. I wonder if a CHANGED_REGION event would trigger if the Region Corner changes. //_______________________________________________________________________________________________//// Script name : NetListen.lsl// Created by : Very Keynes - 2012/09/26// Version : 2.0// Modified ://_______________________________________________________________________________________________//integer DEBUG = TRUE;integer NetCh; // Network Interfaceinteger NetHd;integer GetCh(key id){return ((integer)("0x"+llGetSubString((string)id,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;}key Region(){vector z = llGetRegionCorner();return (key)((string)(z.x/256 + 100*z.y));}//_______________________________________________________________________________________________//default{ state_entry() { NetHd = llListen(NetCh = GetCh(Region()), "", NULL_KEY, ""); if(DEBUG)llOwnerSay((string)NetCh); } listen(integer channel, string name, key id, string message) { }}
  10. Thanks Qie, The reason is to generate a Listener that is unique to my objects in a region. The intention being that if an object is rezed it can register itself with a central Directory service for the region on on a broadcast channel. The Directory Service can then route any incoming Messages to the appropriate device using a chanel derived from the object key. The intention is to reduce the number of open listens, URLs and other comms resources within the region but allow inter region comms for all objects. I did consider a hash of the name or the co-ordinates but rejected it for the reasons you mentioned. I would also prefer to just use the one function, that derives the channel from a key, to generate all listeners. Here is what I am using so far, I just don't like relying on external services that could disappear at any time and so break my products. //_______________________________________________________________________________________________//// Script name : NetListen.lsl// Created by : Very Keynes - 2012/09/26// Version : 1.0// Modified ://_______________________________________________________________________________________________//integer NetCh; // Network Interfaceinteger NetHd;key requestID;integer GetCh(key id){return ((integer)("0x"+llGetSubString((string)id,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;}//_______________________________________________________________________________________________//default{ state_entry() { requestID = llHTTPRequest ( "http://api.gridsurvey.com/simquery.php", [HTTP_METHOD, "POST",HTTP_MIMETYPE,"application/x-www-form-urlencoded"], "region="+llEscapeURL(llGetRegionName())+"&item=region_uuid" ); } http_response(key req_id, integer status, list meta, string body) { if (req_id == requestID) { if(llGetSubString(body, 0, 4)=="Error"){llSleep(0.5);llResetScript();} else NetHd = llListen(NetCh = GetCh(body), "", NULL_KEY, ""); } llOwnerSay((string)NetCh); }} Cheers V [EDIT] Spelling
  11. Hi All, Is anyone aware of a workaround or hack to obtain the Key for the Region that the Object containing the script is in? I would prefer not to use external services such as "api.gridservey.com". It seams strange that the only key not directly accessable is the region key when so many functions are region based. LL must have their reasons but I can't think why they would want to hide it. Cheers V
×
×
  • Create New...