state scoped variables?
|
|
Earnest Clymer
Registered User
Join date: 20 Feb 2005
Posts: 17
|
04-21-2005 19:54
Any know the history or reasoning on why I can't define a variable with state scope? It would be handy to be able have event handlers in a state have access to variables that fall out of scope when I switch state, and much tidier.
e.g. default { string somestr = 0; touch_end(integer no) { llOwnerSay("somestr is: " + somestr); }
} .. which gives a syntax error where I define somestr.
It wants to be either global, or defined within a function or event handler. Actually the example I have in mind is reading in config data, and doing setup, when its useful to have some constants defined to shape the input. Once the script is setup I want to switch to a running state, and all that stuff is then just clutter.
|
|
Spuds Milk
Registered User
Join date: 28 Sep 2004
Posts: 94
|
04-21-2005 20:05
you've created a local variable (to default) then try to reference it in a different locale. Since it doesn't exist in the other locale you get an undefined errer.
If you declare it as a global first, it'll work the way you want.
|
|
Earnest Clymer
Registered User
Join date: 20 Feb 2005
Posts: 17
|
That's my point
04-21-2005 21:21
I know I'd have to make that variable global, but as the variable has no relevance outside of this state it would be nice to be able to declare it inside the state block.. which unless I'm missing something is just not allowed (syntax error - says the compiler) for some reason.
I think this is a feature request (and I'll submit it as such if I don't hear different), I was just looking for some back story, or perhaps an explanation on why state-local (but not event handler local) variables would be impossible or useless or something.
|
|
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
|
04-21-2005 22:19
No idea why, but it's been that way forever. To make a global more state specific, you could add new variables and prefix them with the state name, or add a global variable that maintains the state and AND them together. It's a bit hackish, I guess, but there's no direct way of doing it.
|
|
Spuds Milk
Registered User
Join date: 28 Sep 2004
Posts: 94
|
08-16-2006 15:20
sorry for taking so long to look at this again
you created the varable INSIDE default
if instead you create it OUTSIDE of any state (typically as the first few lines) then it'll be global.
|
|
Rickard Roentgen
Renaissance Punk
Join date: 4 Apr 2004
Posts: 1,869
|
08-16-2006 17:34
heh, the answer is there's no such thing as state specific scope. States, aren't related to functions or loops at all, even though you use curly brackets to enclose them. States are just event handler groups. If you want a variable to be available to any event in one state it has to be global and thereby available to all events in all states and all functions.
As far as why it's that way, I have no idea.
|
|
Xixao Dannunzio
Owner, X3D Enterprises
Join date: 20 Mar 2006
Posts: 114
|
08-16-2006 18:47
default { state_entry(){ string somestr = "whatever"; }
touch_end(integer no) { llOwnerSay("somestr is: " + somestr); state other_state; } }
state other_state { state_entry(){ string somestr = "something new"; llOwnerSay("somestr is: " + somestr); state default; } }
...should work without any problems.
|
|
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
|
08-16-2006 19:04
From: Xixao Dannunzio default { state_entry(){ string somestr = "whatever"; }
touch_end(integer no) { llOwnerSay("somestr is: " + somestr); state other_state; } }
state other_state { state_entry(){ string somestr = "something new"; llOwnerSay("somestr is: " + somestr); state default; } }
...should work without any problems. unless you add ... (and remove the state change back to default) touch_start(integer t) { llOwnerSay(somestr); }
which is the OP's point, you can have it with an event or as a global but not where the entire state (and only that state) can see the var
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
08-17-2006 04:15
Time for the Evil Code Monkey to come out and play. Here's some code for variables that, "magically," have independent values in different states.... //// State specific variables and methods add/change/remove values //// consistently the global declarations, the SSM_NVARS value, and the functions!
integer ss_myInt = 3; string ss_myStr = "hello";
integer SS_NVARS = 2;
list captureState() { return [ ss_myInt, ss_myStr ]; }
restoreState(list vars) { ss_myInt = llList2Integer(vars, 0); ss_myStr = llList2String(vars, 1); }
//// State change code. You should not need to modify any of this.
// State specific mappings and default values integer ssm_currState = 0; list ssm_stateList = []; list ssm_defaults = []; list ssm_mappings = [];
// The meat changeState(string stateName) { integer nStates = llGetListLength(ssm_stateList);
if (nStates == 0) { ssm_currState = 0; ssm_stateList = [ stateName ]; ssm_defaults = captureState(); ssm_mappings = ssm_defaults; return; }
integer nextState = llListFindList(ssm_stateList, stateName);
if (nextState == ssm_currState) { return; }
// Save current state ssm_mappings = llListReplaceList( ssm_mappings, captureState(), ssm_currState * SS_NVARS, (ssm_currState + 1) * SS_NVARS - 1);
if (nextState < 0) { // It doesn't exist, so create it nextState = nStates; ssm_stateList = (ssm_stateList=[]) + ssm_stateList + stateName; ssm_mappings = (ssm_mappings=[]) + ssm_mappings + ssm_defaults; }
// Restore old or just created state ssm_currState = nextState; restoreState( llList2List( ssm_mappings, nextState * SS_NVARS, (nextState + 1) * SS_NVARS - 1)); }
//// Your states, of course. Add lines to each state_entry() as shown
state default { state_entry() { changeState("default"); } }
state state1 { state_entry() { changeState("state1"); } }
state state2 { state_entry() { changeState("state2"); } }
|