Notifications
Clear all

[Closed] storing functions in arrays

I am having trouble with storing functions in arrays when passing things between scripts. I have an array in a global struct and I want to dynamically store functions in it, however ‘findItem’ does not work sometimes and is giving me weird feedback. Anything I should know about storing fns inside of arrays? Here’s a simple example that works:

fn test = (print "hi")
    test()
    fnarray = #(test)
    #(test())
    finditem fnarray test
    1
    fnarray[1]()
    "hi"
However when I pass in the fn with another function that uses finditem to see if it already exists, that does not work. (and why is this stuff above auto indented?)
fn storeFn storeMe = 
   (
       if (finditem crytools.fnstore storeMe) == 0 then
       (
   print ("Cannot find " + storeme as string + " in " + crytools.fnstore as string)
   crytools.fnstore[(crytools.fnstore.count +1)] = storeMe
       )
   )
"Cannot find collapseVerts() in #(collapseVerts())"

Is this because Max passes the '()' when passing a fn? And above i used just the text without the '()'? THis is how I am passing it: 'cryTools.storeFn collapseVerts'
12 Replies
 PEN

I have never even tried to do this and I’m not sure why you are. Can you better explain why you are wanting to pass functions in an array as there might be better ways around what you are trying to do.

I gather Demetry will be working with you soon, he is currently one of my students.

Yeah, will be nice to have another Technical Artist here :). He’s a great guy, and you sound like an awesome teacher; nothing but good things.

Right now I store all my tools stuff in a global struct, but you can’t really add or remove things from a struct if you haven’t defined them (can you?). As I load tools up (they are modular), I would like to pass values and fns between them but stay out of global space. I was ghetto and I just added another string array to index the fn array, but I will post it in case anyone else wants to do this:


 _fnStore = #()
 _fnStoreIndex = #()
 
 fn storeFn storeMe = 
 (
  if (finditem _fnStoreIndex (storeMe as string)) == 0 then
  (
 	 append _fnStore storeMe
 	 append _fnStoreIndex (storeMe as string)
  )
  else
  (
 	 print "fn exists"
  )
 )
 
 fn retrieveFn name =
 (
  index = finditem _fnStoreIndex name
  if index == 0 then
 	 return undefined
  else
 	 return _fnStore[index]
 )
 

Then this is an example of use:

fn testFn a b = (return (a + b))
testFn()
storeFn testFn
#(“testFn()”)
(retrieveFn “testFn()”) 4 5
9

 PEN

This is what I do as well, how ever if you want to access something that is in a struct you don’t need to pass it out of the struct, just access in the struct directly.


struct test
(
  thearray=#(),
  fn aFn=
  (
	print thearray
  )
)
testInst=test()

testInst.thearray=#(#stuff)
testInst.aFn()

Yeah, but lets say you have something that is a function used in a specific tool and all the tools below it or that it can spawn or launch. I want it to load functions that they can use, and make a framework where they can pass variables (through the struct). One example (how I do it but I am self-taught and ghetto) is making keyshortcuts for maxscripts. The collapse above has a key shortcut that runs it’s fn, the fn the key shortcut calls is loaded into the global struct when you open the tool that uses it.

I guess what I am saying is all the sudden you want to make a fn that all your different compartmentalized tools can see or access that was not in your original global struct.

With something somewhat the same I pass vars, just because I don’t know a better way, here’s an example:

crytools.storeVar $ “mySphere”
#(“mySphere”)
cryTools.retrieveVar “mySphere”
$Sphere:Sphere01 @ [0.831159,-0.463183,0.000000]
crytools.storevar $.radius “mySphere.radius”
#(“mySphere”, “mySphere.radius”)
cryTools.retrieveVar “mySphere.radius”
23.2811

All the maxscript tools we have here will be freely available sometime in the next few months, and Demetry will have a hand in that I’m sure. Some of them might already be available on Paul Hormis’ site, as he helped us tackle a problem or two, and we all agreed everything would be publicly available.

 PEN

I think that you might be missunderstanding what i’m getting at.

I do what you are asking…I think this is what you are asking for…all the time. I have for instance a struct that is called PEN_mathLib.ms, this saved in stdPlugs/stdScripts and loads when Max starts. if I want to use a function in that struct with another tool I simply call the struct and the function in it…ie; PEN_mathLib.mirrorMatrix() or something like that. The idea being is you can have nice neat packaged functions and tools. You don’t need to pass those functions to another tool, you use the functions where they are.

I hope that is making sense. I have asked Dimitry (The correct spelling this time), as he is sitting next to me to set up a simple tool example that uses multiple structs and is launched with a macro for you.

Yeah, np, we are talking about two different things! I am talking about storing new functions and variables in places that are generally set in stone when you init them, an example would be a struct. I would never want a fn that collapses selected verts by world space location instead of point index anywhere in my main struct or alway in memory. But when I open our set of morph tools, I then want to use functions to model based on world space loc and not point index, and if anything wants to work with those tools (macroscript keybinding) when they are open, they need access to those functions and the local vars to the morph tools rollout.

So I map those functions and vars to my global struct, so that any module can see them.

So like above, I am ‘tagging’ the sphere and storing it as a dynamically generated var inside the global struct so that anything can access it. I just started doing this to work around some max brick walls sometimes without polluting global space.

I hope this all makes sense, I have something like you talked about, but I (as I am sure you do) like to keep it to general tools that I can use anywhere, if a specific rollout has some weird function that I want something else to access, I started using this method to make that function available globally.

Sorry if I didn’t explain that well enough. I just never understood why the fns didnt work always in arrays, so i use the index array to keep track.

I see what you are getting at, after talking to dimitry for a sec, you mean wrap anything you do in maxscript within its own struct, even UI and rollouts. So that instead of making a tool in a rollout, you make a struct that has a fn that makes a rollout and do struct.openui(), etc… There may be an extra layer now that you have to work through, but you should have direct access to all the fns and vars in that tool because every tool you have written is a seperate instance of a seperate struct by itself, and when you need the structs to communicate vars you do it with a few global vars.

That’s a cool idea, but I would have to rewrite a lot of what I have done to wrap every part in it’s own struct because our stuff is very modular; :-\ each toolset is it’s own little island to an extent, it’s a lot less complicated than it sounds; just a lot of stuff I mostly hacked together in spare time to help the artists and animators out.

 PEN

Yes this is what I’m getting at. I would suggest reworking your scripts to take advantage of this. Building tools this ways gives the best solution to modular scripting that I have found in Max. Some larger tools that I have written for clients are packaged in several structs, will all the UI’s in one struct and then chunks of code broken up into logical sections. One of the ways that I have broken it up was public and private functions since you really can’t do that. This was so the clients could call the nessesary functions from their own tools and not have ot wade through which functions they could directly call, any that were in the public struct they could call, those would then in turn call the provate ones that did most of the work.

 eek

The one issue im finding out with fn calls inside of instanced structs is that they can get called slower inside of script_Controllers it seems, then to directly just call them without being in a struct. Dont know if this is to do with struct fn’s can other fns inside of them. Or whether you need to declare the instanced struct inside the fn eg:

 struct testStruct ( 
 
fn testFn1 =
(
print "test"
),
 
fn testFn2 =
(
testFn1()
or testStruct01.testFn1() ?
 
),
endofstruct
)
testStruct01 = testStruct()

Havent tried building fn rollouts inside of structs, but i can see the benefit of it.

Page 1 / 2