PDA

View Full Version : Scope of Functions


Joel Hooks
10-12-2007, 08:02 PM
This keeps happening to me, and I have searched for a solution with no direct answers found.

I have a maxscript file that looks like this, but I have to run it twice to get the functions to process:

fn someFunction = ()
...
fn someMoreFunctions = ()

(
Rollout
)

I have tried it like this, which causes the function to cease functioning:

(
fn someFunction = ()
...
fn someMoreFunctions = ()


Rollout
)

and this which also seems to need to run twice:


fn someFunction = ()
...
fn someMoreFunctions = ()


Rollout


It is frustrating, and I know the answer is relatively simple.

Bobo
10-12-2007, 08:25 PM
I really don't know what exactly is so difficult - MAXScript can only see what it has already seen before in the current scope or ANY scopes above it, including the global scope.

So


(--open local scope
fn someFunction = ()
fn anotherFunction = ()
rollout someRollout "Test" ()
)--close local scope


*will allow anotherFunction to call someFunction (same scope, someFunction defined first!)
*will allow the rollout handlers to contain calls to both functions (higher scope, defined earlier)

If you want someFunction() to "see" and be able to call anotherFunction(), you can predeclare anotherFunction() as local in the beginning. You can do the same with the rollout if the two functions have to access the rollout for something.


(--open local scope
--make second function and rollout visible to anything in this and any nested scopes:
local anotherFunction, someRollout
fn someFunction = (anotherFunction()) --can call other function since it was predefined
fn anotherFunction = (someRollout.someButton.pressed()) --can "see" the following rollout
rollout someRollout "Test"
(
button someButton "Press me"
on someButton pressed do print "Hey!"
)--end rollout
)--close local scope


Questions?

Joel Hooks
10-12-2007, 08:43 PM
If you want someFunction() to "see" and be able to call anotherFunction(), you can predeclare anotherFunction() as local in the beginning. You can do the same with the rollout if the two functions have to access the rollout for something.

Ha! The declaration bits solved my problem.

I was assuming that declaring the function inside the local scope would simply make it accessible to the local scope completely.

I really don't know what exactly is so difficult - MAXScript can only see what it has already seen before in the current scope or ANY scopes above it, including the global scope.

My functions get put into global scope, so has MXS not seen them at this point? I understand when I run the script again, it is seeing them again. Is it good practice to explicitly declare the scope as outlined above?

Apologies if I am simply obtuse. Thank you for your tireless efforts on behalf of us novices. :buttrock:

Bobo
10-12-2007, 09:18 PM
Ha! The declaration bits solved my problem.

I was assuming that declaring the function inside the local scope would simply make it accessible to the local scope completely.



My functions get put into global scope, so has MXS not seen them at this point? I understand when I run the script again, it is seeing them again. Is it good practice to explicitly declare the scope as outlined above?

Apologies if I am simply obtuse. Thank you for your tireless efforts on behalf of us novices. :buttrock:

It is generally a bad idea to use the global scope unless you HAVE to.
So starting with ( and ending with ) is the way to go 99.9% of the cases.
The only cases you might want something in the global scope is when you define function libraries to be used by all your scripts, but even then you would define a local scope using ( ) and then declare specific functions or structs as global explicitly:

(--start local scope
global myGlobalStructOfFunctions
struct myGlobalStructOfFunctions
(
fn importantFunction = (),
fn anotherFunction = ()
)
)--end local scope

Such a script could be placed in the StrdPlugs\StdScripts folder and would be loaded at startup. Then, any of your scripts could call

myGlobalStructOfFunctions.importantFunction()

and would find the struct in the global scope (because we explicitly placed it there) and we can access all the functions inside that global struct without them being in global scope directly...

Another case you want to use global variables is when defining a rollout to be used as a dialog - you want to be able to "see" that dialog in another run of the script and be able to close it before redefining it. Also, other scripts would be able to access the dialog and press buttons or change settings in it.

(--local scope
global someUniqueRolloutName
try(destroyDialog someUniqueRolloutName)catch()--try to close if already open
rollout someUniqueRolloutName "Rollout"
(
button btn_pressMe "Press Me"
)--end rollout
createDialog someUniqueRolloutName
)--end local scope


This local scope above very often is the scope of the MacroScript that creates a dialog... So if you are defining a Button for the UI, you have to create a local scope for the MacroScript anyway, but still keep the rollout global for later runs or other scripts to see it.

Joel Hooks
10-12-2007, 10:38 PM
Perfect.

Thanks bobo.

CGTalk Moderation
10-12-2007, 10:38 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.