Dynamic Array of Objects – mobj – an Abstraction
I’m working on an abstraction to create an array of objects that can be expanded or contracted on the fly. I call it "mobj" (multi-object, or, if you like, mob of objects). It’s meant for you to have the patch saved in with the patch you want to use it in, then create an instance of it. If instantiated properly, you can treat the mobj just like you would treat the object that it is an array of, provided you prepend all input messages with a number from 0 to n-1 (which is treated like an index into the virtual array to route the input to the proper instance in the array) and acknowledge that all output messages will have the same prepended index.
This functionality is achieved by creating/deleting/patching the array of objects with scripting messages to a thispatcher object.
And the arguments for instantiation:
The first argument when you create an instance of the abstraction is the number of inlets for the mobj. This is meant to match the number of inlets of the type of object you want to create.
The second argument is the number of outlets of the mobj. Same idea, you match it to the number of outlets on the type of object in the array.
The third argument is the number of objects in the array.
The fourth argument is the name to use when creating objects, and all subsequent arguments will be the arguments of the objects created.
For example, you could create an array of 8 [line 0. 10] objects with:
[mobj 3 2 8 line 0. 10]
To change the number of objects in the array on the fly, simply pass any inlet of the object the message (num $1) or (number $1), and the correct number of objects is added or subtracted from the array. To change the number of inlets of the mobj. pass the message (inlets $1). All inlets are automatically routed to the corresponding inlet of each object in the array, provided that the object has enough inlets (if it doesn’t, the inlet isn’t routed to anything). The number of outlets can be changed in the same way (outlets $1). You can also change the objects themselves on the fly if you have the need, by passing (obj $1 $2 $3 … $n) or (object $1 $2 $3 … $n), in which $1 is the object name and all following terms are arguments to the object. Note that these object creation parameters will only apply to all subsequent objects that are created by sending a (num $1) increase message. Note that this means the array can actually contain different kinds of objects, or objects with different arguments. If you wish for all of the array objects to be recreated with the type you specify with (obj $1 $2 $3 … $n), all you have to do is pass a (remake) message and all array objects will be deleted and remade.
- – -
So far, all of this is working properly, but there is one hitch: when you save and reload a patch using these mobj, all patch cords to and from the mobj are not recreated on reload. This is because each mobj begins with no inlets or outlets, then creates them as prompted by the patcherargs object in the mobj, and the parent patch always tries to create the patch connections before the inlets actually exist. So, as of right now, mobj only works if you connect up the inputs and outputs every time you load up a patch. I would love to hear some possible solutions to this problem, because right now, I am getting discouraged.
Here is the code. Save it in a folder as mobj.maxpat along with a new patch to use it in and see what I mean.
----------begin_max5_patcher---------- 5227.3oc6c01aiaiD9yY+UHjlO0MYg36R2UTf6OvAbetnnvunMUWcrCrc1qu f9e+jHohsrnjFIQ4PJqssNcscrG9vYFNjbl44u9zc2ub2umb39f+QvOEb2c+ 0mt6N4Sk+D2o+62c+KK98UaVbP91t+kjCGV7bx8OpdsiI+9Q4yubw1mKdxsu 8R51MIGk+F3SO4t2NV7rH8y95hiq90zsO+K6SVcTIGzv3uD9X.O+AhH+QTzW BC9Y8uwW2s831EujH+V+W6SWro3qMcs741s7+9DByiKdZ025w+30D0m+82W5 y5P5eJeAD9Kg4O6e+oOk+vi.wisI+uruvJvwq6SdMY65fydsRnBpynBUBEbZ 9iB4i3vtBKhX9GJp7maBNrIcUR.oCpJ3VUUnR3fI5InD0.n73URcIWQ4oWV7 aI1wFhIPRCmLzfkotD1Wjg0C0kykpj8ZrPCFYu6zMIeKY+gzcaOaLb28mjcD RNQR3XoTyijSwQ3SReFH+7lcq9sDonFV7jqS9Z29T1kYhd52PBRkdn76Lcal Q8gjsGWbTK7m+Mu3sMG+EyPQ4W+qKVkT6urwoj6t+48oq2sMWHJ8al+zEecY iXlbJmctbKeGaW7pge4i61sY4h8eK8P5xMIklKxTgWrM8kEGSNlpjGb36+do u759zsGK8YUZUjylsKYNT54axr3RSiEqWua+g2Vd9KaxYZ89NpyLQnfrP4Dt xj4bqjlsTprlifd9qTwhIGzdT8iJeAFTZLXCUFAq0V5B6oSpzbZnxJ3hwnY6 op1TP9j.aSAvtBhsUq1W.swZvNClsVK1asXy0pcWc1dls+tPSohcXkWuM6wx 1jOEft70LsdUMFknKdUSFlJm2DR9xWDb9iWZX1tw4kFnTxkunQaTieIWtrew ejK+e5u730A++9fmF4I.TnL9arvpy.HBgNOG.1HPFbKlX6ofIiYvmuN1.w1d B.OUl.d6OSCBGvj.ArQ.SNGP4lBQqWyAnVmCTmnwoe5IyIOmE9v3ZWvTamDo LKn1YJg257wL3el8fcAe1j.7+wA4KBrhOxtqGLYVM9GFa3Wo5aY3edsX3qEq c7Ga00hwbVDYptX7muJaSFYWKhrIjIiUwwfT0+z3DApwIBZ6SDw5iaGkOEvh s0DAhwAMQ7noe3AyNOMtlGb8ozYYyCDiMoLOFfoAF7jfvxSBgjntXZ3AyEoi qwf1EUHx1yCBuwXPhlMhxg1AkU2NBlU7XkAeoqMB0O.b0tWdIQcY.2e+U.8T R0.bVDBMfFpJfFn3WkfUlhHi9vH6HzP5KzT9Zs1jtss6WRJx4uulwsC6da+p B05yh1Ln5.Ycxgioae+RA+oSWhig27ultdc0KbSNSkt90cYFPZ4O3m6kBQeG dpSZL.CbzotfD+Z7Q6vrm5vu8nwmNF7tN.Q9zDHoaiOjWMAx51fiLo0NKb1h 7nQn7zg.6.s9kSb0QXWm+l5ZnxMT3UZnJIF9HrNDw0mCQcXDx7r4P0HD2wQX nWokF0g4P+xKSWhfg6kyacYzglriNOyqRGGYSWuI92d9XcLlkH+ZW6BTOhIy eFezNskVA12NxEbmFdi4Z4m8hYi0SUtvgEeKY8uj88mr53ur33w8oKe6n5LD MLNsVB72xKCoVBddytkK1nq7h2+rp7sXTJq8NMNgZu++cR0vhEKywfMAarec xnS7CFu96NBdcxD2bYxTpj6ZDUs.TVtZVKikGVsO80iAur6aIAOfdJSzCd.m 8u0Bu3ZgWDD3kvkvKhhurlW6H9RZFecHrMSSVaRpQX6isbU9RFIyICT05Ita XaDyMv1FbAr30KJ73t3GnEvTPTkkSMUUZGwRjyikeNHx9ZjwDUZLxrgyTLB0 dUG5.H42mMFGKnDirETx7An7XkDZCp0MAxxPHNp9z6rCUCKOLFZ4v93DWMU0 zFrjZZFvF4CpoeNfLVHok7clgjBe.IecwpeqEadxvB8DSjgdxnC1lm6MwdtN IS1RFs3NQXUnlJjEgFXP8Bga.rWlBc0l9bcDsT8mCRT84MW4FSBtCvgwbdxc wBUSonoTHrLTP5lOrwBMpjDbPiJIrE3H5Kjr+Po484GZ8I+VYPoTPwsMjO0u TpjnamPASGW2YXQkioST4HSq4.5jB6EuSiGNW8GLWiSecUviPdpfGS7TAWDA Uxk8XFmRxw.kbCZUejBtIfrFHWtQFmSzQPzyEtk8IT4Nh4dxMDUECNf9PUTj giCSxotljGC27j6hxNBlrKbQYGCP1UG7nCI6piuqK5LXWB2i5lribmvEYdZD .lL9pEyibMccnqIYzrn+xt9IKtq+1tm++xRM.yFdo158lMee9FuKeyGfhBEr V+d8siOsO6gTa01jE56MV2xWi5WKekgweDs7Up9vxjRsHTdNjbTXGa4q.9Tl a4qdPKecytEqyOA2fP6eE1rPYE5FIUUD3Adf2N+MXONWnENV2c1UItx.uGFl 3l89rJ.Rlc.xna2TAfntuEaoRx8CUxnwCHsjJo6jREcHW+JXugGnAOvFg6FT k2JLhJhMkJa+uaPl+jveq1scaFLbNFGF7.9IkPGLFKUo5QhzXceSLdfXcnyu j+HkCvXl5dIQVwu.M1qRB320aIumGvmoAOBZspzuhptV77t84fzZoQdfVa+x oMXZs3H6n0JrBCObESanEF5+ckgVVu0QUPKIVwdFjgsUJJ24UQKy5A1xRGGo RoMrMTPwDeHt029yzd.jsj8pX0F6Qp8zOzzWE2bbqs0NR+f.1ute2KG9iWVt ai8O3jBycrUL2wBm2be0tWVltMI.E7TCa8mLvUlHJxGJZn3oCEOUiqxubTVk GqiSxJNQIbP19N1dWKWKUEwl99NYGiCuhqYeOUHV3At0Jh3FMB.cHpbqDhJI 91MB.sW.M2jMvH.nDeLBfQQCkfQEUFjMhQEc6pgFqpeEJxJwnh8QMTYH.Y+S enyQZaaA.eJVJycg8Nb2dgfiB3zOjOqmWKFZTTQptsmq8wtQ4GLVfAWzEvHx AJKkVNjsk8LDbJHfxN1dbHGy1M3dvITUDNp.uG5dvQ7a88fWfmzXarGbxs7V vKhQLxJwHxZ47gbz8feplR066dDhEWqxFo1sMcn2cL9F8b2KvQ0oVLb8U1M6 lZzV93vXaroFFlNuu6h7DAougMgUzQucSNrBfTXEfjdylaXE3HyJ3H1KZ9FA KVud29Cusz9wLQiT4uMVtcIAZfgyKnVI6DtTlOkP+kgvZSr+KRt+S4WOWexr QWx6TFSt+pI3OjOIvI3Ofj7GRh92Zx9CLg+aHo+gk3+sj7+sT..sVD.0UH.l KFfKzTrNuAFftJDqIwpjVGcxP0ueevSi7Dfltqv1k1.UrUz7bPmnZbhsmBlL lAe95XCDa6IfYNuFNmWqMBXVkyqUrn0zjxqeNK7gw0tP2y5zrdM0NSIsSzxy f+Y1C1E7YSBv+GGjuHvJ9H6tdvjY03eXrgekpukg+40hguVr1werUWKVyodS yEi+7UYaxHKys6rnIiUwQC0eSimfXyYdQcSDZxcGKac2ly9h9LQfXbPSDO1V 671QmcdZbMO35SoyxlGHFaRYdL.SCL3IAgkmDjT9EbSCOXtHcbMFztnBQ1dd P3MFCWlihMlmhCAkap4QW8ZiP8C.Ml+hiH5UoAS2UmEgPCngpBnAJ9UIXkoH xnOLxNBMj9BMkuVqJsk6pH1jfM8lYBwYZr7lhHRm3DI6jm.fmnD27jlzsm9j k9zjj60GGS41VciqFT2pGt9HD0wQne4YQzoUzUHh+MG10nx7m4vtM5XQ9lWF kDi6vHDOw0PUiP+QCsK6YPkOV9zl9pSfqc7glzpm5Cv.4SSfztO97JETTGbf VKb3xqPzkc1RGS+Km8hEbRgRpalWJtXbZsD3ukWFRsDzLeU792hQor16z3Dp 8QzLpzc22VXHxdWUR5xnonSJFgFXIwR8QNrcjvVlPmheJrUct+Cobi8FrsnW fqUdya4ujGGC.VdsJDtJUAFZOTi47Uy8nxl05quSBlCkMqIDOfcOPgiP4xJJ U1wwCDF8hx7bjZ+zpDjlfIVo09g7ntO8H0zFTsLUq.m3na1V1fPUacVogMf4 Na+ZXrnjbJi+EVbbrfmsJCGHQsi3rObNIGNqGyndJmGyvNkfyfSyztEoGyvd pfSX9pfi.phSbKUbLTpqk3VD.KlCkpicKxek.0xTdN4H2R+Frb6P3MApb6V9 Sfpl3VqzCN.E2Z0xtnZ6R7NNTzFycrnS.i3NlbK.i3tkcIAbTUNFfSAtJuIU pORIOGGIP.bgaon.MZPWSOg6oaaf2IGJtS3f4rW.rvuQNnKbDvkdbm05wHvJ JB2JNVvwe6VtTHbf5I4b2kKonvfZX5VwVQI.k6bJRxkzuiApe6X1kDnq7PId YfUT253S.6MwwNUSgGGWEHuft0owRf5Mg5VdSnP0Svtk26bhLGVzfB2StAom D4mxMKzs11Pnm5GjBdY9X+L7aJ2oB+lJ5hb6P6mGpCbpicxOPOIYliI27tf2 T2Qtgd.gL2ZASVmzuI9mePFyO8ey70.Tbrqlh3oAnjSTqv1Yr6I1D+aClR4F 7FiQdnZhaodC0cBJz8TS.sedtWdcZNlXSi7Uu2PkaqdM25mrnjQaqbQ0CfFK ST.kHZCIUeakFZKkEpwRB0bp0qPA4ip4O4f6rLpWMXan.ENmbzR29z9cukMe 8bwKZpBELWkGl6VqTUgFFZlRzpGBKmq8EEkPC0sUMDe1kjdVwbeMjc1YDcFh STEwmj+zYp5PkQPmUS.FI5rxjbFjOEvjbVKDbVqZcCUg2Lgl0NYl0.Ql0.Il 0HAlYh7xpRbYVrxc1raw575LMHz9DANVnpZGoph.OPhCz8qYzQjDFwJZTmGN yAiybv3LGLNyAiy7+2LGLNyAiyLbyLGLNyAiybv3cybv3LGLNyAiybv3LGLN uV7LGL5dQnNyAiybv3LGLdW8WnzLGLNyAiybv3LGLNyAiCG8l4fwORjYpxAi NUGkelP.lIzgaOF4XRSoJSZ9vY5SmQSeJoZpSoXScJg61gV+lxTy3zmdMmxz i5zmVamlzQ7DmJom7T.9Dk51q06d8wrD4W6ZWf5QLY9y3i1oszJ7NNlD2og2 LGLZ5S4FhCFkGCcvk29gk3kIMUBUPec73aPFXbjfVBWw7hJZXCghlFDvXiTw 1xwfJ13HUdxDaCtCihAQ5UWSxtpQk0bBrDMZDEnhiPojgoZR8f5PbexqIaWa +54jhUTsnT4jwFHiKF4cjrpZ0oGvYKkFbwKkWd4I6yeMbokExiZZ0t2T2iI1 99ciUUUKWUO5JlEMysgmSLq.lSVsaaFxdVPCgmMMbZ9wvaa0w8aJWsyi7jDR 44gn4fO00iOfIIp2vdt2OZJ7Tky7nYxysutxU0PNlNydtCLjMs4slQ2uonO2 7ffW1STk1BpJCufpB0HdfXZXmI+0INEEWnyxQ2NbT7n.jXTrMARwMKYOinB0 IHHl3z87UGXUQLYKfk4i.a9J+4qSsbDVmh99dtF9BUXP8kmKVmR9Wc.PdDh1 W6VUoAOXmqDev4p9vaBNzKJgusSBK7rf9EzA5JHz427zhWGmCBCEo13YjDOY CscbE6Mm5R4aqQeZKxeLBF+ZPVAunnAdvsHgyqtNJQnVfag1vGp3lMPe8Yeq ZCeCdoHDO1cfxtcZqmNo6GvOkMXFkqrQg1Tj9boDCzzmFKnt+Q8cYeQvVa.P c8WLhMh+WBkXebO.aROb7oEqV81KAwY+w9mCnP2yUj5rwC71wDQQnVtfrGcN uDmRy.kShQ33+YhyVMCgGnigbTVbq5WfwUmbUnM7KPCcVeBMmxKg8N7TkENs 95mtbu9ti69zX4u5vng5XPDPQitbGliETToXngtPPXa4YVzWXYKwH34WfQHT HozIqMVi4q742nOTWDu9V4PWNT2xsvA6D07ot4dkZGu+7EATV3RuLuKQQGPI NG2h2yJhKEFm+n19kqg5HuTgwrDUCv6Vr+CFLam5XbwNTRPywHIJikmgevbQ RjDjuE2xwBtKqD4XhNXtM2sbHhDdpWEndwq1WM9XofSDv0NcL86p0FUc3Mwo nnPv3MA6d5IfwaGRtgtZOwwnjcv3sa4+17tC7BQm.leE02HhKotfgxn7H2St Ai4dpKQGStqQ80S3RzXOUvq1+77EAm4oBt4Mk4Ip4bvws3VmJDAJkmScP4F2 kEhbHZOmC02Bl5VAKBVtcqMwAWtMdlce3hNBJj6X1m9pb6mpJLrmt3IyaC0B 7l9cP+3fV7TPcrSaFp6PF1AEbHpJLGCwgZZZUME8SVz5pZqsUoG.M1tp.zpp ZH4LZqEU0R6oxXqoxb9ZnPA4ip4O4f6rDdQMXaHQWZp7ZLlzOlSyEyjFiLCv hElKol5Avyyrk2YwpFREJiXSGAkx4v4Yo9ib7G7.5w.8nN3A7iAYfPvCDi3D tq3DMTlWrQ7yJW1ySbSX.068bqQFnpS6QoLuX+yGxb4hBhdux2gnEgaEcTYS HBE1O0nF.mGuN.TdCAHzNPhP2A.TkWYOMrvLRbsfhojQcDwlT6XHowEtvbgn .FWX0hKiKd7sEmVLHuU7TAmj4NdtumkI6ktfTKxk+if8Iur32RBz9qJ.L35a Q0iqLUKrSmPuJ58oGdxOk190XEV2+cUrNSskCKNV5vhyGhVHBiZTI75Yad7W SOnctaI7go6HWR.hG2OsITOcneVLh52+28uy+MJMLCt+el+v28exeTVlr4Oi JNSMpJ+BJmWrJP9xXl0PsgCvtTZbAJ.+pAIaN.4Jy7cSnPsHThX9UUpPXdL. r55BUp0OaUnTKmbMAKND8JzUUlXXryISROrsa+cgj6FR0kywWAccFDwBi9HL AQNlXIhXNp1dqN1itt9phf3VPITnqmyJJ.g5xL6e7Uph4tnXU4KzMLA0hExM EKNnEcPWawhAZUmqtXgaSmG+QLGRbRoh1dznwtn+Ac.FHWyAwUWtnfVPbHQ+ k8W96O8+AT4qxe. -----------end_max5_patcher-----------
When mobj is done and working well, it’s going to do so much for my Max workflow. I hope it can be of some use to others as well.
Oh, I should add that when you paste the above code, it will go ahead and create an array of 8 [i] objects based on the default arguments in patcherargs. In order for the patch to work correctly, YOU MUST delete ALL of the objects on the left side of the patch, including inlets and outlets. These will all be created according to arguments, and if they are there before instantiation, it will screw up the array that gets created.
list-accum: No such object
For the inlets/outlets, the usual solution offered is to include some hypothetical max number of in/outlets (99?) in the mobj abstraction and have the script delete the unused ones at instantiation.
I suppose I can give the maximum inlets/outlets thing a try. It seems reasonable enough.
And, whoops, I suppose I must have downloaded list-accum from some external repository. I can try to to reimplement the patch without it, if other people are interested in using mobj.
Okay, I’ve got this working using 100 inlets and outlets upon instantiation, then eliminating all but the needed ones.
My only problem now is that, because the abstraction instance begins with so many inlets and outlets, the patching rectangle always comes out huge – a width of 1355.5 (which is, I guess, the default patching rectangle width for an object with 100 inlets).
Is there a way for me to make the abstraction change the size of its own patching rectangle in the parent patch? (Or to make it always come up as a reasonable size and not have to go in to the inspector to change the number by hand every time I instantiate an mobj or try to change its arguments?)
[list-accum] can be replaced by [zl group].
any chance of a max4 patcher, or at least a .maxpat binary or a little jpg? i am interested.
So, I should be able to send a (sendbox size 150 20) message to the abstraction to change the size, and I can actually send this message from the inside of the abstraction with the [thispatcher] object. The problem is that the whatever is connected to the first inlet on the inside of the abstraction receives the message and resizes it rectangle, rather than resizing the rectangle of the abstraction within the parent patch.
So, I’m still at a loss for how to resize the rectangle from within the abstraction.
Also, I’m not sure what it would entail for me to convert this to a max4 patcher or maxpat binary for you, Roman, but I can certainly look into it. I’ve been doing Pd/Max stuff for several years now, but I never really learned about how to properly share a maxpatch with others in a way that would be useful to them.
Maybe you could do something with js sending a message out to the parent patcher telling the abstraction box to resize?
not sure about the resizing, but for the Max4 stuff, you’d need to build the example patch in Max 4 and share that text code. Then anyone with Max 4 or 5 could open it, but Max 4 users can’t open Max 5 code directly. (backwards compatible but not forwards)
if you can give me .maxpat file or a picture (with everything unlocked/visible) i should
be able to build a max 4 version from it and upload it when everything works.
we are getting lesser, but there are still many lots of people on max v4, which can not
open max5 code. but we can look at max5 patches using the runtime and copy stuff
So, you want to port it to v4 from the v5 maxpat file?
Yeah, of course I can upload it. I’m just glad to hear that other people have use for this as well.
The maxpat is attached. I haven’t changed [list-accum] to the more universal [zl group] yet, but you, being the one who suggested it, should have no trouble making that switch. Also, I hope the thispatcher scripting commands work the same for v4. Let me know if you have any trouble getting it to work correctly. It’s kind of sensitive.
Also, the sizing problem makes it kind of awkward to use, so if you come up with any solutions now that you have the code, please let me know. It’s the only thing standing in the way of this being a practical abstraction for everyday use.
thanks. i will be able to just change things as soon as i understand what it should do.
right now max 506 runtime does not display the message boxes. :D
@Roman – have you seen the supercollider code that converts from Max5 to Max 4?
I find it handy every now and again as I am still working across both versions. Of course you have to run supercollider to do the conversion but it is a lot easier than doing it manually. I can’t remember exactly how you do the conversion but it is not too complicated. There are some other posts here on the forum about it if you get stuck.
You can get the code here:
i know it but i dont have sc3 installed :)
Well, if you need any help from me with piecing things together, let me know.