Jump to content

I know this has been asked before... Own Function Libraries...


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

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

Recommended Posts

If I have a set of my own functions which I use a lot, do they have to be copied into Every script I write for an object, or is there a way for one script to call a function in another script, or some sort of cool hack (please please please please)

(Otherwise, if I update or change a function, all the scripts need to be changed too, and this can FATTEN horribly etc etc)

 

ty

 

  • Like 1
Link to post
Share on other sites

The only way to do that is to use the usual means of communication - which in this case would most likely be llSay (or llWhisper, or llShout ..) if the scripts are in different objects or llMessageLinked of they are im one. I'm afraid, that's abourt all.

  • Like 1
Link to post
Share on other sites

Hi Domitan,

Yes it is possible to create your own function libraries by using the Prim "Description" field hack.

When Script A calls a function in Script B, it first issues a Linked Message command.  After Script A has issued the command, then sits in a Loop polling the Description field.  Script B will process the message, executes the required command, and the output passed via the Description field.  Script A notices a change in the Description filed, processes the information, and returns the result.

Ok, it won't be the fastest or neatest way, but it works!

You can download the LSL Library Function System from the Marketplace (free of charge), which demostrates this technique.

https://marketplace.secondlife.com/p/LSL-Library-Function-System-Powerful-set-of-functions-to-make-scripting-easier/354418

Have fun.

Link to post
Share on other sites

 


Pavcules Superior wrote:

Yes it is possible to create your own function libraries by using the Prim "Description" field hack.

No offense, but isn't this a somewhat overly-complicated way to send strings from one script to another? Why not just use the built in link message functionality?

 

Link to post
Share on other sites

Hmmm..... Thanks.

So passing complex sets of args, lists and keys and things is Slow and Clunky. 

Thanks, but this is not remotely what I had in mind... either #include or a way to call functions directly in another script.

LSL is really the swiss cheese of programming languages, I think, truly typical of Linden   :smileytongue:

Link to post
Share on other sites

This isn;t exactly a function library, but it acts like one sort of.  Script A doesn't ever know that happens in script B. It simply passes a value to the Description field and gets one back when it senses that the field has changed again. You could swap out different versions of script B without ever having to mess with script A. This could be handy if, for example, you wanted to make script A no mod but let your end user create custom versions of script B.

Link to post
Share on other sites

That is technically correct Rolig, but again - why not just use link messages?

The only real advantage I see here is that the data remains readable for an extended period of time instead of being an instant broadcast that can be missed while a script is missing from the contents.

Link to post
Share on other sites

 


CrystalShard Foo wrote:


Pavcules Superior wrote:

Yes it is possible to create your own function libraries by using the Prim "Description" field hack.

No offense, but isn't this a somewhat overly-complicated way to send strings from one script to another? Why not just use the built in link message functionality?

 

depends on if you need the value return in the current event or not.... if you do, then it (or similar) is the only way to go... (think secondary event processed llMapDestination for public use) otherwise, yeah it's much easier to treat a link request as an asynchronous (or daisy chained) data query...   of ya know, just paste in the function. =)

 

honestly I do not recomment trying to use these methods in LSL.... they take up more scripts, more time, and are more prone to failures (mostly due to complexity).... Object Oriented Programming really isn't very suited for an Event Driven scripting language, at least not at this scale.

there ARE two viewers that have preprocessors.... Imprudence, and Phoenix. both of those have stopped development, but Firestorm (the oh so uncreatively named v2 version of phoenix) will most likely include it again as well.

Link to post
Share on other sites

Unfortunately, LSL isn't a full programming language......it's simply a scripting language, and it's functionality is limited to what LL decides to expose, as well as the event-driven nature of the design.

 

#include would be nice, however it has its own problems....LSL isn't an optimizing compiler....so any functions you '#include'd would always appear in the resulting compiled code, even if they were never called in the script.  So a large library would typically eat up memory while only providing a very few functions that get used.

 

