(feature request) Loadbang delay argument
I keep finding myself using lots of loadbangs with various delays and it would be nice if the loadbang object could take an integer as an argument that would be a delay time in miliseconds.
What do you think?
In a complex giant patcher, the initialization gets quite complex. The method I settled on, in the largest patch that I use, is to start a metro/counter at the top left corner of the top level patch that counts to 100 at a rate of 5ms / tick. I send this value around via a [send load_percent] and elsewhere in the patch I compare load_percent to some threshold, and initialize when load_percent has crossed that threshold. This allows me a deterministic order of initialization across a giant patch, albeit at the cost of a half second longer load time.
i use an abstraction which allows 9 arguments for 9 different delay times.
Thanks for the ideas!
I don’t understand why having the delay built into loadbang would be any better than using a delay object. (That’s what it’s made to do: delay a bang.)
A different approach would be to use a single loadbang at the top level and use send or forward to send the messages you want where you want in the order you want. What with all the objects such as b, t, delay, pipe, uzi, etc., you can construct about any sort of ordering system you want. Here’s a ludicrous example.
----------begin_max5_patcher---------- 1691.3oc6asrjahCEcs8WAEUVMkmtPhmd1M07ALaxtzo5R1HaqIXvEH2ORp7 uOBIgMXCHQrQMYlrAZjERWcz8ktG5uMel8prWwE1V+g0mrlM6aymMi2TYCyj OOydO500InBd2rSwujs5erWH9IJ9UJu4C4jTp0i1ebGovZG5vAbZgUNY6NpE ZCEmaQ2gsJvqyRiY2nOZWMBIjTVqGS4CimrwMYozTzdLen+ybBJop6oG2mcj lfobowoV+KHek2e.7gplIw7AfIu+NLpZDNfnq2QR29TNdMUrxAArWg8hNk2V 5UdMfMJVe97jRRqlSPYaee97xKKtMP63WIVt1CbM6JaUzD8sCXwhvdEJcq8h y2IkXZ0R3PNt.mRQTRVZ8UNjuz8CKu5Hub5kz.VC6CVgQ7AWLEfxqPmtfU38 CVaUWTnEheFm+FsTNsvIE3NTCcGO0v.kpgB3ZIeGwK5dpEtGWTf1huBuXJFw Ve.rv5CvgpLB5RYzdHJQd8AJgBiSW9sPW9CQFPKhNTr.1IVrXf3ArWkDtYZD 2zx06A+9Lp.ifQ0KYR+3EVIHlM0YanQvbAzGR3w8TCC32.dv9cvbOwhRgg4M 4Q65Q0Nth2t48o3nzmBziqtDB52ohS8wAmKAFIxvDERRo+yBVHjZ19yrOOad K4yVDeqvCv2Xh.mmNFduMIa8Wvw0ltY1w3MCYLxXNzO2em5gtZD+RzSRZ8Xe WNuniIzmZGia96aPqwc9xstgNydaNINKsTHZ7lkMWMcU6PQ0EadGRQGZ4coY YIqP4OSJHqRvM1FXpxnTxdlMIkHDGnyo2irma.2XrvoH1XrqXcdVRRigR7KO 2xuDielrF+BIltiOVmAqFYRVSsogQVi16yXqcmO+U1wjXqUXKT5aVxvYmr25 27paSrdLytzTyq9f0syYg0FHH5RORc3UZVkmIwer39Cfk4eSxi2bLIoYV.CF z.09kti5O.L0UAlBCgBzje0wWMl5XJLU34eJBpPEfpacLEBlPX5FRdAcJBo. 8r8qzS+AwzyAAJydnC+o7Yu72aGrKxNlutZoJEcqlxQLtfRROEQ7SmbucQ+1 QhiaFAhuaRhOjw7HKEOqOqkxwPkZ33J0dfxbmEWAAKqdXjVLti6hAFMfUirQ 1xRjtWA5Yb7SrYmoK+DhRyIqNRE5dMR+q6DczHWHU4Z0ZNVc0YVRjqPIxzTO Mg18l217ynv84T.qKyMZfY0606YDWL7yJBhz3ry7W0JHPwgEkMVttdJFQQWp .b4YYX.srWW6h5K32Z5E19YTxwpU60N4sZVslML6G5tGrOo+1lMnbNfsOGsD b9xIgrQ24vs8435jptXJJHudwT7CZ7g2uRbnIvcWO9b4xxwXyc1dfu5pb.8D wT8M2Y6KvIV.K3vqKqmt0ks59fLy8TWmUnH0ifPiUSneikmiiycqlgMJXsFX hq5hCIOClmuwJ976WYCAP05HRXwj0Mjb.+tTUY.PC3XI2whquw4l3uSOU3vw 2SqiFNODETF3FZtpnpCkg7LE5gwP3ngZK6AzfBRZpNxGboznZ7AsMY4ufxiG Okk9xmrpTLtZwnG3+XoZGpFYh35C9KmLIZWRsW45jaFwS73lxnVLXB+VZOZt 8OZ7bnubvldYIaPt5UqJ1GKxxblmFrtuBybXwKW+6Ho68cPCWwQKFOR20hBQ YTt2KFD8T+swHRTR3kaDIPzu1mfiqLGMX3vHPT8X7KBD++JAhe7Le8ktdMI2 gAZQISUZ3SGpCqCc7X0FG47Uw7hnLmRnC5MIgNgKdSCcpHrdYfvKonLwKmZ7 UKRO5mDhpkpghOGIc392v7TOo.S8HnVfkQtSM9omTPIPKa7ny34DgUZcoD0+ mRVoClTR86wW.vunY9tbRwUVdiNUTxxun8AFcUdfQWYg0MGQCIYn5g3tcxFF Jn.TBJBevN5W1TdOZ5yUfPWZ+Kwoqs6aXP2gQeI+.05zUV7sase0t1fjIfBY BBLuLAUgS9FUlJ+eqQMNEMLYB36x+DgDeRHP+SObqBqNJZCUViDhmzhwGViy kpmpXuR7gOAit8ERnFZBPnQ0Db0QQHz3hjpsaXfYsWf53qaf6bxuktx+2.8E ziV8zs5wIRGDzy7HnJEMPjY8Lq0tJv7xjRbx0rxDPGbxr5S.Wc26.FSlBzXq a4vPIX.ONkf72ZObiRZ38OhZUbRGu5QMc7tYYMXDjUOgmWGNddRV8uYOuAZD f27ASUIQAFWhbUHQlMaXcbucKdbYO784+KTFc3sL -----------end_max5_patcher-----------
I wrote a little abstraction to do delayed loadbangs.
The first (optional) argument specifies a delay time in ms. (Optional)arguments after the first one will be sent out as a message after the delay (so it’s loadbang and loadmess with a delay function).
Stick it in a patcher, save it as ‘loadbangdelay’ (that’s how I named it anyway) and put it in the Max path.
----------begin_max5_patcher---------- 665.3ocyV1zbaBCDF9L9WwNb10URX.6dqyzi8Xu0loiLr1Vc.IOHQyWS9uWj DjPRvA6Z2TeHPzpud0y9p0b+jfvUpaPcH7I36PPv8SBBbgrABZaGDVxuIqfq cCKThWqV8qvo9tL3MFW36J.oYKv55XG2jsUH27yJLy3WeJKcFYJPoT6q4KsO YjYD3p14npMEnwb6NzOgvvoM+8X2hb2N0r6eXdZ29rVIMRdoaFgetRvK52iV bmqGJqYy7gk0kBYy13NMrmB52beTavGlLw9X5YAKz2.KoyOaTI4RiJYpxRTZ dEV91VgF3YllGZnPwyWwkalBqpMfoRrYCV0zyZCVAlsHriW0bVL1fa4+FgUH JcyBy6V4BgDyT0R2xOe+vlkrrGsoww1WIrd3tGOOS3jNHNImOSlFKZNfPtRh u00ukdiFwQfT13FMaRYulM1+R3bN8Zes0dAeDr+aIp0v0hlKkY0ZipTn4qJP HGK32BbYNXG.eCN6Gxufq40EMlTiBjpdCwtbyFz5w1O+m6we5r3oPLw0vFZH 1FcjrMYVLkxHK+u39bGUrhWsQCDv6YFoXWxBGJhNkhczKM+Wqu4U7YDhDS7P v8JJxAlj2jHCQiXR7QxCxwT6md9rK9aQjQIBMw80By8DYwn0oF9yDXWZTwO8 w8CQ95ywcOGNouH7Htx2FsqNocUB6cBb6fqZ1K9dPmHswe9wRqpqx5RAs+h. 7jNyQsQH4FgR1aLtLRuQsUjmix9xqTjuSIjlVQvHQ1Bls+Rc7xGa.WMH8OTw 1T9.niH1iTpmnhbWgGEftb96npdYBaepJ9cUUzCwpkb4IoziSRKbd+k9OYMJ oqwImRO3LJ8v0Zq9nKbksSidrwop1jCtrB8uLY2z3gI+AzIZ+UL -----------end_max5_patcher-----------
Be prepared to discover that this scheme (delaying loadbangs) not always works flawlessly. What I found to work better is that a process which has finished (eg loading a file, filling a buffer) triggers the next step in the sequence. And I use deferlow abundantly. The scheduler’s ways are unfathomable (sometimes).
For me Initialization order is the most tricky and mysterious part of Max.
In particular, I wonder how to handle self-initializing live.* objects in combination with loadbang initializations of other objects.
Any comments on this?
@broc, total agreement (as you know!).
i used to think i had a pretty good handle on max initialisation, but since m4l and live.* objects came along, the thing is a minefield. every time i do anything i build test patches which give me different results to the last initialisation-test-patches i made.
so, +1 to broc, any comments always good…
(p.s. – gives me great heart to read the great jvkr’s comment "The scheduler’s ways are unfathomable (sometimes)")…
I think the delay approach is problematic. Generally you should make a clear distinction between startup time and run time which is scheduled time in Max. If you definately want to defer something to the scheduler at startup
defer is a better choice.
In complex patchers it is good to only use one
loadbang object, connected to a
trigger and possibly
receive so that you can initialize sub-modules of your patch in a deterministic way. This would correspond to writing multiple init functions in a programming language, and call them all from the main function.
@Hans – your approach makes perfect sense to me. Thanks for explaining.
So I think the confusion comes only with MaxForLive where Max behaves different in some aspects. But that’s another story..
Hans: The order of send/receive itself is non-deterministic, isn’t it?
it is getting interesting here now.
jvkr is right:
delayed loadbangs sometimes do not work as exspected, for example
when drawing to lcd or loading files from disk, and mostly when the delay is too short.
so be careful what you do, never forget that maxmp is a young girl.
answer to christopher:
for the same reason why you make abstractions in any other situation.
110.loaddels 400 500 600 700 800 900 1000 is simply less writing compared to
loadbang del 400 del 500 del 600 del 700 del 800 del 900 del 1000 and
(the same is true for ordered loadbangs – see my abstraction attached.)
then a little idea about how to organize/find the required load order.
you are the programmer, you must simply decide and take responsibilty yourself.
what can really help to do so, is that you do not put any loadbangs in your
subpatches (except inside abstarctions, where it is unavoidable), but have
a "loadbang-input" to you bigger subpatches and/or bpatchers, in order to
keep overview and/or control the load order.
important for beginners: do not use delays only because you are unsure how
to organize order. learn how to organize order!
The order in which objects of the same name receive messages is (basically) not deterministic, however using a trigger to invoke separately named objects is. The name would correspond to the submodule being initialized, of course.
I use the word "basically", since the first case would actually depend on creation order which is of course subtle.
The following patcher should make this all clear.
----------begin_max5_patcher---------- 912.3ocyXtsbaBCDF9Z6mBUtpcpaFchCt202gdWSlNfQ0lVPxCHWa2L4cuRB HFGKGiS3fugCBgX++jVs6xiSm3DI1wJb.eE7CvjIONcxDSS5FlTc+DmrvcKR CKLcyYgHKiwkNyJeljsSZZ+6rBIPJ.4rTQXL3iwrTlj84M7Xwm.xULv5M4qS Y.QzuYKjfPdLnfw.qDaAQrUg+MQrIGrXUHeIq3C0idZBmsPrga9DjpFShMeP 0.8k.25dx2jkvUeQiQhpZ7WBtjGlwL8+a4IgoM5tXirt+vF8uH4el9iv2U27 5P4hUI7k+LWY4krh.UOEfwDyIntu.ZvcPvC5W4ooS0Gl8NQZX51v8Ef7jkqd 9gMEOdjDOB6azqq9nOsDAcr1yB2qVWbr1OZ0.1BPfi0pg.MCJO5Z3Ag1w7Pj Ct2QBh.Q26XYsf27wZsf6bsdqVR358tVLvYaUh4DsmCBsIYhUICuRIWinxlj 6WyJEliC3gqlFdFJfCJ2cv8.LpdkEhTQdYWg2QcgyClot.iP9dt5qBf9ATh9 p4dTen2.PQ7sGEI3yPw2.LxXEEgKYmPiBoXsEbPsiC7XhC77fRDXHAwDxAEz 0tX6sQC3s2hCD8HeLZ+rgyNKzfL+FjFv4cGMNWrmDtjwiYw.QdLKusQiIAiU HIiGBw0bxMnWBGuMWvWdO+5.h+nEiF0fHkos8lIRzFoTvs4dbgbwWdTvOhuJ .GRGoCVc.0HNocOlHEg+SiQA876dx.bhyUjpvhCNX1fDpIjH90G6XHQuFHAo DDwWKOjWfG1+MSJ0.7b1FtpLLPzNgY9jtCYmYq3BqAlviVoOTyVrnpDc6kzc KrF8AiFKIib6NIeVGCj2qJuVFB8xd4kUrGfaDtj1sSeQ.rsouto1T7qp7Yuj .WSM8k4UpleUUhnx.2sOlk8GjI4xBw6y4XAmUB7SSYtSpen2llq1wtzK10ue 19xVclnQ8WyTu4kcAa3nI8sW7mPMimt8ioPgXS9h5Yj5hnAGBjFyJjI7PYhx G3PmnG0mUIwwLdSMkkDuVnR0txFNyTRqMIRKMIzfYR5pIuwLIcTmKZRX3fNy gaClzYCLz1D5R1DdPsI+1rZ5RlzQ4H6G.IywyrdUyDkegNn95fk00O.Ob2.H vgcYPqbWFDliJyPo6gNsK1JuKTXklHHupjYpu48JvV3IqKke.WVQaAxICa3S 8+5qWinqt4oo+GvNFYas -----------end_max5_patcher-----------
The documentation clearly states:
"The order of reception by two or more receive objects is not deterministic."
So it’s quite simple: if you need deterministic behavior, avoid multiple receivers
(which is easy by giving them different names).
Well it is not uncommon for a behaviour to be deterministic under the hood even if it is not documented/specified. Such behaviour may of course change without warning and should not be relied on.
As I originally stated: use one loadbang, different receivers ;)