Signed timers in LSL
tracked
Zi Ree
It would be great if we could have "signed" or "named" timers, so we can distinguish timer events from each other. So we could have:
llSetSignedTimerEvent(float timeout,integer signature)
signed_timer(integer signature)
{
}
or:
key llSetKeyedTimerEvent(float timeout)
llUpdateKeyedTimerEvent(key id, float timeout)
keyed_timer(key timer_key)
{
}
Whatever is easier to implement. Personally I would like the arbitrary signed timer best, with a limit of 8 or 16 simultaneous timers if needed.
Log In
Gwyneth Llewelyn
I'm still unsure if it's a good idea or not to have
several
timers per state
. For now, I'll reserve my vote on this, because I'm aware there are some subtleties regarding timers and, most importantly, events triggered by the dataserver, which may
spread across all
states, in all
scripts running on a linkset.In other words — I'm assuming that the purpose of having "signed" or "named" timers is to allow to keep track of different events that can potentially be triggered and hit the script at different times, without the hassle of switching states — and not knowing if the new state will catch the even at all. LSL has this peculiarity that you
can
register to catch events from several
sources, simultaneously, but you can only
set one
timer (per state — which is the same thing, as the LSL VM can only be on one state at the time).I would personally think that the most fun approach would be to allow the LSL VM to be in several states at the same time 😅 — each triggered by a different event, of course — and then you could stick to just one timer per state,
and it would work
. Alas, as mentioned below, LSL implements a finite-state machine (FSM), which requires that the script can only be in one
state (to the exclusion of all others). To implement "parallel states", or the ability to be in several different states at the same time
, the only option we got is to use multiple scripts — of course!It's arguable what would be best, then. I suppose that what LL had in mind was that you'd have a constellation of scripts, each just handling
one
event trigger, and pass linked messages among scripts in order to notify that some requested information has just arrived. However, this approach is by no means easy to debug; having your concept of "signed" timers would allow to coalesce the constellation of scripts into a single one, which makes debugging easier (and possibly also consumes far less memory & other resources).I actually don't quite get how exactly your proposal would work in practice, expressing something that cannot be accomplished today with, say, some sort of global variable (or many; or the KVP store) where you store some kind of reference to which timer events are supposed to be pending for several different (and concurrent!) event listeners. Granted, the one-timer-only-to-rule-them-all limitation means having a complex code sequence just to figure out if it's time already to act upon a timer having fired for a specific situation, it also means that currently you have to decide to implement, in advance, what
granularity
the timer needs to process — i.e. if it's fine to check every second for an expected response, or if you want to get the timer fired every fraction of a second (which will inevitability make the whole process orders of magnitude "heavier", so to speak) and check for multiples of that, depending on what is needed for the different events. There should be better ways of accomplishing that...Zi Ree
Gwyneth LlewelynYour last paragraph is exactly the reason for my proposal. All that complexity and maintenance nightmare would go away if we had timers that carried information about what function they are being used for. Similar to the key in a dataserver event, the channel on a listener event or the handler for at_target.
SamanthaTekcat Resident
I do think we need a new keyed_timer event, however we should have a function that includes the following:
key llSetKeyedTimerEvent(float seconds, integer repeat, float timeout)
llStopKeyedTimerEvent(key timer_key)
float seconds - Same function as llSetTimerEvent()
integer repeat - -1: repeats indefinitely, 0: Plays once and doesnt repeat, 0<n: number of repeats before it stops automatically
float timeout - when to force the timer to stop, ignoring the repeat specification.
WolfGang Senizen
Also ontop of this would be great to have JS style timeout aswell for a 1 time timer, though we could just cancel the timer itself by its sign manually I suppose.
But llSetSignedTimerDelay ... or something would be nice.
As allot of multitimer work is handline multiple "timeouts" at once.
Talia Tokugawa
I have this built into my prepro includes. I just call it a scheduling system. I add the current unix time to the interval I want then put that in a strided list with the event name, sort the list by time column get the next time code remove the unixtime from that set the next timer event.
Then in the timer event when it fires, check the list for anything < unix time, do the action then delete row 0, on repeat till the the item at the top of the list > unix time and then set the timer event = that time - unixtime.
((Or at least that is what I started with.. I have some extra options to increase precision. e.g. checking server TD and providing it with a margin of error. ;) ))
((Also not my original idea. It's a fork of Haravikk Mistral's scheduler https://wiki.secondlife.com/wiki/Scheduler ))
Zi Ree
Talia Tokugawa Yeah, that's just short interval timers, not as efficient as an actual signed/named/labeled timer.
Blaise Timtam
That would sure avoid the need for multiple scripts or a timer set to the shorter interval as i do
Spidey Linden
tracked
Issue tracked. We have no estimate when it may be implemented. Please see future updates here.
Extrude Ragu
It's a shame that LSL doesn't have the concept of a callback function. Being able to use a user defined function as a callback would be tidier than the inevitable
if (...)
{
...
} else if(...)
{
...
} else if(...)
{
...
}
that this is going to produce. That or a switch :p
Gwyneth Llewelyn
Extrude Ragu it's a shame that LSL is not... Lua :) Or JavaScript :) Or C# :)) Or [insert favourite programming language here]!
Jokes beside, LSL actually had a cool concept behind the overall language: it describes, for all purposes, a finite-state machine, something which computer science geeks love (but not necessarily computer
programmers
), since it is a well-studied field of CS, within the larger corpus of automata theory. In fact, if my knowledge doesn't fail me, LSL is probably the most used programming language for FSMs (not to be confused with the Flying Spaghetti Monster!), at least in terms of lines of code and actual implementation — but I bet L$50 that the top automata theory experts have never heard of it :)That said, it's arguable if a FSM is a good idea or not as an embedded language for a virtual world platform. One could definitely argue by saying "it's been around for twenty years, so it can't be
that
bad" — but that's a fallacy of age (or however it's called).FSMs are technically not as expressive as, say, Turing machines (which are the basis for
most
general-purpose languages), but the narrower scope of FSMs doesn't necessarily mean that they're "useless". It just means bending your mind around a problem and make it fit into a FSM :) instead of doing it the other way round, i.e., trying to turn a FSM in something it is not
.Personally, I used to find it rather amusing that
most
LSL scripts I've seen/read actually use few
(formal) states (i.e., those that are defined witj state XXX
); instead, they use variables to sort of figure out what pseudo-state the script is in, and everything goes into the default
state.When I
first
started writing some LSL, I totally went overboard with states; I believe that my earliest scripts would easily have five or six or sometimes even more, and happily switch among them, according to a very precise order. It might sound counter-intuitive, but you catch errors in your logic much faster doing things that way (and that's also a reason why, from a purely theoretical point of view, FSMs continue to have some purpose and are not merely a "theoretical exercise" to frustrate young programmers who just want to learn Java).These days, of course, I tend to stick to just a handful of states, like everybody else.
Having said that, in defense of LL's original choice of using a FSM instead of a Turing machine, I'd say that it would be easier for new users (those who never programmed before) to learn the basics. It would also be much easier to create a
visual
programming language that would convert nice little connected nodes in a graph into LSL — there were
some crazy guys who did exactly that, eons ago, but then stopped updating their software as LSL became more and more complex.On the flip side of the coin are the
real
programmers — those who effectively write most lines of LSL code by far — most of which would prefer that LSL became a dialect of Java, like every other programming language does, given enough time and a large user-base of professional programmers who push the core language developers to accept their
preferred language constructs, in the misguided belief that all programming languages should essentially become "Java done right". If you don't agree with me, just look at the language constructs that were piggy-backed on Perl, Basic, PHP, or even JavaScript itself... see how all they evolved and converged towards a mix of the main distinguishing features present in C++, Java, C#. (Others, like Rust, were designed from the start to become
those languages — just "done right".)I still think that Object-Oriented LISP or Object-Oriented Prolog are Abominations Upon The Eyes of the Lord :)
That said, I'd certainly love to have a built-in
switch
construct; the big question would be how exactly to implement it: old-style, as in Algol/Pascal/C (each case is just one possible variant of a variable's value), or contemporary-style, where each case can be any expression you want (that evaluates to true or false) — or something in-between.I'm pretty sure we would discuss until the end of time which approach would be best for LSL :) — and that's probably
one
of the reasons for not
having switch
as part of the syntax, although you can certainly use your favourite LSL pre-processor and do it in whatever style you prefer.Callbacks are another story. Even
functions
are borderline constructs for a "pure" FSM, since, technically speaking, functions use a stack (to pass parameters in and out), which is something you're not supposed to have on "pure" FSMs. Then again, I'm sure that nobody at LL will stand by the claim that LSL implements a "pure" FSM. That being said, the notion that an event is passed a callback is not that easy to implement in state machine: instead, you're supposed to switch to a different state as a response to an event.You might argue that this would lead to a horrible mess of uncountable states, with complex relationships among them, and making the code next-to-impossible to track — while having events trigger
callbacks
is much cleaner and more expressive.Congratulations,
now
you've understood why
there are few languages to define/implement/programme FSMs, and why professional programmers prefer easier-to-manage conceptual frameworks :)Note that I'm not disagreeing with you! I'm also not 100% convinced that implementing a FSM was a
good
idea in the first place — if it were, one would argue that all
embedded languages in virtual worlds would be FSMs, but that's not true — AFAIK, only LSL fits the bill, but I might be wrong. There are certainly some platforms out there which use LISP for their embedded language. Implementing FSMs in LISP is not only straightforward, it's a trivial exercise — the kind of thing that every CS student will have met along their studies, and promptly forgot. On the other hand, LSL is not
LISP (and I would argue that this would have made matters even worse
!...), and no, I'm certainly not
going to argue if it's better for the future of LSL (assuming there is
a future for it!) to resemble more and more LISP or JavaScript; given the choice between the two evils, I'd still favour a JavaScript dialect over a LISP one (don't get me wrong — I like LISP a lot, but I wouldn't love to use it inside SL, much less try to explain
how LISP works every time someone finds a bug with my code...).Extrude Ragu
This would be a nice feature, current workarounds often inadvertently end up being a source of bugs/debugging headaches in my scripts, and makes things difficult to maintain.
This would increase the maintainability of my scripts in general and make more complex ideas easier to implement.
Kadah Coba
Could call it "Multi-timers"