I try to keep a 'library' file of useful routines on my personal box, and when I need one of those functions in a script, I C&P it into it.  Keeps things from getting bloated.  I also occasionally go through those functions to try to optimize them as much as possible (both from memory usage and speed).

 

There are considerably more pressing issues concerning LSL, even in my mind......I'd still like to see a 'llDialogOrdinal() ' function that returns the INDEX of the button pressed, and not its text.  Numeric comparisons are a LOT more efficient than string comparisons unless you carefully choose your strings (which isn't always an option.)

 

It is possible to put together a 'library' script with useful functions that can be called via chats or link messages with a well-defined API so that you could just drop that script into the object, and write your other code to send and receive the data for the functions......but it wouldn't be synchronous, as others have mentioned.

 

Link to post
Share on other sites

'include' was one of the reasons I changed to using eclipse for my off-world editing.  What I hadn't realised is that as well as 'just' including the referenced file it can then attempt to optimise the result - constant folding, inlining functions, etc.  I'm not totally happy with the results of using this, but it's nice to know it's there :-)

Link to post
Share on other sites

functions may not always be the best candidates for includes unless they are all interdependant or large things that can't be inlined well, but #define macros can be a blessing for some things....

for instance I can never remember the overflow value for posJump, which is a bit of code with no return value, so very safe for a macro, which I write as:

 

 #define uWarp2( x ) llSetLinkPrimitiveParamsFast( !!llGetLinkNumber(), [PRIM_POSITION, <1.304382E+19, 1.304382E+19, 0.0>, PRIM_POSITION, x] ) /*//-- Warp 3, sir? No, that will be way too slow" - Weird Al --//*/

(and yes I know it can be optimized to use a static link number but this avoids problems if the obect is de/re/linked)

 

similarly I've defined ALL the event headers with my own custom variable names, so now I just type the event name and () and poof, no more typing out those stupid type definitions either =) (how many times do we have to type out event headers for listens and link messages before we desperatley crave that?)

 

  • Like 1
Link to post
Share on other sites

Yes, looks like all the techniques are marginally acceptable for "services" but not really for functions, e.g. a string manipulation library used 50 times on a single string etc...

I may look Eclipse, but cutting and pasting constantly from an Eclipse window into a script window doesn't really sound like fun, but might be worth it.

 

Thanks to all for the very interesting discussion!

 

-DR

 

Link to post
Share on other sites

I don't use eclipse, so I don't know.... but does it allow files to be saved as ".lsl"? if so then you can use the external editor function in imprudence, phoenix, or v2 to open the script inworld, and edit it in eclipse, and save it there, which updates back to SL

I havent tried v2's version of this, but I know the phoenix version locks the inword copy from being written to untl you close and reopen the script (although it does show the live changes)

Link to post
Share on other sites

 


CrystalShard Foo wrote:

 No offense, but isn't this a somewhat overly-complicated way to send strings from one script to another? Why not just use the built in link message functionality?

 

 

Sending information via Linked Messages is perfectly okay, and I use it all the time.  The LSL Library Function System shows the ability of calling functions from other scripts, but returns the function result on the line it is currently executing on.   So if you are running some code, but do not want to stop the flow of things, then the Description polling is currently the easiest way around the problem.

 

So, for example:    (CallFunction would be the function in the script to handle the data transfer via the Description)

string strValue = CallFunction("Text","ReverseString","Hello");    // Call ReverseString function in other script, and get the result.

llOwnerSay("Reversed: " + strValue);    // Output the result.

 

But, using the Linked Message appraoch, you would have a complicated setup.  You would have to fire the Linked Message, then wait for a Linked Message from the other script.  And then call another function / place code in the message event to carry on triggering the rest of the code, which would be very messy.

ReverseString()

{

llLinkedMessage(LINK_THIS,1234,"ReverseString=Hello",NULL_KEY);     // Send message to other script. and wait for linked message response.

}

state_entry()

