Jump to content

Phoenix / Firestorm LSL Preprocessor - an example Library


Very Keynes
 Share

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

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

Recommended Posts

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]

 

  • Like 1
Link to comment
Share on other sites

I have been using the prerocessor since it came out in Phoenix. There was a period of time when Firestorm first came out but it did not have the preprocessor yet so I was unable to upgrade. I'm totally addicted to the preprocessor and can't script without it any more.

HOWEVER, it is not perfect. When the compiler detects a syntax error, it gives a line number in the expanded version. Clicking on the error will take you to that line in the expanded version, and the interface will even let you waste your time editing that version. I've been frustrated many times to discover that I have edited the wrong version and have to make my changes over again in the real source. And even if you remember to edit the unexpanded version after looking at the error, there is no easy way to find the same line in the source. Yes, I know that included lines will not be there in the main source, but when a line does appear in both of them, I can click on the error to see the bad line in the expanded version, but then I have to search for the same line in the source before I can fix it.

Link to comment
Share on other sites

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]

 

 

Link to comment
Share on other sites

I'm surprised to see you say LSLEditor is so badly out of date.  

I'm using LSLEditor 2.46, which was last updated at the end of April.  It's missing a few, very new, functions but I find the syntax checker perfectly adequate for most purposes. 

Thanks so much for making the example Library.  I've never been much of a fan of the Phoenix pre-preprocessor, both for the reasons already discussed and because I've never really seen the attraction of Phoenix, but now I think it's available in Firestorm, too, so I might well give it a try there.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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