Difference between revisions of "Script-and-inputOutputField.x3d"

From Web3D.org
Jump to: navigation, search
(correct versions - final Flux is 2.1, final Vivaty is 1.0, see Player_support_for_X3D_components)
 
(7 intermediate revisions by one other user not shown)
Line 1: Line 1:
<?xml version="1.0" encoding="UTF-8"?>
+
<?xml version="1.0" encoding="UTF-8"?>
<X3D profile='Full' >
+
    <X3D profile='Full' >
 
   <Scene DEF='scene'>
 
   <Scene DEF='scene'>
 
     <Viewpoint position='20 0 40'/>
 
     <Viewpoint position='20 0 40'/>
Line 12: Line 12:
 
       <field accessType='inputOutput' name='foo' type='SFFloat' value='5'/>
 
       <field accessType='inputOutput' name='foo' type='SFFloat' value='5'/>
 
       <field accessType='inputOnly' name='readFoo' type='SFTime'/><![CDATA[ecmascript:
 
       <field accessType='inputOnly' name='readFoo' type='SFTime'/><![CDATA[ecmascript:
 
 
   //-----------------------------
 
   //-----------------------------
 
   function initialize (value) {
 
   function initialize (value) {
Line 18: Line 17:
 
     text.string[0] = line;
 
     text.string[0] = line;
 
   }
 
   }
 
 
   //-----------------------------
 
   //-----------------------------
 
   function readFoo (value) {     
 
   function readFoo (value) {     
 
   text.string[1] = 'readFoo called: TRUE, value: ' + foo;
 
   text.string[1] = 'readFoo called: TRUE, value: ' + foo;
 
   }       
 
   }       
 
 
   //-----------------------------
 
   //-----------------------------
 
   function foo (value) {     
 
   function foo (value) {     
 
   text.string[3] = 'foo function called: TRUE; ' + value;
 
   text.string[3] = 'foo function called: TRUE; ' + value;
 
   }       
 
   }       
 
 
   //-----------------------------
 
   //-----------------------------
 
   function set_foo (value) {     
 
   function set_foo (value) {     
 
   text.string[4] = 'set_foo function called: TRUE; ' + value;
 
   text.string[4] = 'set_foo function called: TRUE; ' + value;
 
   }       
 
   }       
 
 
   //-----------------------------
 
   //-----------------------------
 
   function foo_changed (value) {     
 
   function foo_changed (value) {     
Line 46: Line 41:
 
       </field>
 
       </field>
 
       <field accessType='inputOnly' name='fooCatcher' type='SFFloat'/><![CDATA[ecmascript:
 
       <field accessType='inputOnly' name='fooCatcher' type='SFFloat'/><![CDATA[ecmascript:
 
 
   //-----------------------
 
   //-----------------------
 
   function fooCatcher (value) {
 
   function fooCatcher (value) {
 
     text.string[2] = 'Foo value send: TRUE; value: ' + value;
 
     text.string[2] = 'Foo value send: TRUE; value: ' + value;
 
   }
 
   }
 
 
   ]]>
 
   ]]>
 
     </Script>
 
     </Script>
Line 58: Line 51:
 
     <ROUTE fromNode='s1' fromField='foo_changed' toNode='s2' toField='fooCatcher'/>
 
     <ROUTE fromNode='s1' fromField='foo_changed' toNode='s2' toField='fooCatcher'/>
 
   </Scene>
 
   </Scene>
</X3D>
+
</X3D>
  
 
== Browser Results ==
 
== Browser Results ==
Line 71: Line 64:
 
| 7.107
 
| 7.107
 
| Not Expected
 
| Not Expected
| No objects showing, global not supported
+
| Follows the X3D-Spec: read on foo gives you the field value,
|-
+
but foo() as function gets also called. Breaks the ECMAScript spec.
 +
|-
 
| FreeWRL
 
| FreeWRL
 
|  
 
|  
| Untested
+
| Not Expected
|
+
| No support for inputOutput
  
 
|-
 
|-
 
| Octaga
 
| Octaga
 
| 2.2.0.12
 
| 2.2.0.12
| Expected
+
| Not Expected
|
+
| same as bscontact but addition initialize() is not called. Breaks the ECMAScript spec
 
|-
 
|-
 
| Instant Reality
 
| Instant Reality
 
| 2.0.0_beta4
 
| 2.0.0_beta4
 
| Not Expected  
 
| Not Expected  
| Both spheres the same intensity, expect attenuation not supported
+
| reading foo returns the function not the field value.
|
+
foo() funciton gets called. Does not break X3D or ECMA spec
 +
but field value is not accessible.
 
|-
 
|-
| Vivaty
+
| Flux
 
| 2.1
 
| 2.1
| Expected
+
| Not Expected
|
+
| reading foo does not work but also no function called ?!?
 +
|-
 +
| Vivaty
 +
| 1.0
 +
| Not Expected
 +
| reading foo does not work but also no function called ?!?
 
|-
 
|-
 
| Xj3D
 
| Xj3D
 
| 2_M1_DEV_2008-06_02
 
| 2_M1_DEV_2008-06_02
| Expected
+
| Not Expected
|
+
| the value of foo is the function and the foo() function is
 +
not called.
 +
 
 
|}
 
|}
 +
 +
== Specification Notes ==
 +
 +
Basic Problem:
 +
 +
A) The X3D-spec (not VRML) supports intputOutput Fields in Scripts
 +
(http://www.web3d.org/x3d/specifications/ISO-IEC-19775-X3DAbstractSpecification_Revision1_to_Part1/Part01/components/scripting.html#Scriptlanguages)
 +
 +
B) Field values can be read or written in the Script code
 +
(http://www.web3d.org/x3d/specifications/ISO-IEC-19775-X3DAbstractSpecification_Revision1_to_Part1/Part01/components/scripting.html#Accessingfieldsandevents)
 +
 +
C) Events received by the Script node are passed to the appropriate scripting language method in the script. The method's name depends on the language type used.
 +
(http://www.web3d.org/x3d/specifications/ISO-IEC-19775-X3DAbstractSpecification_Revision1_to_Part1/Part01/components/scripting.html#Eventhandling)
 +
 +
D) ECMAScript X3D-binding: If the function represents an inputOutput field, the name of the function shall be the same name as the field declaration, without the set_ or _changed modifiers
 +
(http://www.web3d.org/x3d/specifications/ISO-IEC-19777-1-(X3DLanguageBindings-ECMAScript/Part1/concepts.html#ReceivingEvents)
 +
 +
E) ECMAScript: variable and function both are objects in the same namespace.
 +
(http://www.ecma-international.org/publications/standards/Ecma-262.htm)
 +
 +
=> There is variable/function-shadowing problem ((E) brakes (D)) which prevents reading/writing (B) or receiving of events (C)
 +
 +
-------------------------------------------
 +
Solution:
 +
 +
_S1_) Leave the X3D-Spec like it is (This breaks the ECMAScirpt spec (E))
 +
-----------------------------------------------
 +
There are ways to abuse the ECMAScript impl. (e.g SpiderMonkey)
 +
to work this way but still breaks the spec. (and slows down the object access)
 +
However there are some major browser that did exactly this
 +
 +
code snip:
 +
 +
    Script {
 +
    inputOutput SFBool foo TRUE
 +
      ...
 +
      function initialize () {
 +
          Browser.println( 'value: '+ foo);
 +
      }
 +
      ...
 +
      function foo (value,timeStamp) {
 +
          Browser.println( 'value: '+ value);
 +
      }
 +
 +
_S2_) Change the X3D-Spec, use set_foo for the event handler
 +
-----------------------------------------------
 +
change the name of the function for inputOuput from "same as field" to
 +
"set_" prefix
 +
 +
code snip:
 +
 +
    Script {
 +
    inputOutput SFBool foo TRUE
 +
      ...
 +
      function initialize () {
 +
          Browser.println( 'value: '+ foo);
 +
      }
 +
      ...
 +
      function set_foo (value,timeStamp) {
 +
          Browser.println( 'value: '+ value);
 +
      }
 +
 +
 +
_S3_) Change the X3D-Spec, use foo_value/set_foo or foo_changed to access the value
 +
-----------------------------------------------
 +
change the field-value access funciton
 +
 +
code snip:
 +
 +
    Script {
 +
    inputOutput SFBool foo TRUE
 +
      ...
 +
      function initialize () {
 +
          Browser.println( 'value: '+ foo_value);
 +
      }
 +
      ...
 +
      function foo (value,timeStamp) {
 +
          Browser.println( 'value: '+ value);
 +
      }
 +
 +
---------------------
 +
conclusion:
 +
 +
It is a mess right now and I would suggest that we change the spec
 +
to change the event-handling function form foo to set_foo;
 +
 +
Something like:
 +
 +
ECMASCRIPT: 4 Concepts: 4.3.5.4 Receiving events
 +
 +
OLD:
 +
 +
Events sent to the containing node are passed to the corresponding ECMAScript function in the script. The function's name is the same as the field and is passed two arguments. If the function represents an inputOutput field, the name of the function shall be the same name as the field declaration, without the set_ or _changed modifiers
 +
 +
NEW:
 +
 +
Events sent to the containing node are passed to the corresponding ECMAScript function in the script. Two arguments, the value and the timestamp, are passed while calling the function. For inputOnly fields the function's name is the same as the field. If the function represents an inputOutput field, the name of the function shall be the same name as the field declaration plus a set_ prefix.

Latest revision as of 12:16, 11 September 2011

<?xml version="1.0" encoding="UTF-8"?>
   <X3D profile='Full' >
 <Scene DEF='scene'>
   <Viewpoint position='20 0 40'/>
   <Shape>
     <Text DEF='text' string='"Initialize called: FALSE" "readFoo() called: FALSE" "foo value send: FALSE" "foo function called: FALSE" "set_foo function called: FALSE" "foo_changed function called: FALSE"'/>
   </Shape>
   <Script DEF='s1' directOutput='true'>
     <field accessType='initializeOnly' name='text' type='SFNode'>
       <Text USE='text'/>
     </field>
     <field accessType='inputOutput' name='foo' type='SFFloat' value='5'/>
     <field accessType='inputOnly' name='readFoo' type='SFTime'/><![CDATA[ecmascript:
 //-----------------------------
 function initialize (value) {
   line = 'Initialized called: TRUE; foo value: ' + foo;
   text.string[0] = line;
  }
 //-----------------------------
 function readFoo (value) {     
  text.string[1] = 'readFoo called: TRUE, value: ' + foo;
 }       
 //-----------------------------
 function foo (value) {     
  text.string[3] = 'foo function called: TRUE; ' + value;
 }       
 //-----------------------------
 function set_foo (value) {     
  text.string[4] = 'set_foo function called: TRUE; ' + value;
 }       
 //-----------------------------
 function foo_changed (value) {     
  text.string[5] = 'foo_changed function called: TRUE; ' + value;
 }       
 ]]>
   </Script>
   <TimeSensor DEF='ts' cycleInterval='3' loop='true'/>
   <Script DEF='s2' directOutput='true'>
     <field accessType='initializeOnly' name='text' type='SFNode'>
       <Text USE='text'/>
     </field>
     <field accessType='inputOnly' name='fooCatcher' type='SFFloat'/><![CDATA[ecmascript:
 //-----------------------
 function fooCatcher (value) {
   text.string[2] = 'Foo value send: TRUE; value: ' + value;
 }
 ]]>
   </Script>
   <ROUTE fromNode='ts' fromField='fraction_changed' toNode='s1' toField='set_foo'/>
   <ROUTE fromNode='ts' fromField='cycleTime' toNode='s1' toField='readFoo'/>
   <ROUTE fromNode='s1' fromField='foo_changed' toNode='s2' toField='fooCatcher'/>
 </Scene>
</X3D>

Browser Results

Browser Version Result Notes
BS Contact 7.107 Not Expected Follows the X3D-Spec: read on foo gives you the field value,

but foo() as function gets also called. Breaks the ECMAScript spec.

FreeWRL Not Expected No support for inputOutput
Octaga 2.2.0.12 Not Expected same as bscontact but addition initialize() is not called. Breaks the ECMAScript spec
Instant Reality 2.0.0_beta4 Not Expected reading foo returns the function not the field value.

foo() funciton gets called. Does not break X3D or ECMA spec but field value is not accessible.

Flux 2.1 Not Expected reading foo does not work but also no function called ?!?
Vivaty 1.0 Not Expected reading foo does not work but also no function called ?!?
Xj3D 2_M1_DEV_2008-06_02 Not Expected the value of foo is the function and the foo() function is

not called.

Specification Notes

Basic Problem:

A) The X3D-spec (not VRML) supports intputOutput Fields in Scripts (http://www.web3d.org/x3d/specifications/ISO-IEC-19775-X3DAbstractSpecification_Revision1_to_Part1/Part01/components/scripting.html#Scriptlanguages)

B) Field values can be read or written in the Script code (http://www.web3d.org/x3d/specifications/ISO-IEC-19775-X3DAbstractSpecification_Revision1_to_Part1/Part01/components/scripting.html#Accessingfieldsandevents)

C) Events received by the Script node are passed to the appropriate scripting language method in the script. The method's name depends on the language type used. (http://www.web3d.org/x3d/specifications/ISO-IEC-19775-X3DAbstractSpecification_Revision1_to_Part1/Part01/components/scripting.html#Eventhandling)

D) ECMAScript X3D-binding: If the function represents an inputOutput field, the name of the function shall be the same name as the field declaration, without the set_ or _changed modifiers (http://www.web3d.org/x3d/specifications/ISO-IEC-19777-1-(X3DLanguageBindings-ECMAScript/Part1/concepts.html#ReceivingEvents)

E) ECMAScript: variable and function both are objects in the same namespace. (http://www.ecma-international.org/publications/standards/Ecma-262.htm)

=> There is variable/function-shadowing problem ((E) brakes (D)) which prevents reading/writing (B) or receiving of events (C)


Solution:

_S1_) Leave the X3D-Spec like it is (This breaks the ECMAScirpt spec (E))


There are ways to abuse the ECMAScript impl. (e.g SpiderMonkey) to work this way but still breaks the spec. (and slows down the object access) However there are some major browser that did exactly this

code snip:

   Script {
   inputOutput SFBool foo TRUE
     ...
     function initialize () {
          Browser.println( 'value: '+ foo);
     }
     ...
     function foo (value,timeStamp) {
         Browser.println( 'value: '+ value);
      }

_S2_) Change the X3D-Spec, use set_foo for the event handler


change the name of the function for inputOuput from "same as field" to "set_" prefix

code snip:

   Script {
   inputOutput SFBool foo TRUE
     ...
     function initialize () {
          Browser.println( 'value: '+ foo);
     }
     ...
     function set_foo (value,timeStamp) {
         Browser.println( 'value: '+ value);
      }


_S3_) Change the X3D-Spec, use foo_value/set_foo or foo_changed to access the value


change the field-value access funciton

code snip:

   Script {
   inputOutput SFBool foo TRUE
     ...
     function initialize () {
          Browser.println( 'value: '+ foo_value);
     }
     ...
     function foo (value,timeStamp) {
         Browser.println( 'value: '+ value);
      }

conclusion:

It is a mess right now and I would suggest that we change the spec to change the event-handling function form foo to set_foo;

Something like:

ECMASCRIPT: 4 Concepts: 4.3.5.4 Receiving events

OLD:

Events sent to the containing node are passed to the corresponding ECMAScript function in the script. The function's name is the same as the field and is passed two arguments. If the function represents an inputOutput field, the name of the function shall be the same name as the field declaration, without the set_ or _changed modifiers

NEW:

Events sent to the containing node are passed to the corresponding ECMAScript function in the script. Two arguments, the value and the timestamp, are passed while calling the function. For inputOnly fields the function's name is the same as the field. If the function represents an inputOutput field, the name of the function shall be the same name as the field declaration plus a set_ prefix.