Embedding and running 2 or more patches in the same page

Tags: #<Tag:0x00007f703536d5d8>

Hello, this is more of a general question i had .

Was wondering if theres a recommended efficient way of embedding 2 or more patches within a page.
Especially if 2 or more patches utilises the timeline?

Currently im thinking i can just duplicate the patch init for X amount for the amount of patches. but it looks like it’ll get very dirty if i do more than just 2.

and i think sometimes i experience weird glitches for keyframed ops. but i cant be sure yet if its caused by my patch or because of the way the patches conflict each other when embedded together.

I sometimes need to do that too, and found two ways of doing it, depending on the patches you want to use.

So if a) you want to reuse the same patch in different canvases and just change some data through variables, you can do something like this:

const patchFinishedLoading = () => {
  CABLES[this.id].setVariable("src", window.location + 'assets/' + this.src + '.jpg');
  CABLES[this.id].setVariable("loadTexture", 1);
}

CABLES[this.id] = new CABLES.Patch({
  glCanvasId: 'glcanvas' + this.id,
  patch: CABLES.exportedPatch,
  prefixAssetPath: '/',
  glCanvasResizeToWindow: true,
  onError: showError,
  onPatchLoaded: patchInitialized,
  onFinishedLoading: patchFinishedLoading,
});

Note that this example is from a vuejs project, so I’m feeding the src and id from the parent component, but you should be able to use a simple loop here to achieve the same, just make sure the canvas element with the correct id exists in the DOM.

But if you b) have patches that are very different, things get a bit tricky imo, since CABLES.exportedPatch will be different for each patch you want to show. One workaround I found feels very inelegant, and I hope the devs can shed some light on a better solution. But it goes as follows: each of the patches needs to be exported as multiple files. If you want to use a loop, name each exported json something like “project-0.json”, “project-1.json” and so on. then you can do this, and later access each patch by eg. CABLES.patch[3].pause():

CABLES.patch = [];
const numberOfScenes =  5;
document.addEventListener('CABLES.jsLoaded', function(event) {
  for (var i = 0; i < numberOfScenes - 1; i++) {
    CABLES.patch[i] = new CABLES.Patch({
      patchFile: 'js/project-' + i + '.json',
      prefixAssetPath: '',
      glCanvasId: 'canvas-' + i,
      glCanvasResizeToWindow: true,
      onError: showError,
      onPatchLoaded: patchInitialized,
      onFinishedLoading: patchFinishedLoading,
    });
  }
});

The problem is though, that each patch has different ops referenced in the patch json. So you need a master patch, which only references all ops used across all patches once. the ops don’t need to be connected or anything, you just need to export the patch and include the ops.js from this master patch. the “libs.core.min.js” and “cables.min.js” can come from any patch. As I said, that can get very finicky very fast, since you always need to update the master patch by hand, if you change one of the other patches. But this is a quick workaround I found when I had this use-case. So if there is a better solution I am all ears!

And I never really used the timeline, so not sure if it interferes with the methods above.

Hi Artur. Thanks for the the detailed breakdown.

I think what im trying to do is to have more than 1 patch visible and ‘playing’ at the same time in the same page. In your ‘B’ method, it describes playing 1 patch at a time yes?

Also i’m wondering what you mean by master patch. You mean having 1 of the patches have its cables library referenced by the others yes?

No problem, let me try to lift the confusion

In your ‘B’ method, it describes playing 1 patch at a time yes?

No, each canvas with this method behaves like a regular standalone patch, they all can play at the same time.

Also i’m wondering what you mean by master patch. You mean having 1 of the patches have its cables library referenced by the others yes?

The master patch is just a workaround so you don’t get a reference error for missing ops code. Lets say you have three patches, all of them use imagecompose and draw image ops. the first one uses on top of that an orbitcontrol op, but the others dont. if you export the second patch as multiple files for method B) and include this ops.js, you get a reference error, because this particular ops.js does not know/include the code for the orbitalcontrol op. if you export the first patch though, the exported ops.js includes the code for orbitalcontrols, drawimage and imagecompose, because all these ops were used in this particular patch and you wont get an error, because the other patches are able to use the same ops.js. if you then add a lets say a performance op to the second patch, you will again get a reference error, because you still use the ops.js from the first patch. the workaround is, to just add a performance op to the first patch as well and export it again, it does not even need to be connected to the mainloop, it just needs to be there so the ops.js will include the code. thats what i meant with “master patch”, just a patch, that has all the ops in it which are used in the other patches you want to show.

So, if working with multiple files when you export a patch, you need to know, that:

ops.js - includes the code for each op used in the editor of this particular patch
project.json - includes the order of execution, so the node connections in the patch, but does not “know” what the ops are actually doing but looks for the code inside ops.js.
cables.min.js - handles the logic. this file is always the same, regardless of what ops you use.
libs.core.min.js - libraries and helper. this file is also always the same.

also @devs if i am talking nonsense let me know - this is just what i assume after working for a while with cables extensively… a better solution than my workaround would be great.

ah thats very interesting! i’ve never worked with multiple files, always Single Javascript file

and what i found in single js exports is that in patch.js, all the code outside of CABLES.exportedPatch is identical regardless of the patch. essentially in single js export versions, the declared CABLES.exportedPatch is similar to the json in found in multiple file formats it seems. and this is referenced in the ‘patchFile’ option when instancing a new new Cables.Patch in javascript.

so thats why i was abit confused about needing a master patch, cause i think in the single file exports, all the necessary ops for each patch are self contained within CABLES.exportedPatch. (correct me if im wrong devs or anyone else)

I’m now starting to wonder if it’ll makes things simpler for me if i worked with a multiple js export flow in trying to accomplish this