{

    ReverseString();     // Start executing.

}

linked_message(...etc..)

{

  if(message=="ReverseStringResult")                // Message retrieved from other script.

  {

        strValue = ... Extracted Result.

       llOwnerSay("Reversed: " + strValue);    // Output the result.

       // Carry on executing the rest of the code, etc.

 }

}

 

 

 

 

 

Link to post
Share on other sites


Pavcules Superior wrote:

The LSL Library Function System shows the ability of calling functions from other scripts, but returns the function result on the line it is currently executing on.

... string strValue = CallFunction("Text","ReverseString","Hello");    // Call ReverseString function in other script, and get the result

I'm bemused and will have to actually read this suff now :-( There is NO way of calling a function in another script inline, end of story, so I have no clue what this does.  While you can encapsulate linked-messages in a function they will always be separate, asynchronous events.

Link to post
Share on other sites

Don't be so sure about that Peter ;)

string callFunction( string library, string action, string data ){
    llMessageLinked( LINK_THIS, 0, library, action+";"+data );
    while ("" == llGetObjectDesc());
data = llDeleteSubString( llGetObjectDesc(), 0, 0 );
llSetObjectDesc( "" );
    return data;
}

 

ETA:
for the record that's just an example written on the fly, but it tecnically returns the results inline to the caller.... after horrendous delay. the library script catches the link message, parses it, and throws the result back to the description so that the calling script never has to leave the current event context, and in fact never needs to leave the line.
       

Link to post
Share on other sites

Well, yeah - you can stall the script forever, but that's just party-tricks; a way to make it look inline while actually being a polling loop   What I mean is, it makes your code look good* but it's actually a **bleep**e way of programming.

(*looking good, ie; readable might be a good enough reason for doing it, but only if you don't care about the about functionality)

 

(Edit:  Hehe. I posted something different to " **bleep**e" but the software caught it!)

Link to post
Share on other sites

hey no one said it was particularly SANE.... but if you have a complex enough function, or a desperate need to remain in the same context it works

it's how we hacked llMapDestination to work with asynchronous data lookups (like llRequestInventoryData, and http, for things like stargates that can't use read ahead or pre loads)

ETA:
it's also how two major networks manage to pop up map destination when you collide with the event horizon, rather than when you touch the dialing device (although the touch is required)

Link to post
Share on other sites

Ugly and probably useless

 

The better way is to use the preprocessor of some alternative viewers to develop.

For the final distribution to the customers , the code preprocessed can be generated to work in any viewer.

To add the optimiser will remove the functions declared but not called . It s a thing impossible to do with the ugly trick in the precedent posts

 

 

 

The description of preprocessor is here

http://wiki.secondlife.com/w/index.php?title=User:Toy_Wylie/Phoenix/Preprocessor&diff=1033262&oldid=prev

chapter 5 Including files has one disadvantage though. You will get the complete contents of the file, if you need it or not. But the Phoenix LSL Preprocessor uses an optimizing technique, which only keeps the things you really used in your code and removes all global functions and variables you didn't reference in your script. This makes sure that your scripts don't get burdened with a lot of unused code. You can enable or disable this functionality in the script editor's "Advanced" menu.

 

 

Link to post
Share on other sites

It appears nobody is actually answering the OP's question hehe. Although I did like reading the responses... the OP is/was asking if you could use preprocessing run-time... not compile-time. You can't. Having scripts be able to communicate with each other is nice for having your script talk to a function library you also placed in the prim but doesn't address the OP's issue with the library changing and needing to be updated.

You have a few options but, in general, I'd have your objects check their version number vs a response given by a "server" you run and then do one of two things... tell the user they are out of date and send them a new copy of the object or quietly push the new scripts to the object and update it yourself. That is how most people "implement" function libraries/script updating given that there is no way to use preprocessor directives at run-time such as #include.

Link to post
Share on other sites
You are about to reply to a thread that has been inactive for 3737 days.

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...