[x3d-public] getContainerField() [was cobweb DOM integration]

doug sanden highaspirations at hotmail.com
Mon Oct 10 13:48:30 PDT 2016


H: If there is a function to iterate over a nodes fields, a function to get the abstract node type of a field, and a function to get a list of the abstract interfaces supported by a node, then a matchmaker function could iterate over the fields of a parent node till it finds an abstract node type match.
With higher/highest/most-derived-type match preferred.
________________________________________
From: Andreas Plesch [andreasplesch at gmail.com]
Sent: October 10, 2016 1:47 PM
To: Roy Walmsley
Cc: X3D Graphics public mailing list; doug sanden
Subject: RE: [x3d-public] getContainerField() [was cobweb DOM integration]

Hi Roy,

On Oct 10, 2016 10:27 AM, "Roy Walmsley" <roy.walmsley at ntlworld.com<mailto:roy.walmsley at ntlworld.com>> wrote:
>...
> Q1 – Usually (always) just one field for a given parent nodetype. I don’t have an exhaustive answer, but I will give an example. It may be the only one, not sure. Look at the Collision node, (19775-1, 23.4.2, http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/navigation.html#Collision. Note that there is a children field and a proxy field, both of which accept X3DChildNode. In other words, what can go in one can also go in the other.
>

This may not be the best example since children is a mfnode and proxy is a sfnode. So based on the node type of the child it would be still possible to determine which field is targeted ?

> The Collision node has a containerField attribute with a default value of “children”. This simply tells us that, unless otherwise specified, it will go into the children field of its parent node.
>

The default containerField attribute values are defined in the schema?

I believe what cobweb returns for node.getContainerField() is always the default value. So the method might be named node.getDefaultContainerField(). It is then up to the calling code to check if there is an explicit containerfield attribute which is what in cobweb the Parser.addNode() method does.

It is good to know that each node has a default value for the containerfield attribute.

> Similarly, if we look at, for example, MetadataBoolean, it has a containerField with the default value of “metadata”. So, MetadataBoolean, unless otherwise specified, will go into the metadata field of the parent node.

The question would be if MetadataBoolean could go anywhere else than the metadata field. Likely not.

> Q2 – ExternProto: Hm… good question. My first thought was that there’s nothing there. But, on reflection, it’s not about the definition using ExternProtoDeclare, or ProtoDeclare. It’s about where you use it. And that means ProtoInstance. Look there, and you see that there is an attribute for containerField, with a default value of “children”. So, if you want the ProtoInstance in some other field, you need to specify a different value for containerField.

It looks like 'children' is what cobweb returns for the default containerField value of ProtoInstances:

https://github.com/create3000/cobweb/blob/master/cobweb.js/cobweb/Components/Core/X3DPrototypeInstance.js#L105

Cobweb also should recognize an explicit containerField attribute value for ProtoInstance elements since they are added to the parent as a field value in Parser.addNode() just like any other node.

> Q3 – containerField: I think of the parent node as the “container”, and the “field” is the field that does the containing. And you are right, it is not a field. It is an XML attribute. It is not required, for example, in the classic VRML encoding, or the JSON encoding, because the encoding is such that, for each node, fields have their names explicitly written, followed by their values. So, for Collision, we would write:
>
>
>
> Collision {
>
>     children [
>
>         DEF group1 Group{},
>
>         DEF group2 Group{}
>
>     ],
>
>     proxy [
>
>         DEF group3 Group {}
>
>     ]
>
> }
>
>
>
> But, when it comes to XML, if we write
>
>
>
> <Collision>
>
>    <Group DEF=”group1”/>
>
>    <Group DEF=”group2”/>
>
>    <Group DEF=”group3”/>
>
> </Collision>
>
>
>
> Then all three Group nodes would be loaded into the children field of the Collision node, because the default value of the containerField attribute for Group is “children”. So, to reproduce the VRML encoding we write:
>
>
>
> <Collision>
>
>    <Group DEF=”group1”/>
>
>    <Group DEF=”group2”/>
>
>    <Group DEF=”group3” containerField=”proxy”/>
>
> </Collision>
>
>
>
> The only way to definitively know which is the default containerField for any node type is to read it from the schema or DTD.

This is very helpful from the 'horse's mouth' and clarified greatly my understanding on the role of the containerField attribute. I wonder if the XML encoding spec. should have a paragraph on the role of the containerField attribute. Well, the spec. actually has

http://www.web3d.org/documents/specifications/19776-1/V3.3/Part01/concepts.html#ContainerFieldAttributeSyntax

. The paragraph should perhaps stress more the cases when containerField is actually useful rather than stress that it is not needed in most cases.

Perhaps there should even be a list of nodes for which the containerField attribute needs to be explicitly set to a non-default value to ensure the node is targeting the intended field, ie.of all nodes which can have multiple targets. This would duplicate some of the schema content in

http://www.web3d.org/documents/specifications/19776-1/V3.3/index.html

but the schema is somewhat hard to read (for most?).

-Andreas




More information about the x3d-public mailing list