Skip to content

Multiple components#1566

Merged
fernandojsg merged 1 commit intoaframevr:masterfrom
dmarcos:multipleComponents
Jun 30, 2016
Merged

Multiple components#1566
fernandojsg merged 1 commit intoaframevr:masterfrom
dmarcos:multipleComponents

Conversation

@dmarcos
Copy link
Member

@dmarcos dmarcos commented Jun 19, 2016

Description:

It allows defining multiple component of a specific kind by appending an id to the component name followed by a __ character. e.g:

el.setAttribute('sound__1', { src: '...' });
el.setAttribute('sound__explosion', { src: '...' });

Components have to opt into multiplicity otherwise an error is thrown.

This PR depends on #1565

Needs feedback from @fernandojsg

@ngokevin
Copy link
Member

The overall API looks good to me. We might consider a double underscore to further make it look different from normal component name hyphens (like OOCSS namespaces).

@fernandojsg
Copy link
Member

I agree with @ngokevin having double underscore maybe looks uglier but it will make it easier to differentiate between normal components and multiple instances

@fernandojsg
Copy link
Member

I'm trying this PR on the editor. Please share what you think about the way to show this feature: aframevr/aframe-inspector#72 /cc @ngokevin @dmarcos

@fernandojsg
Copy link
Member

I've been playing with your example examples/test/cube:
Querying each component return the expected results:
screenshot 2016-06-29 11 03 07

But when I try to change one instance's attribute something weird happens: it generates a new sound component, copying the same values from sound_2 but the volume is being copied as string instead of number.
screenshot 2016-06-29 11 04 59

@fernandojsg
Copy link
Member

fernandojsg commented Jun 29, 2016

It fails just on debug=true as in the flushToDOM you're using just the this.name for the component (sound) instead of the whole component_id name:
This:

  flushToDOM: function () {
    var attrValue = this.attrValue;
    if (!attrValue) { return; }
    HTMLElement.prototype.setAttribute.call(this.el, this.name, this.stringify(attrValue));
  },

Should be something like:

  flushToDOM: function () {
    var attrValue = this.attrValue;
    if (!attrValue) { return; }
    var nameId = this.name + (this.id ? '_' + this.id : '');
    HTMLElement.prototype.setAttribute.call(this.el, nameId, this.stringify(attrValue));
  },

I'm thinking also about componentChanged event:

    el.emit('componentchanged', {
      name: this.name,
      newData: this.getData(),
      oldData: oldData
    });

With the current implementation it will emit just sound name event without any additional information, we should add the full name sound_{id} or at least an additional id parameter

@dmarcos dmarcos force-pushed the multipleComponents branch 4 times, most recently from 0c476eb to 0506450 Compare June 30, 2016 00:19
var id = this.id;
this.listener = null;
this.sound = null;
this.object3DName = id ? 'sound-' + id : 'sound';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why don't we use here the same style as the component's name? sound__

@dmarcos dmarcos force-pushed the multipleComponents branch from 0506450 to 7dcea81 Compare June 30, 2016 01:06
@fernandojsg fernandojsg merged commit 89388c0 into aframevr:master Jun 30, 2016
value: function (name, data, isDependency) {
var component;
var componentInfo = name.split('__');
var id = componentInfo[1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this error? 'geometry'.split('__')[1]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name componentId might help differentiate from just HTML ID.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will return undefined, we could leave it that way or do something like componentInfo[1] || null. In any case it should works as expected on the rest of the code where the full name is built using: componentName = id ? component + '__' + id : component and both undefined or null will return false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it just returns undefined

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

umm, maybe instanceId ? and the componentId could be the whole name componentName__instanceId?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the id has to be still easily accessible. Each component is going to handle multiplicity in a different way and it's nice to have access to the id directly without having to parse any string. I can add this.name, this.attrName, this.id to the component.


if (name.indexOf('__') !== -1) {
throw new Error('The component name `' + name + '` is not allowed. ' +
'The sequence __ (double underscore) is reserved and cannot be used ' +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would update to The sequence__(double underscore) is reserved for multiple components of the same type. since the "cannot be used" is sort of restating the first sentence

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants