Jump to content

What is wrong!


Jennifer Boyle
 Share

Recommended Posts

For many years I have used this simple script to display the name, always of a single, unlinked prim, as hovertext:

default
{
    state_entry()
    {
        llSetText(llGetLinkName(0), <1.0,1.0,0.0>, 1);
        llResetScript();
    }
}

It worked perfectly for many years until some months ago. Now, the hovertext is always "00000000-0000-0000-0000-000000000000" instead of the name of the prim. I have read the documentation for llGetLinkName, but I can't figure it out.

Will someone who actually understands scripts tell me how to fix it, please.

Thanks.

Link to comment
Share on other sites

Link numbers are weird. If your link set has more than 1 prim, the first prim is not 0, but 1. Link 0 exists only in single-prim objects, so you're asking for the name of something that does not exist. Use LINK_THIS instead if you want something that is guaranteed to work.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

It will tell you the name of link #0 in the linkset.  If there's more than one link, there is no Link #0.  Links are numbered starting with #1 if there's more than one link.

EDIT"  Heh... What he said ^^

Edited by Rolig Loon
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

llResetScript(); << that throws the script into a reset loop when having it in the state_entry event.

Also if u want the name of the root prim to display just use llGetObjectName() instead

Edited by VenKellie
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I always use the script in a single prim, never in a linkset.

I changed it to use llGetObjectName and deleted the line with llResetScript, and now it works.

Thanks for the help, and please don't laugh too hard at me.

Edited by Jennifer Boyle
  • Like 1
Link to comment
Share on other sites

23 minutes ago, Jennifer Boyle said:

I always use the script in a single prim, never in a linkset.

I'll try llGetObjectName.

llGetLinkName returns "00000000-0000-0000-0000-000000000000" if the link number doesn't exist, so you must've mistakenly put it in a linkset.

It's mentioned by the wiki page: "If link is out of bounds, NULL_KEY is returned."

 

Also like VenKellie said, those two lines in your script cause an infinite loop in a pretty fierce way. I hope it's just a build-helper and you don't share objects with scripts like that in them.

A more gentle way to do the same thing would be something like:

default
{
    state_entry()
    {
        while (TRUE)
        {
            llSetText(llGetObjectName(), <1.0,1.0,0.0>, 1);
            llSleep(2);
        }
    }
}

...with as long of a sleep as you can deal with.

Edited by Wulfie Reanimator
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, Wulfie Reanimator said:

Also like VenKellie said, those two lines in your script cause an infinite loop in a pretty fierce way. I hope it's just a build-helper and you don't share objects with scripts like that in them.

I have never shared it. I use it to make it easier to keep up with what's in storage prims.

Link to comment
Share on other sites

Here i am speaking about teaching to write meaningful code.

The purpose of high level programming languages is to clearly describe an algorithm (the sequence of logic and action to solve a problem).

To clearly describe the actions needed to solve a problem.

while ( TRUE ) even technically efficient locally, is a kind of code obfuscation, a code that don't want to tell you what is doing.

Like: "Why?" "Because yes."

The conditions that should be tested (instead of TRUE) can be found asking the question:

"At which conditions this activity become useless or wasteful?"

This will make the code clear to understand and globally efficient.

 

  • Haha 1
Link to comment
Share on other sites

A timer event loop is restricted to maximum of 15/sec, a while loop can be up to 45/sec with llSLeep.

I don't see any issue with using while(TRUE) for a small effect in LSL -- understanding what the pitfalls of an endless loop are is important, of course. On top of that, the condition to end the loop is outside the script's control and access - the deletion of the containing object.

If while(TRUE) sounds too unclear, you could define integer UNTIL_DEREZZED = 1 and use that instead. :P 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

6 hours ago, 2Tessa said:

Here i am speaking about teaching to write meaningful code.

The purpose of high level programming languages is to clearly describe an algorithm (the sequence of logic and action to solve a problem).

To clearly describe the actions needed to solve a problem.

while ( TRUE ) even technically efficient locally, is a kind of code obfuscation, a code that don't want to tell you what is doing.

Like: "Why?" "Because yes."

The conditions that should be tested (instead of TRUE) can be found asking the question:

"At which conditions this activity become useless or wasteful?"

This will make the code clear to understand and globally efficient.

 

They didn't give us an unconditional loop in LSL. I guess you could use "jump".

Link to comment
Share on other sites

8 hours ago, 2Tessa said:

Here i am speaking about teaching to write meaningful code.

The purpose of high level programming languages is to clearly describe an algorithm (the sequence of logic and action to solve a problem).

To clearly describe the actions needed to solve a problem.

while ( TRUE ) even technically efficient locally, is a kind of code obfuscation, a code that don't want to tell you what is doing.

Like: "Why?" "Because yes."

The conditions that should be tested (instead of TRUE) can be found asking the question:

"At which conditions this activity become useless or wasteful?"

This will make the code clear to understand and globally efficient.

 

I think you're missing the forest for the trees.

The purpose is to automatically update the hovertext based on the name of the object. That's it.

There is no changed event, or other convenient way to do that without the user interacting with the object, so we need to check the name regularly.

There are two (apparently three) ways to do that. A timer, a loop, or resetting the script.

  • If we used a timer, that wouldn't be functionally any different from an infinite loop, since the script does literally nothing else. It's just extra typing, more events, and more complexity.
  • If we reset the script as soon as it starts, it's going to use more script-time than anything else, and it's basically an unthrottled/uncontrolled infinite loop. We could use a sleep here, but resetting the script for one function call is still overkill.
  • If we used a traditional while(true) loop, we can control each iteration, improve performance, reduce complexity, and cause no unnecessary events. It's three lines of code, there's no obfuscation, it's exactly fit-for-purpose and needs no exit-condition.

