jussi-kalliokoski / webmidi-issues

A test repo for importing the issues from bugzilla
0 stars 0 forks source link

MIDIEvent should have a port attribute #6

Open jussi-kalliokoski opened 11 years ago

jussi-kalliokoski commented 11 years ago

Originally reported on W3C Bugzilla ISSUE-20502 Mon, 24 Dec 2012 08:12:47 GMT Reported by Marcos Caceres Assigned to This bug has no owner yet - up for the taking

In situations where there are multiple sources attached to a device, it is important to distinguish which MIDI output emitted a particular message. As such, I recommend adding a port attribute to the MIDIEvent interface:

interface MIDIEvent : Event { readonly attribute MIDIPort port; ... }

jussi-kalliokoski commented 11 years ago

Original comment by Marcos Caceres on W3C Bugzilla. Mon, 24 Dec 2012 10:27:05 GMT

On Monday, 24 December 2012 at 07:42, Jussi Kalliokoski wrote:

Yes, actually I thought that for events on an EventTarget, both "this" and ".target" would automatically be the port, but now that I checked, it seems that >only the former is true.

But then you still have two objects that are disjoint ("this" and the MIDIEvent instance). It would be nicer, IMO, to have them combined (specially because there can be multiple sources for an event, and a single listener).

There is precedence for knowing the "source" of the event. For instance, Web Messaging has a "source" attribute.

There is also GamepadEvent, which has: readonly attribute Gamepad gamepad; http://dvcs.w3.org/hg/gamepad/raw-file/tip/gamepad.html#gamepadevent-interface

But that being the case, I think we should use ".target", rather than introduce a new way of reporting the target.

According to DOM4, the event.target "Returns the object event is dispatched to." Not the object it was dispatched from.

For example, in Web Messaging. If I postMessage some data from document A to iframe "Document B", I get:

e.source.document.title === "Document A"; e.target.document.title === "Document B";

In any case, I find .target confusing. It's also more confusing because you also have the sourceElement attribute, which will probably have to also be set.

jussi-kalliokoski commented 11 years ago

Original comment by Chris Wilson on W3C Bugzilla. Tue, 25 Dec 2012 20:40:12 GMT

Can't you easily set this up by binding the onmessage handler?

jussi-kalliokoski commented 11 years ago

Original comment by Marcos Caceres on W3C Bugzilla. Tue, 25 Dec 2012 21:00:31 GMT

(In reply to comment #2)

Can't you easily set this up by binding the onmessage handler?

It's probably not a good idea to use the onmessage handler because it can be overridden by anyone (please also see issue at bottom of this reply). Also, to set that up requires some minor gymnastics when you could just get it for free from the event itself.

Like: var recording = []; for(....; i++){ midiaccess.getInputs()[i].addEventListener('message', function (e) { var instrument = {port: this, event: e};
recording.push(instrument); //or e.port = this; recording.push(e); });

The second case above kinda sucks because it's not nice to add things to object that you don't own (in this case a MIDIEvent).

Actually, that brings up a separate issues I forgot to raise: is the MIDIAccess object a singleton? As in:

a = navigator.requestMIDIAccess(); b = navigator.requestMIDIAccess();

a === b?

In the spec, this is currently unclear in 5.1.1: "success: Let access be the MIDIAccess object for which access has been granted."

Which kinda reads like the spec is assuming requestMIDIAccess() will not be called repeatedly.

Need to file a separate bug for the above, but some clarification would be good.

jussi-kalliokoski commented 11 years ago

Original comment by Chris Wilson on W3C Bugzilla. Tue, 25 Dec 2012 21:06:17 GMT

(In reply to comment #3)

(In reply to comment #2)

Can't you easily set this up by binding the onmessage handler?

It's probably not a good idea to use the onmessage handler because it can be overridden by anyone (please also see issue at bottom of this reply).

"Can't you easily set this up by binding the message handler (onmessage or addEventHandler function)?" Binding is on the function object, irrelevant of onmessage or addEventHandler.

Also, to set that up requires some minor gymnastics when you could just get it for free from the event itself.

Well, it's not totally "free" - because it would have to be set on the event object for each call then - but not very expensive, I suppose.

Like: var recording = []; for(....; i++){ midiaccess.getInputs()[i].addEventListener('message', function (e) { var instrument = {port: this, event: e};
recording.push(instrument); //or e.port = this; recording.push(e); });

The second case above kinda sucks because it's not nice to add things to object that you don't own (in this case a MIDIEvent).

Well, but this leads me to believe it's not a good idea, because it will encourage the use of adding things to the MIDIPort (to get back to your own code), and binding (in the rare case that you would need a pointer back to your objects that isn't just a function pointer).

jussi-kalliokoski commented 11 years ago

Original comment by Marcos Caceres on W3C Bugzilla. Tue, 25 Dec 2012 21:24:00 GMT

(In reply to comment #4)

(In reply to comment #3)

(In reply to comment #2)

Can't you easily set this up by binding the onmessage handler?

It's probably not a good idea to use the onmessage handler because it can be overridden by anyone (please also see issue at bottom of this reply).

"Can't you easily set this up by binding the message handler (onmessage or addEventHandler function)?" Binding is on the function object, irrelevant of onmessage or addEventHandler.

Maybe I'm not getting what you mean here. Are you literally saying use .bind()? Or something else?

Also, to set that up requires some minor gymnastics when you could just get it for free from the event itself.

Well, it's not totally "free" - because it would have to be set on the event object for each call then - but not very expensive, I suppose.

Like: var recording = []; for(....; i++){ midiaccess.getInputs()[i].addEventListener('message', function (e) { var instrument = {port: this, event: e};
recording.push(instrument); //or e.port = this; recording.push(e); });

The second case above kinda sucks because it's not nice to add things to object that you don't own (in this case a MIDIEvent).

Well, but this leads me to believe it's not a good idea, because it will encourage the use of adding things to the MIDIPort (to get back to your own code), and binding (in the rare case that you would need a pointer back to your objects that isn't just a function pointer).

Oh, my example was supposed to be all bad - I'll see if I can come up with a real usage scenario as I just made that on up on the spot. In any case, I think we might be misunderstanding each other, but I can understand the need for a good justification to adding this.

I might need a stronger use case. At the moment, this might just fall into the "nice to have" category.

I'll also be honest: I didn't know that "this" would become the port itself before Jussi mentioned it. It makes sense, but I wonder if many developers know about that.