pattrhub shortcomings and a nice crash


    Apr 16 2022 | 7:24 am
    I'm somehow underwhelmed by the pattr snakepit of objects. For all its bloat and complexity, it doesn't go to 100%, and can crash.... read on. In the control patch below, I'm trying to refer, via [pattrhub ::testui], to a remote top-level UI patcher that contains a [pattrmarker testui].
    1. I'd expect pattrhub to also send me changes made to parameters in the remote patch, like pattrstorage can do with @outputmode, but that works only in the remote patch, DUH!
    2. When the remote patch is not open *before*, pattrhub ignores its arg (and you need to resend the "patcher") message, so no loadbang will do, but one needs to devise a send/receive logic where the remote patch says "I'm here now". I'd expect pattrhub to be notified that the pattrmarker is created (by loading the remote patch or creating it), and connect automatically.
    3. Once connected, after closing the remote UI patch, pattrhub crashes when trying to change a remote param:
    Thread 0 Crashed:: CrBrowserMain  Dispatch queue: com.apple.main-thread
    0   com.cycling74.Max             	0x00000001018528c6 object_attr_get + 38
    1   com.cycling74.Max             	0x00000001018993a3 object_attr_getvalueof_imp + 99
    2   com.cycling74.Max             	0x0000000101853627 object_attr_getobj + 55
    3   com.cycling74.pattrhub        	0x0000000126dd97c2 pattrhub_resolve_object_impl + 146
    4   com.cycling74.pattrhub        	0x0000000126dd7ab2 pattrhub_anything + 194
    5   com.cycling74.Max             	0x000000010187e8e3 typedmess_fun + 371
    6   com.cycling74.Max             	0x0000000101869bb2 outlet_anything + 1426
    7   com.cycling74.Max             	0x000000010187e8e3 typedmess_fun + 371
    8   com.cycling74.Max             	0x0000000101848f9a aeval + 2314
    9   com.cycling74.Max             	0x000000010184863e atombuf_eval + 142
    10  com.cycling74.message         	0x0000000107741a17 jmessage_atombuf_eval + 567
    11  com.cycling74.message         	0x000000010773f68f jmessage_int + 175
    12  com.cycling74.Max             	0x000000010187c878 outlet_int + 1560
    13  com.cycling74.number          	0x00000001276dc029 jnumber_mousedragdelta + 409
    

    • Apr 22 2022 | 5:30 pm
      For the record: I got the additional tip to look at the patcher inspector for the parent and the child's "global patcher name" attribute. the pattrmarker sets the parent's one and then refuses to set the child to the same name when encapsulating.
    • Apr 25 2022 | 3:35 pm
      Thanks, looks like you've found some bugs and oversights, which we'll take a look at. In particular, I think we can improve the automatic registration/unregistration in pattrhub, which probably haven't been significantly updated since the objects were originally added to Max. Obviously, crashes aren't ideal, so keep an eye open for improvements.
      As for the global patcher name issue (which tip I gave you on Facebook), I think we can improve how pattrmarker handles name conflicts (looks like it just fails at the moment). I need to think about your expectation that encapsulation of a pattrmarker object moves the global patcher name. We could certainly provide some ways for pattrmarker to inform you when the wish-name doesn't match the real-name, but I don't know if moving the object should automove the name.
      Here's why: the pattrmarker object modifies a patcher attribute; if you delete the pattrmarker object entirely, the global patcher name is retained, and in fact, you never even need a pattrmarker object in order to award this name to a patcher, you can just type it in the inspector. This has roots in the evolution of pattrmarker from a 3rd party object/feature to a core object/feature, and that's just how it is. But I don't know if it's appropriate for an encapsulation to change attributes in the parent patcher. On the other hand, the presence of a pattrmarker is a fairly good indication that you're explicitly assigning that attribute using the pattrmarker object mechanism, so it's worth thinking through.
    • Apr 25 2022 | 4:03 pm
      > As for the global patcher name issue (which tip I gave you on Facebook),
      thanks indeed, you understood my question and situation better than myself!
      > I think we can improve how pattrmarker handles name conflicts (looks like it just fails > at the moment). I need to think about your expectation that encapsulation of a > pattrmarker object moves the global patcher name. We could certainly provide > some ways for pattrmarker to inform you when the wish-name doesn't match the > real-name, but I don't know if moving the object should automove the name.
      Yes, a warning would already be helpful (but could be missed when it is output only when encapsulating... don't know if that name mismatch state could be warned about at each patch load.)
      > Here's why: the pattrmarker object modifies a patcher attribute; if you delete > the pattrmarker object entirely, the global patcher name is retained, and in > fact, you never even need a pattrmarker object in order to award this name to a > patcher, you can just type it in the inspector. This has roots in the evolution > of pattrmarker from a 3rd party object/feature to a core object/feature, and > that's just how it is. But I don't know if it's appropriate for an encapsulation > to change attributes in the parent patcher. On the other hand, the presence of a > pattrmarker is a fairly good indication that you're explicitly assigning that > attribute using the pattrmarker object mechanism, so it's worth thinking through.
      If that's an option, I'd definitely be for making the "global patcher name" attr editable, and make pattrmarker optional. It would make for one less member in that unwieldy zoo of pattr* objects (one less moment of head scratching "what is this good for? do I really need to remember this object?"). While we're rethinking this for simplification options, couldn't the patcher name be defined by the scripting name? That's one thing everyone is already used to, and easy to reach via CMD-'.
      Thanks a lot for caring!... ...Diemo
    • Apr 26 2022 | 1:30 pm
      Another crash when setting from OSC, investigating...
      Thread 0 Crashed:: CrBrowserMain Dispatch queue: com.apple.main-thread 0 com.cycling74.Max 0x00000001063b48c6 object_attr_get + 38 1 com.cycling74.Max 0x00000001063fb3a3 object_attr_getvalueof_imp + 99 2 com.cycling74.Max 0x00000001063b5627 object_attr_getobj + 55 3 com.cycling74.pattrhub 0x000000011737d7c2 pattrhub_resolve_object_impl + 146 4 com.cycling74.pattrhub 0x000000011737bab2 pattrhub_anything + 194 5 com.cycling74.Max 0x00000001063e08e3 typedmess_fun + 371 6 com.cycling74.Max 0x00000001063cbbb2 outlet_anything + 1426 7 com.cycling74.Max 0x00000001063e08e3 typedmess_fun + 371 8 com.cycling74.Max 0x00000001063e08e3 typedmess_fun + 371 9 com.cycling74.Max 0x00000001063cbbb2 outlet_anything + 1426 10 com.cycling74.Max 0x00000001063e08e3 typedmess_fun + 371 11 com.cycling74.Max 0x00000001063aaf9a aeval + 2314 12 com.cycling74.Max 0x00000001063aa63e atombuf_eval + 142 13 com.cycling74.message 0x000000012b4cba17 jmessage_atombuf_eval + 567 14 com.cycling74.Max 0x00000001063dfb06 outlet_list + 1398 15 com.cycling74.Max 0x00000001063df1b2 outlet_float + 1458 16 com.cycling74.scale 0x000000012bae55f8 scale_float + 856 17 com.cycling74.Max 0x00000001063df3a3 outlet_float + 1955 18 com.cycling74.Max 0x00000001063ddd79 outlet_bang + 1385 19 com.cycling74.Max 0x00000001063ddd79 outlet_bang + 1385 20 com.cycling74.Max 0x00000001063ddd79 outlet_bang + 1385 21 com.cycling74.Max 0x00000001063ddf50 outlet_bang + 1856 22 com.cycling74.Max 0x00000001064db736 trigger_iterate + 86 23 com.cycling74.Max 0x00000001064db5f5 trigger_anything + 37 24 com.cycling74.Max 0x00000001063e08e3 typedmess_fun + 371 25 com.cycling74.Max 0x00000001063cbbb2 outlet_anything + 1426 26 com.cycling74.Max 0x00000001063e08e3 typedmess_fun + 371 27 com.cycling74.Max 0x00000001063cbbb2 outlet_anything + 1426 28 com.cycling74.udpreceive 0x000000012a60229a osc_parse_osc_packet + 1866 29 com.cycling74.udpreceive 0x000000012a601a30 udprecv_clock_tick + 80
    • Apr 26 2022 | 2:30 pm
      Diemo, this is the same crash as above, don't go to any extra effort to isolate it.
    • Apr 27 2022 | 10:56 am
      If that's an option, I'd definitely be for making the "global patcher name" attr editable, and make pattrmarker optional. It would make for one less member in that unwieldy zoo of pattr* objects (one less moment of head scratching "what is this good for? do I really need to remember this object?").
      This is already the case -- the global patcher name attribute is always available to be set, even without a pattrmarker object. The reason it's not synonymous with the patcher's scripting name is that every patcher in a pattr hierarchy has a name for navigation purposes, but you don't generally want those patchers to be available as "pattrmarked" top-level nodes. Also, pattr/scripting names are patcher-local, while pattrmarker names are global.
      I'm still thinking about the name-moves-with-pattrmarker-object expectation, but I'm not 100% convinced. In some ways, it's a question of what is easier to document. In any case, the name collision issue needs to be sorted for people using pattrmarker/global patcher name inside of abstractions/poly~/etc.
      I've fixed the pattrhub registration issues, though (and thus the crash), and that fix will eventually make it into an updated Max. But I can't say when at this moment...
    • Apr 27 2022 | 11:51 am
      @Diemo, my mistake, looks like there's a bug in the way the attribute is presented to the inspector so that the field isn't editable if a pattrmarker object is instantiated anywhere. Clearly not ideal.
    • Apr 27 2022 | 2:16 pm
      i guess it' not editable because if you were to change it manually, the next patcher restart would trigger the instantiation of pattrmarker and hence re-change the patcher's scripting name ?
    • Apr 27 2022 | 6:27 pm
      @vichug yeah, that's correct. the next version will still be uneditable, but only if a pattrmarker is in the patcher in question. If there's no pattrmarker providing the name, that field will be editable.
    • Apr 27 2022 | 7:19 pm
      Hi Jeremy, thanks for the clarification of patcher name/scripting name. It makes complete sense. What do you think about the expectation that pattrhub also output param changes in the remote patch (with an appropriate @outputmode), and thus make it an actual bidirectional hub, not just a control object? That would allow to completely take over (i.e. link to a hw controller) an existing (sub)patch, without having to instrument it by pattrstorage and send objects.
    • Apr 27 2022 | 7:22 pm
      @diemo sounds reasonable to me, but no promises. pattrhub was originally a fairly primitive object which was largely ignored when pattr, pattrstorage and friends became more complicated (since no one seemed to use it very much). I'm definitely open to making it more useful, and most of the infrastructure is available to do so.
    • May 13 2022 | 4:53 pm
      Hi again, another occasional pvar crash when closing a patch, don't know if it's related (and thanks for the hopeful response to the pattrhub suggestion, BTW):
      Thread 0 Crashed:: CrBrowserMain  Dispatch queue: com.apple.main-thread
      0   com.cycling74.Max             	0x000000010601c115 pvar_free + 213
      1   com.cycling74.Max             	0x0000000105f803ce freeobject + 190
      2   com.cycling74.Max             	0x0000000105ef296a jnewobj_free + 26
      3   com.cycling74.Max             	0x0000000105f803ce freeobject + 190
      4   com.cycling74.Max             	0x0000000105f7725b object_free + 27
      5   com.cycling74.Max             	0x00000001060418ef jpatcher_free + 319
      6   com.cycling74.Max             	0x0000000105f803ce freeobject + 190
      7   com.cycling74.Max             	0x0000000105f7725b object_free + 27
      8   com.cycling74.Max             	0x0000000105f736e0 object_method_imp + 352
      9   com.cycling74.Max             	0x0000000105cc7fcc jwind_close + 1052
      10  com.cycling74.Max             	0x0000000105f87794 object_method_typed + 148
      11  com.cycling74.Max             	0x0000000105eec54f jmenuitem_process + 559
      12  com.cycling74.Max             	0x0000000105eec2fd jmenu_process + 141
      13  com.cycling74.Max             	0x0000000105e17f4b interface_process + 11
      14  com.cycling74.Max             	0x000000010636ebec juce::JuceMainMenuHandler::invokeDirectly(int, int) + 60
      15  com.cycling74.Max             	0x000000010636eb54 juce::MessageManager::AsyncCallInvoker<juce::JuceMainMenuHandler::invoke(juce::PopupMenu::Item const&, int) const::'lambda'()>::messageCallback() + 52
      16  com.cycling74.Max             	0x000000010624b36d juce::MessageQueue::runLoopSourceCallback(void*) + 269
      17  com.apple.CoreFoundation      	0x00007fff32adad17 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
      18  com.apple.CoreFoundation      	0x00007fff32adacbd __CFRunLoopDoSource0 + 108
      19  com.apple.CoreFoundation      	0x00007fff32abe67b __CFRunLoopDoSources0 + 195
      20  com.apple.CoreFoundation      	0x00007fff32abdc45 __CFRunLoopRun + 1189
      21  com.apple.CoreFoundation      	0x00007fff32abd54e CFRunLoopRunSpecific + 455
      22  com.apple.HIToolbox           	0x00007fff31d1c1ab RunCurrentEventLoopInMode + 292
      23  com.apple.HIToolbox           	0x00007fff31d1bee5 ReceiveNextEventCommon + 603
      24  com.apple.HIToolbox           	0x00007fff31d1bc76 _BlockUntilNextEventMatchingListInModeWithFilter + 64
      25  com.apple.AppKit              	0x00007fff300b377d _DPSNextEvent + 1135
      26  com.apple.AppKit              	0x00007fff300b246b -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1361
      27  com.apple.AppKit              	0x00007fff300ac588 -[NSApplication run] + 699
      28  org.cef.framework             	0x000000010fab43bc base::mac::CxxPersonalityRoutine(int, _Unwind_Action, unsigned long long, _Unwind_Exception*, _Unwind_Context*) + 4764
      29  org.cef.framework             	0x000000010fab31d3 base::mac::CxxPersonalityRoutine(int, _Unwind_Action, unsigned long long, _Unwind_Exception*, _Unwind_Context*) + 179
      30  org.cef.framework             	0x000000010fa723bd uhash_compareUnicodeString_69 + 754989
      31  org.cef.framework             	0x000000010fa3e3fd uhash_compareUnicodeString_69 + 542061
      32  org.cef.framework             	0x000000010f722d3b __gxx_personality_v0 + 401403
      33  com.cycling74.Max             	0x0000000105dceb82 MaxCefEventLoopHandler::runMessageLoop() + 18