[Closed] Best practice: Code libraries | Structs
Hi all,
I’m trying to convert most my scripts to some sort a library of functions and GUI’s. So I decided to include alot of functions in structs and have them included in stdscripts dir and build GUI by macroscripts. Thus seperating logic and UI stuff as much as possible.
Now I’m wondering how anyone else tackles this problem. I’m grouping similar functions in structs, but some functions rely on other functions in the same struct. I want the function library to be as flexible as possible, so I can reuse functions if I please…
The “issue” I run into is this, If I access a function in a struct that relies on another function in that struct I have to declare first the struct name and than the function.
for example
struct JHN_demostruct
(
fn function1 a = function2 a * a
fn function2 a = a * a
)
--This will work with an instance of the struct but not when calling the struct directly
--So to be safe I do this:
struct JHN_demostruct
(
fn function1 a = JHN_demostruct.function2 a * a
fn function2 a = a * a
)
Sometimes I don’t want to instanciate a struct, but just use a function directly, but othertimes I want to instanciate the struct. And is the code then just as fast, also it just doesn’t feel right :shrug:
I think I understand why it does work the way it works, but is it me or is it a bit weird…
Any comments on building a logic and sound code library are also very welcome!
-Johan
I think it’s a matter of personal prefernce…
Unfortantly, I come from a OO (object orientent) background, so I like to encapsulate my work into a struct where the functions relate to a single task or object paradigm, then leave “utility” functions free and in the open…oh for the ability to inherit and extend…
Anyway…for me…a struct should be an isolated code block, where the code inside relates to a single logical task or piece of work and the functions inside support that task.
I would then instance that struct when I need to do my work. I would then use the “utility” functions in a free-standing state that would perform common and annoying tasks.
SOOOO, if I can’t logically group a set of functions together, then I’d just use plain functions…
I guess it comes down to what you want and how you want to work in the long run, the fact that you are thinking about it is great!!
Shane
I will have code libraries like ones that do math or handle sorting methods and each of those groups will be in a struct. Then I write the tool starting with a struct as well so that that tool is not sitting globaly but I can still get at the functions if need be from mcr scripts or just command line to speed up my work flow. The tool will fileIn the needed libraries at the top when it is run.
I have been working on a very large tool recently and I decided to break that up into five different scripts each being a struct. The main tool and its UI and UI handling functions as well as some of the main initializing functions. The others are libraries of functions for differernt tasks. One just handles all the reading, sorting, searching of XML files.
I think that every one has their preference.
Shane, Paul thanks for the insights.
I’m now just putting all similar functions in structs, i’m just wondering if I should instance my structs or not. I have a struct that holds the pointcache routines, do I
-
filein the struct on startup (filein in stdscripts\init script, have it hang there until I need it, for example instance it later on, or calling it directly)
-
filein and instance the struct on startup (calling the script and immediatly make a instance for later use, which is a bit problamatic I think when you have two scripts calling some variables from the instanced struct)
-
filein on calling the tool and making an instance, not having it globally available.
I’m wondering how important it is to have the tools globally available, and how much impact it would have to initialize a whole codelibrary on startup memory wise, not knowing If I’m even going to call one function that session.
Feels like a struct behaves like some sort of namespace, and an instanced struct like an object. It’s not ambigious calling a function from a struct or an instanced struct… I find it hard “doing the right thing”.
If I read Pauls comments right he has a struct that filein other code when called, is the memory hit to have all code available on startup to big then? All maxscript librabries seem to be there all the time? And it feels like double the work… You have a duplicate function for including the file on call, calling the same function on the now included functions?
Thanks for the response, trying to refine my skills
-Johan
Well I have some that are called on startup that are used by many tools and are very general. Like the math library that I use. It is called from characters, tools and all sorts so I have it running all the time. Others that are part of a larger tool I will fileIn when needed which is when the tool is launched. Most of what is on my site are all run on startup but could be changed and most probably should be. Both are valid solutions.
What I have done with the latest tool is the MCR fileIn’s all the needed scripts and then calls the function that opens the UI for the tool.
I’m in the same boat as PEN. I have general functionally structures I’ve written for convenience that load at startup and filein structures of functions that are specific to a large scripts. These sometimes move from one to another… TextPad is a savior when this happens… “Find in Files” is the best function ever written
Most of my .mcr’s are a single filein to a .ms file.
Others where script requires context, like ensuring the user has a mesh selected, are a a little bit more but the bullk of the functionally is filein.
Again, this is a design decision. If you find yourself “filein”ing a script alot, you might consider putting into the sdtscripts so it easy to access.
I, again, tend to group scripts into logical groups where possible, creating a lot of small scripts that do very particular jobs, it makes it easier to find stuff, but removes the need to include irrelevent code…
This can take some time and I’m sure you will move code around a bit until you are comfortable with script locations and content.
Feels like a struct behaves like some sort of namespace, and an instanced struct like an object. It’s not ambigious calling a function from a struct or an instanced struct… I find it hard “doing the right thing”.
I think this concept is a good one, again, it will come down to your needs.
Some code will be, by it’s nature, static, it won’t need to be instanced as it does not maintain information between calls, where some will need to be instanced, as it’s maintains stateful information.
Using some name conventions should help as well, so you can determine which structs are “static” in nature and which ones aren’t.
Have fun
Shane
Guys,
I really appreciate all the feedback(!), and I will indeed be shifting code around alot in the near future Your insights help me think about these “problems”. I think I will go for static functions structs for general functions and instanced structs for more specific tools.
Seperating logic and UI in different structs, UI calling logic functions. Load generic stuff on startup and filein specific code when needed.
I’m scripting php/javascript/maxscript and some python for some years now (without programming background) but starting to finally feel somewhat comfortable with my coding practices Even started reading a c++ book… would be great if maxscript had some sort of “real objects”, with private/static functions etc… (without hacking). It’s a fun ride. The new maxscript editor is also speeding up my workflow… only thing missing is dualview (two files next to each other) and shift+ctrl+up or down to move a line up or down as far as I want (notepad++ has both)…
Ahwell off to scripting another tool then I love my work!
-Johan
Like others above, our studio-wide library-type script files are deployed into <maxdir>\stdplugs\stdscripts. That’s the first script folder evaluated at startup, so any functions/structs declared there are guaranteed to be accessible further down the line.
I would recommend this sort of approach over a strictly filein-based setup, for one reason. If you have more than one script filein-ing the same base library script, it will get evaluated again each time. It won’t realize it’s been evaluated already and that the file hasn’t changed. This wasted work can add up to a few seconds each time depending on its size, and how many times it’s referenced.
This became a big factor in our startup times at one point, so we pushed everything common into stdscripts and punted all the fileins. You still have to watch for library scripts that depend on other library scripts, but otherwise it’s been easy to manage.