Tonejs / Tone.js

A Web Audio framework for making interactive music in the browser.
https://tonejs.github.io
MIT License
13.45k stars 977 forks source link

Tone.Emitter.on() not responding to .emit()? #1176

Closed tmhglnd closed 5 months ago

tmhglnd commented 1 year ago

Hi!

I'm trying to use the Tone.Emitter(), and maybe i'm not understanding how the object exactly works. What i'm trying to do is create an Tone.Emitter() instance in a class that is emitting events, and another Tone.Emitter() in another class that is listening for those events and calling a function as callback. My code looks something like this:

this.emitter = new Tone.Emitter();
this.loop = new Tone.Loop((time) => {
  this.emitter.emit('myEvent', time);
}

Then somewhere else I have

this.emitter = new Tone.Emitter();
this.emitter.on('myEvent', (time) => console.log(time));

Based on the documentation it looks like this should be working, but I don't see anything logged to the console. Maybe i'm missing something. Any help would be appreciated!

DarshanDixit05 commented 1 year ago

I want to work on this , can you please assign it to me ?

tmhglnd commented 1 year ago

Would be amazing if this could be fixed (or explained how it should work). Thanks a lot if you can work on this!

tambien commented 5 months ago

Just checked, and this works fine for me:

const emitter = new Emitter();
emitter.on("test", (arg) => {
    console.log('emitted', arg)
});
emitter.emit("test", 100);

Maybe the Tone.Loop is never being started?

tmhglnd commented 5 months ago

Yes, that works, true! But what I was trying to do is have 2 different classes with individual Tone.Emitter's and let the emitters send/receive from eachother. Like so:

import { Emitter } from "tone";

const receiver = new Emitter();
receiver.on("test", (msg) => {
  console.log("emit received!", msg);
});

const emitter = new Emitter();
emitter.emit("test", "send from other Emitter");

But it seems this is not a feature that is implemented? Or maybe I'm missing something. It was not super obvious to me based on the documentation.

Anyways, in the meantime I have created a workaround, which actually works quite well so far:

// in the emitter class passing the time of that class through the event to the receiver
let event = new CustomEvent("test", { detail: { value: 1, time: time } })
window.dispatchEvent(event)

// in the receiver class using the time value
window.addEventListener("test", (event) => { 
    if (event.detail.value > 0){
        // trigger some Tone process with event.detail.time
    }
});
tambien commented 5 months ago

Emitter events are just on the single Emitter, not global to all Emitters. If you're looking for a global event, i think the way you're doing it looks great!