Basically, I’d have two levels of organization. I tend to put one big struct into a file that contains smaller structs and any shared data - basically, the equivalent of a python module. I don’t use that one as an instance, but as a namespace (again, like a python module) and I’ll put that into a global. Other script that need the functionality from that file use the global, and then make/use individual structs within it. In the thread you probably saw this:
<
struct
(
<params>
<structs>
<rollouts> or <forms>
<functions>
<event handles>
)
>
Which is really a way of saying “I make a class (= struct) that handles all the functionality for my tool in the same scope”. The only changes i might make to that : It doesn’t really need to be a global per se, as long as you can get a handle to it. My usual practice (warning: I’ve been out of MXS as a day job for 4+ years ) was to make globals structs that contained only other structs and functions and use them as if they were python modules.
global databasemodule
username = "steve"
password = "xxx"
connection = databaseModule.get_connection(username, password) -- < a function in the databaseModule that gives back a struct (also defined there)
models = connection.request("models")
connection.close()
Individual dialogs or whatnot might be their own globals or not; if you are good about keeping UI and function separate, the “UI” structs will be 99% UI code with functions/structs from elsewhere doing the actual work. The ‘globalness’ only matters in the sense that you have to have a handle to the tool in whatever code scope you’re running; structs keep the scopes nice and tight instead of sending every callback out to the global scope all the time.
The main trick to keeping this working is that you don’t want to go nuts with fileins. To use a ‘module’ you would have a header that checked the global’s existence, and if it did not exist would filein the module file into the global. This is basically a lame version of the way python modules work.
fn using globalName script:undefined =
(
if classof globalName == Name do globalName = globalName as string
scriptPath = if script == undefined then globalName else script
if not (matchPattern scriptPath pattern:"*:*") do scriptPath = (scriptDir + "/" + scriptPath)
if not (matchPattern scriptPath pattern:"*.ms") do scriptPath = (scriptPath + ".ms")
genericCommand = "" as stringStream
format "global %
" globalName to: genericCommand
format "% = if % == undefined then (filein \"%\") else %
" globalName globalName scriptPath globalName to: genericCommand
seek genericCommand 0
execute genericCommand
-- typical pattern
--using #materialMgr
--global materialMgr
-- materialMgr.DoSomething()
)
Looking at this now I realise the smart way to do this would have been to return the contents of the global from the call so the pattern would be shortened to
materialMgr= using #getMaterialFromFace
But that would require executing another eval to get the contents of the global. All of this might be better today, it seems like an obvious place for MXS to have gotten better.