JS autowatch issue when used with JS require.


    Oct 15 2020 | 10:50 pm
    Hi, I use to use the 'autowatch = 1' feature in my JS files in order to recompile them automatically after an edit. Since I use the JS require mechanism to split my JS code in several parts, it seems that the autowatch mechanism gets a bit buggy and I can't figure why... Can you help me ? The context I'm currently designing a MIDI editor for a hardware synth with Max for Live. My design is based on an MVC pattern. My model and my controller are pure JS patchers. The controller includes a viewManager.js file (with JS require) to communicate with the view, which is a standard Max patcher. The view contains classical UI objects, the JS code uses a ParameterListener object in order to control the UI objects (set/get). So no patch chords are required to make the controller and the view communicate with each other.
    The problem At dev time, when I edit my code in the viewManager.js and save it, it seems to be not recompiled automatically with autowatch. Indeed, when I change the dial's value in the view, the Max console outputs strange 'ghost' values that look like the previous ones I've used in my code ! And if I edit my code many times, it seems that the Max console outputs the 'history' of all my edits, that is really disturbing... Please help ! I've built a simple example project with Max 8.1.7 in order to demonstrate the issue I encounter with the JS autowatch property, when used with JS require. I would appreciate if someone could : • download and unzip my Max example project (Max 8.1.7 required because of the new ParameterListener 'silent' mechanism) • open the 'jsAutowatchIssue.amxd' project in Max (I'm an Ableton Live user) • open the 'view' patcher (in blue) • open the controller.js and the viewManager.js files in an external text editor (I use TextMate) • have a look at the 'onDialChanged' function in viewManager.js • do the first and second tests step by step, as described in my comments • let me know what are the outputs in the Max console
    Thank you for your help :) Regards, Guillaume

    • Oct 16 2020 | 12:46 am
      Requested access. Low tech solution, but if it's just autowatch that is resulting in problems you could maybe use [filewatch] object and then call compile on your js again.
    • Oct 16 2020 | 6:38 am
      Sorry for the restricted sharing, my Google Drive link should work now. Thank you for the filewatch idea, I'll have a look !
    • Oct 16 2020 | 8:22 am
      I've done some more tests this morning and I start to think the problem is not due to the autowatch option. Actually, if I edit let's say a string in one of my debug post(), the new string appears as expected in Max console after saving the JS files and initing my M4L device. So I'm pretty sure my JS files are recompiled as expected. The 'history' 'ghost' outputs I get with my code in Max console seems to be in relation with the variable returned by the require() function itself. Apparently require() returns a jsobject, and when I debug it I get a negative value, I guess it's a kind of pointer or address. It looks like a new 'pointer' is created by require() each time I run my code, and that the previous 'pointers' are still active in memory. So their onParameterChange() function may still be active too, which could explain the 'history' output I get. Am I right ? Is there a way to notify the garbage collector to delete these plausible 'previous pointers' ? I don't know how I can inspect the variable returned by require() a bit more. I know that a getprop() function exists for jsobject, but I don't know what to pass as arguments to get info from the variable... An idea ?
    • Oct 16 2020 | 10:31 am
      This is a limitation/bug in the current implementation of jsrequire. We're looking into it, thanks for bringing it to our attention!
    • Oct 16 2020 | 11:09 am
      Hi Jeremy, Great ! I'm happy you've found the problem with JS require. While an improvement is under study, I will rename my main js patcher each time I'll have to edit my JS subcode, it seems to avoid the problem of multiple ghost outputs from JS require. Cheers. Guillaume
    • Apr 04 2021 | 5:20 am
      Guillaume,
      I'm doing nearly the same thing you have described. I'm writing an editor for a hardware synth. I have three .js files: one that handles interaction with the synth, one that defines the dictionary of params for the synth, and one that interacts with the UI controls.
      I've put post("loaded module v0.1 \n") commands at the top of each .js script. Even though the updated version number in the top line shows up properly in the console when I save, the function I am working on fails to recompile, and my edits are ignored.
      I have to close the project and reload it for my edits to be seen.
      Rick
    • Apr 04 2021 | 9:23 am
      Hi Rick, What Max version do you use ? I encountered this issue while I was developing under Max 8.1.7. I've reported the problem to Jeremy @C'74 (see older posts above), and normally the bug has been resolved since then. Have you tried to double click on the name of your main JS patcher, like if you would like to rename it, and then press enter ? This trick seems to force the autowatch mecanism and should help you to reload the last versions of your edited JS patchers. Guillaume
    • Apr 04 2021 | 5:39 pm
      Guillaume,
      Thanks for the speedy reply! I was using 8.1.8. I've now installed 8.1.10 and the problem persists.
      I tried your suggestion to double-click the name of my main JS patcher. That didn't work, but it led me to try closing only the patcher (instead of the project), then reloading with the double-click on the main patcher in the Project window. That caused the .js to be properly reloaded.
      The thing that has me scratching my head is that the autowatch appears to be working (at least partially). That is, in the main body of the .js updated post() commands are reflected in the console "automagically" when the file is saved. That led to me believe that autowatch was working. The problem is that functions within the .js are not reloaded, and fail to produce updated post() commands.
      Thanks again,
      Rick
    • Apr 07 2021 | 9:18 am
      You're welcome Rick :)