Can you come up with a condition for the loop? You're welcome to suggest one, but so far I haven't seen you do that.

Edited by Wulfie Reanimator
  • Like 2
Link to comment
Share on other sites

17 hours ago, Jennifer Boyle said:

I always use the script in a single prim, never in a linkset.

I changed it to use llGetObjectName and deleted the line with llResetScript, and now it works.

Thanks for the help, and please don't laugh too hard at me.

not laughing at all. totally understandable for someone new to lsl to make that mistake. I've made many over the years while learning the language.

  • Like 1
Link to comment
Share on other sites

On 1/22/2023 at 2:07 PM, Wulfie Reanimator said:

I think you're missing the forest for the trees.

The purpose is to automatically update the hovertext based on the name of the object. That's it.

My note is about the use of unconditional cycle. For educational purposes (newbies reading). Not this specific case.

On 1/22/2023 at 2:07 PM, Wulfie Reanimator said:

Can you come up with a condition for the loop? You're welcome to suggest one, but so far I haven't seen you do that.

You may use

if ( llGetRegionAgentCount() == 0 ) Sleep(60);  

while ( llGetRegionAgentCount() > 0 )

so the script takes longer pauses when the task is not needed.

Again, this is not about changing an hovertext but anything to be executed continuously.

 

Link to comment
Share on other sites

On 1/22/2023 at 9:07 PM, Wulfie Reanimator said:

If we used a traditional while(true) loop, we can control each iteration, improve performance, reduce complexity, and cause no unnecessary events. It's three lines of code, there's no obfuscation, it's exactly fit-for-purpose and needs no exit-condition.

One thing to be aware of, especially for newbie scripters, is that an unconditional loop without an exit inside an event handler blocks further event processing.

An event handler needs to finish first before another event handler (or the same one but responding to a different event) can fire.

This may or may not be a problem, but scripters need to be aware of this anyways.

 

  • Like 1
Link to comment
Share on other sites

If you ask me, while(TRUE) is very common practice and important for new programmers to learn, especially in the context of flow control language constructs such as return, stateor as @Love Zhaoyingalready suggested, jump.

Personally, I'm still haunted enough by that ol' time modular programming religion to be forever leery of jump, but LSL is not Pascal and while(TRUE) is the most obvious and elegant way to write many loops with non-local exits.

  • Like 3
Link to comment
Share on other sites

Ironically, in my big (Interpreter) scripting project I just figured out that using Jump to chain between functions is MUCH more efficient than calling each function: nothing gets added or removed from the call-stack, so no "context switching" is needed, and the last function in the chain (or any "failing" function) can Return. This ends the call chain, returning a value to the caller. 

Much, much more efficient. 

Qie, I don't remember problems with Pascal being modular. However, in about 1988-1989, I used Pascal exclusively in my first job. We figured out how to load (Turbo, pre-Borland) Pascal modules into "high memory" so they didn't need to load / reload / switch out. I guess before that, we had an issue with modules. Essentially, we treated "loading modules" like Windows much later treated DLL's with "LoadLibrary".

Being old is fun!

  • Like 1
Link to comment
Share on other sites

6 hours ago, Love Zhaoying said:

Ironically, in my big (Interpreter) scripting project I just figured out that using Jump to chain between functions is MUCH more efficient than calling each function: nothing gets added or removed from the call-stack, so no "context switching" is needed, and the last function in the chain (or any "failing" function) can Return. This ends the call chain, returning a value to the caller. 

Much, much more efficient.

You can't do that, that's illegal! (As in, you're not supposed to be able to do that in LSL.)

Sounds like yet another bug with the jump destination restrictions. 😄

Edited by Wulfie Reanimator
  • Thanks 1
Link to comment
Share on other sites

1 minute ago, Wulfie Reanimator said:

You can't do that, that's illegal! (As in, you're not supposed to be able to do that.)

Yeah, each of my "Function" entry-points is really just a top-level LSD entry (previously in-memory JSON). 

So, I can Jump to them, Call them, etc.

I had already added the ability to "jump" between these "entry points" because:  By splitting a "Function" up into "segments", only the currently loaded "segment" takes up actual memory.  Does a function seem to large? Split it into segments! Jump from one to the other. 

..the same works for jumping from one function to another, without any changes at all.  (Unless the jumped-to function has input parameters, of course.)

Link to comment
Share on other sites

5 hours ago, Love Zhaoying said:

Qie, I don't remember problems with Pascal being modular. However, in about 1988-1989, I used Pascal exclusively in my first job. We figured out how to load (Turbo, pre-Borland) Pascal modules into "high memory" so they didn't need to load / reload / switch out. I guess before that, we had an issue with modules. Essentially, we treated "loading modules" like Windows much later treated DLL's with "LoadLibrary".

Being old is fun!

Doh! It's "fun" until it makes me say "modular programming" when I meant "structured programming". Pascal was kind of the classical ideal of Structured Programming, a language designed from the ground up with block loop constructs from which it was considered impure to exit except from the bottom. That's in contrast to FORTRAN WATFIV-S, for example, that added those language constructs to its relatively unstructured forbearers.

  • Like 1
Link to comment
Share on other sites

20 minutes ago, Qie Niangao said:

Doh! It's "fun" until it makes me say "modular programming" when I meant "structured programming". Pascal was kind of the classical ideal of Structured Programming, a language designed from the ground up with block loop constructs from which it was considered impure to exit except from the bottom. That's in contrast to FORTRAN WATFIV-S, for example, that added those language constructs to its relatively unstructured forbearers.

I personally chose Pascal to use at that first job.

It's been a lot of years, though.

 CE92AFBD-6D24-4529-A5E2-3E50084F5D1E.jpeg.b3007e6c3a95630bc99b242feb315835.jpeg

  • Like 1
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...