[Closed] Load order scripts
So I have what seems to be an issue with script load order.
I thought I fixed that long ago, but with mu latest script I have an issue.
load order now is :
plugin folder > callback_struct.ms : makes all callbacks available in a global struct
plugin folder > utilities_struct.ms : has structs.functions that are used in callback struct
startup folder > set_callbacks.ms : actually assigns the callbacks like so :
callbacks.removeScripts id:#nmt_newscene_systemPostReset
callbacks.addScript #systemPostReset “nmt_callbacks.NewScene (callbacks.notificationParam())” id:#nmt_newscene_systemPostReset
So when a new scene is opened it fires the callback from callback_struct.ms which in turn uses a global variable (struct) from utilities_struct.ms.
I figured that because the .ms files from the userplugins folder is loaded before the startup folder I can just use global variables in the callback_struct.ms file. But appearantly I cannot access :
>> MAXScript Callback script Exception: – Unknown property: “GetDefOutputDir” in undefined <<
Can a struct that is loaded in global scope before another struct (loaded in global scope) never access the latter to use it’s functions!?
I thought that at the time a callback is actually assigned (way later in startup scripts) was the time something was accessible or not.
Anyone knows, I will rename my callback file to something that loads later then utilities… but I think it’s weird, everything is loaded to global scope before the callback is being made…
Thanks,
-Johan
And to ask the question is to answer it.
Yes the load order matters, if you have 2 library scripts that depend on each other, the load order is important…
[pseudo]
Load order
script1.ms > str1.myFirstFn = str2.mySecondFn()
script2.ms > str2.mySecondFn()
calling myFirstFn fails, as it not knows about str2.
Even though I wont call str2 until later… that’s a pain if you build utility structs etc. You have to worry about load order even if you don’t call any of the functions directly upon loading the script with the structs.
~Johan
Yes load order is a pain with complex scripts. I have 3 ways I deal with but all are hacks so any other solutions would be great to hear.
-
Create a master struct that holds everything. any functions created within a struct can reference each other regardless of order they are defined, never tried that with structs within structs though.
-
prototyping: I create a single script which loads in null functions and structs first, this defines them all once, then I load in the real ones later that redefines to what they actually should be.
prototype file
fn foo = ()
fn bar = ()
actual file
fn bar = foo()
fn foo = 1
- I simply load each script file, then I run back through and reload them all again. This also works but is not the most elegant solution and doesn’t really work well when loading from multiple locations.
I almost always create a single custom loader script that goes in my plugins or start-up folder that loads my scripts that way I have complete control over how things are loaded.
Yes, sometimes the batch processing of maxscript is a pain, especially if you are adding more and more functions and need to keep them in order.
One solution could be to declare all the functions in the first script, either as local or global. This way they are visible all the time.
This fails:
(
fn fn_1 =
(
print "FN1"
try(fn_2())catch("FAILLED calling fn_2")
)
fn fn_2 = (print "FN2")
fn_1()
)
This works:
(
local fn_1
local fn_2
fn fn_1 =
(
print "FN1"
try(fn_2())catch("FAILLED calling fn_2")
)
fn fn_2 = (print "FN2")
fn_1()
)
two things you could do:
-
make use of the stdplugs\stdscripts folder. It is loaded before any other scripts.
-
Only put one script in automatically loaded folders. Put the remainder of the files in a subfolder and have that one script filein to them manually.
Thanks, all. As I have my own sync tool for scripts I will probably go for the subfolder option and a base script that will fileIn the scripts in ‘proper order’.
Great info, thanks!
~Johan