Passing variables to states!
|
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
12-04-2003 05:41
Minnasan, konnichiwa! Idea!  Encapsulation withen LSL is one of the most difficult 'things' to accomplish, and therefore, it's a bit of a chore for people like me, who like to be object-oriented. I suggest that we be able to pass variables to states, just like we're able to pass variables to functions. For example: default { state_entry() { integer foo = computeBigThing(); llMessageLinked(LINK_SET,foo,"DO_SOMETHING",""); } link_message(integer s, integer n, string m, key id) { state process(n); } }
state process(integer n) { state_entry() { n = finishComputing(n); } touch_start { llSay(0,"Value of n == " + (string)n); } }
This is probobly a bad example of what this could accomplish, writing code in the morning is not my thing  So basicly, variables are passed to states much like they're passed to functions, declaring a state like this: state foo(vector bar) { } will cause the compiler to require you to pass bar to foo when you want to go into that state. You do this in the common state-change command: state foo(<0,1,20>  ; This system would allow the old way of changing states (without variables) yet allow state-specific variables *along* with a way to actually pass variables to states. With this implimented, scripters have more control of where variables exist in the script's memory, and an easier method of passing large amounts of data to specific places for only a limited amount of time, then clearing that memory completely, when the data isn't needed anymore. ==Kurisu Edit: Gah! Grammer != good;
|
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
01-04-2004 18:32
Bump... wow... I didnt know the idea was *that* bad... 
|
|
Azelda Garcia
Azelda Garcia
Join date: 3 Nov 2003
Posts: 819
|
01-04-2004 19:29
Just use modules and linkmessages.... ok, so the event paradigm is a little annoying (Xylor agrees with me on this cos I've seen his posting asking for a WaitForMessage function), but it really does work very nicely.
Fighting with states is a little like building a sandcastle when the tide is coming up...
Azelda
|
|
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
|
01-04-2004 19:35
You can do the same thing with a global var. And building sandcastles with the tide coming up is what i've done all my life. I built them for resilience, not looks. I actually managed to fend off the sea for quite some time. Fun fun fun.
|
|
Kex Godel
Master Slacker
Join date: 14 Nov 2003
Posts: 869
|
01-05-2004 07:30
I'm starting to think that states are a frivolous feature where we are essentially limited to about 8k of stack+heap space.
Just do your state change manually with a separate script for each "state", and pass data around with link messages.
If you don't know how large your project will grow, you'd be best off just getting this done from the beginning.
I don't see what the disadvantage is to this. You get more memory and a multithreaded program.
|
|
Michael Small
Addicted To Counseling
Join date: 22 Sep 2003
Posts: 123
|
01-05-2004 12:38
If you think of each state as an individual object, this idea is basically just constructors. something vb lacked until vb.net, and c++ was out in front on.
i second this idea. global variables are the devil's apprentice. goto is the devil.
|
|
Azelda Garcia
Azelda Garcia
Join date: 3 Nov 2003
Posts: 819
|
01-05-2004 12:50
> i second this idea. global variables are the devil's apprentice. goto is the devil. A COBOL fan I see 
|
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
01-05-2004 17:46
From: someone Originally posted by Kex Godel I'm starting to think that states are a frivolous feature where we are essentially limited to about 8k of stack+heap space.
Just do your state change manually with a separate script for each "state", and pass data around with link messages.
If you don't know how large your project will grow, you'd be best off just getting this done from the beginning.
I don't see what the disadvantage is to this. You get more memory and a multithreaded program. A seperate script for each state would be awfully hard to debug really, and the deal with link_message is that it isnt an actual synchronized variable. States do not limit you to 8k. I have a rather large and complex script that uses about 5 states, and at runtime, I have 10k of memory available, and that amount stays relatively constant. Its quite readable as well, since everything is consolidated in its own little box. Multithreading is good when you want to do two things at once, not doing two things that happen sequentially. ==Chris
|
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
01-05-2004 17:50
From: someone Originally posted by Michael Small If you think of each state as an individual object, this idea is basically just constructors. something vb lacked until vb.net, and c++ was out in front on.
i second this idea. global variables are the devil's apprentice. goto is the devil. Hehe, exactly what I was getting at. (Im currently learning Java, love the OO). If this is implimented along with my idea on functions switching states, I can see a whole new style of script development being created. <- Fellow global var hater 
|
|
Antagonistic Protagonist
Zeta
Join date: 29 Jun 2003
Posts: 467
|
01-05-2004 20:43
From: someone <- Fellow global var hater Most of the time I would agree with you ... but in LSL I don't see what the problem is with global variables. Tell me why they are a bad thing, in terms of LSL only. -AP
|
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
01-05-2004 22:14
From: someone Originally posted by Antagonistic Protagonist Most of the time I would agree with you ... but in LSL I don't see what the problem is with global variables.
Tell me why they are a bad thing, in terms of LSL only.
-AP Pretend this was the blank space over 'default': integer foo; // 8 bits of space gone. float goo; // n bits of space gone. rotation bar; // n * 4 bits of space gone. vector bargoo; // n * 3 bits of space gone. string foobar; // 1 bit of space gone. key foogoo; // 1 bit of space gone. Globals are auto-initilized, so they hold data no matter what, wether you need it or not, theyre there, looming... pushing the heap closer to the stack... desireing that precise moment when stack meets heap  With locals, theyre disposed of right after you exit the code bracket. All knowledge of the local variable is erased, and any space it took up is now free. Providing a middle-ground between having a variable be global then local helps the situation a bit, state specific variables and passing variables to states would provide this middle-ground.
|
|
Ama Omega
Lost Wanderer
Join date: 11 Dec 2002
Posts: 1,770
|
01-05-2004 22:28
From: someone integer foo; // 8 bits of space gone. float goo; // n bits of space gone. rotation bar; // n * 4 bits of space gone. vector bargoo; // n * 3 bits of space gone. string foobar; // 1 bit of space gone. key foogoo; // 1 bit of space gone. A pointer to memory in the heap is most definatly larger than 1 bit. If we can assume local addresing of a 16k space that means 2^14 spaces or 14 bits, but probably an even 2bytes. Also integers are more than 8bits, the range is somewhere in the billions which puts it (I think) in the 4 byte range (32 bits). Also I would bet that vectors and roations may have some extra meta data with them.
_____________________
-- 010000010110110101100001001000000100111101101101011001010110011101100001 --
|
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
01-05-2004 22:42
From: someone Originally posted by Ama Omega A pointer to memory in the heap is most definatly larger than 1 bit. If we can assume local addresing of a 16k space that means 2^14 spaces or 14 bits, but probably an even 2bytes. Also integers are more than 8bits, the range is somewhere in the billions which puts it (I think) in the 4 byte range (32 bits). Also I would bet that vectors and roations may have some extra meta data with them. Oops...  Well.. you get my point ne? 
|
|
Azelda Garcia
Azelda Garcia
Join date: 3 Nov 2003
Posts: 819
|
01-06-2004 03:37
> but in LSL I don't see what the problem is with global variables. Tell me why they are a bad thing, in terms of LSL only
I think I know what youre trying to say. In both C and LSL, you can treat a single scripting module as an object, and the variables in that module are the Properties of that object, and are encapsulated within that object.
As long as you make sure your scripting modules really do correspond to normalized objects, many variables really can be quite sensibly module-global.
This is how I program in C, to excellent effect, and it works equally well in LSL.
> Encapsulation withen LSL is one of the most difficult 'things' to accomplish, and therefore, it's a bit of a chore for people like me, who like to be object-oriented
states on the other hand have nothing to do with encapsulation, they are merely a concept that sounds like it should be good for games, but isn't as useful as it sounds in practice. Maybe I'm missing something here, and if someone wants to point out a book or resource providing the pragmatic benefits and uses of states, I'll be happy to look over it.
In my personal experience so far, using single-state LSL code results in more compact, easier to maintain code with vastly reduced code redundance and no event loss problems.
Azelda
Edit: I guess States could contribute to encapsulation. I guess there are two possible discussions here: - what is the most effective and efficient way to program in LSL today? - what is and should be possible in the distant future?
To the first question, which is the one that interests me, I'd answer: normalized scripting modules with linkmessages. You'll never see a stack-heap error in your life, except for maybe the odd database module. You'll never see the event loss that you get when switching states. You get AWESOME code re-use: just drop the modules you wnat in each object. YOu get multithreading. YOu get encapsulation. Frankly, you get a *lot*.
To the second question, well, I guess the honest answer is I dont have a strong opinion, but I have always favored small code modules because they are easy to maintain, debug, unit test, and re-use. States seem to promote the denormalization of code, which I dont see as a good thing.
If you want to improve the architecture in LSL, the following could be the main priorities:
- "include" and / or "import" - classes - synchronous function calls between modules (like Xylor's WaitForMessage thread)
|
|
Ama Omega
Lost Wanderer
Join date: 11 Dec 2002
Posts: 1,770
|
01-06-2004 06:28
From: someone - "include" and / or "import" - classes - synchronous function calls between modules (like Xylor's WaitForMessage thread) Yes! I don't know exactly how it would fit - just data structures would be nice though. I never really understood the need. In that order. I have asked for include or import since hm.... probably about feburary 2003. If you want the whole class type thing then just use modules. Erm, I guess what I mean is if you can import another script on an object then you have classes essentially. Well you can't instatiate an instance ... but we are dealing with a limited memory scripting language not a full fledged programming language. the waitformessage is why you do something people seem to forgetting in the 'classes or module' argument. You can do both, it shouldn't be an or. After programming in LSL for the past year that is the strategy I use and think is the best. Modular with states. If you are waiting for a message then you are in a wait state until you get the message and move to the right state. I do this all the time. All my arcade games have a minimum of 2 modules and multiple states in each. The best programming method is to use both - when each is appropriate. They are both different programming structures and concepts and they each have seperate places. Using modules instead of states isn't good coding and will be messy. Using states when you should be using modules isn't good coding. They each have different seperate uses. States allow you to know where you are, to be in exactly 1 place at any given time and to give that place a name. Modules allow you to divide up work and seperate different tasks. All implementations of modules for states I have seen are rather messy with lots of waits etc. States are much cleaner. And I have a very bad cold, can't sleep and my sinuses are so clogged my face actually hurts. So please forgive any mistakes.
_____________________
-- 010000010110110101100001001000000100111101101101011001010110011101100001 --
|
|
Bino Arbuckle
Registered User
Join date: 31 Dec 2002
Posts: 369
|
01-06-2004 11:50
From: someone Originally posted by Christopher Omega ...and at runtime, I have 10k of memory available, and that amount stays relatively constant... Didn't Ama point out that there is a bug in llGetFreeMemory() so it doesn't report the correct value? And on the rest of this thread, I have to agree that using states and modules together has worked best for me.
|
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
01-06-2004 14:37
Basicly, states are a quick, clean way of doing simplifying something like: integer gMadeMess = FALSE; integer gMootPointReturned = FALSE; integer gMoved = FALSE; integer gGotData = FALSE;
string gData
default { state_entry() { } link_message(integer s, integer c, string m, key id) { if(id == "MESS_TRUE) gMadeMess = TRUE; if( id == "RET_FOO_BAR") { gMootPointReturned = TRUE; gData = m; } if(id == "PROCESS_DATA") { if(gMadeMess && gMootPointReturned) { if(gData != "") { doComplexThingWith(gData); } else { llSay(0,"Erk! Error! Data sequence out-of-order!"); } } else llSay(0,"FATAL: Process request made with null arguments."); } } }
Gah, g2g, plus, writing this chaned if() thing is kind of sickening... From: someone Originally posted by Ama Omega Yes! I don't know exactly how it would fit - just data structures would be nice though. I never really understood the need. In that order.
I have asked for include or import since hm.... probably about feburary 2003.
If you want the whole class type thing then just use modules. Erm, I guess what I mean is if you can import another script on an object then you have classes essentially. Well you can't instatiate an instance ... but we are dealing with a limited memory scripting language not a full fledged programming language.
the waitformessage is why you do something people seem to forgetting in the 'classes or module' argument. You can do both, it shouldn't be an or. After programming in LSL for the past year that is the strategy I use and think is the best. Modular with states. If you are waiting for a message then you are in a wait state until you get the message and move to the right state. I do this all the time. All my arcade games have a minimum of 2 modules and multiple states in each. The best programming method is to use both - when each is appropriate. They are both different programming structures and concepts and they each have seperate places.
Using modules instead of states isn't good coding and will be messy. Using states when you should be using modules isn't good coding. They each have different seperate uses. States allow you to know where you are, to be in exactly 1 place at any given time and to give that place a name. Modules allow you to divide up work and seperate different tasks. All implementations of modules for states I have seen are rather messy with lots of waits etc. States are much cleaner.
And I have a very bad cold, can't sleep and my sinuses are so clogged my face actually hurts. So please forgive any mistakes.
|
|
ixO Baskerville
Member
Join date: 18 Dec 2003
Posts: 3
|
01-08-2004 22:28
Kudos to Ama and Carnildo  .. i switched my notereader over to states and signaling itself via llMessageLinked - works perfectly and even looks good code-wise, heheeh .. can't do much better than that  i guess the callbacks-triggered from previous state warnings really only applies to listeners, eh? .. that was my major worry about using states, but putting a few bits of test code in the new stuff shows it not to be true for link messages and such .. states don't seem so much like sugar now 
|
|
Garoad Kuroda
Prophet of Muppetry
Join date: 5 Sep 2003
Posts: 2,989
|
01-09-2004 08:11
Well I think this is pretty neat, it's kinda like constructors. Throw in the ability to overload them too, while we're at it?
_____________________
BTW
WTF is C3PO supposed to be USEFUL for anyway, besides whining? Stupid piece of scrap metal would be more useful recycled as a toaster. But even that would suck, because who would want to listen to a whining wussy toaster? Is he gold plated? If that's the case he should just be melted down into gold ingots. Help the economy some, and stop being so damn useless you stupid bucket of bolts! R2 is 1,000 times more useful than your tin man ass, and he's shaped like a salt and pepper shaker FFS!
|
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
01-14-2004 09:24
Bump!
|