<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "https://www.web3d.org/specifications/x3d-3.0.dtd">
<X3D profile='Immersive' version='3.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.0.xsd'>
  <head>
    <meta content='TimeDelaySensorPrototype.x3d' name='title'/>
    <meta content='Time delay sensor design pattern, implemented as a reusable prototype node.' name='description'/>
    <meta content='Don Brutzman and MV4204 class' name='creator'/>
    <meta content='29 August 2003' name='created'/>
    <meta content='28 November 2019' name='modified'/>
    <meta content='TimeDelaySensorExample.x3d' name='reference'/>
    <meta content='https://www.web3d.org/technicalinfo/specifications/vrml97/part1/concepts.html#4.6.8' name='reference'/>
    <meta content='https://www.web3d.org/technicalinfo/specifications/vrml97/part1/nodesRef.html#CoordinateInterpolator' name='reference'/>
    <meta content='TimeDelaySensor' name='subject'/>
    <meta content='https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/TimeDelaySensorPrototype.x3d' name='identifier'/>
    <meta content='X3D-Edit 3.2, https://www.web3d.org/x3d/tools/X3D-Edit' name='generator'/>
    <meta content='../../license.html' name='license'/>
  </head>
  <Scene>
    <WorldInfo title='TimeDelaySensorPrototype.x3d'/>
    <ProtoDeclare appinfo='TimeSensor functionality commences after delayInterval pause' name='TimeDelaySensor'>
      <ProtoInterface>
        <field accessType='inputOutput' appinfo='describe the purpose of this sensor' name='description' type='SFString'/>
        <field accessType='inputOutput' appinfo='whether sensor is active' name='enabled' type='SFBool' value='true'/>
        <field accessType='inputOutput' appinfo='when current time exceeds startTime, isActive becomes true and sensor becomes active' name='startTime' type='SFTime' value='0'/>
        <field accessType='inputOutput' appinfo='seconds' name='delayInterval' type='SFTime' value='1'/>
        <field accessType='outputOnly' name='delayCompleteTime' type='SFTime'/>
        <field accessType='initializeOnly' name='traceEnabled' type='SFBool' value='false'/>
      </ProtoInterface>
      <ProtoBody>
        <Group>
          <TimeSensor DEF='TimeDelayClock'>
            <IS>
              <connect nodeField='startTime' protoField='startTime'/>
              <connect nodeField='enabled' protoField='enabled'/>
              <connect nodeField='cycleInterval' protoField='delayInterval'/>
            </IS>
          </TimeSensor>
          <Script DEF='TimeDelayScript' directOutput='true'>
            <field accessType='inputOutput' appinfo='describe the purpose of this sensor' name='description' type='SFString'/>
            <field accessType='inputOnly' name='set_fraction' type='SFFloat'/>
            <field accessType='outputOnly' name='delayCompleteTime' type='SFTime'/>
            <field accessType='initializeOnly' name='LocalTimeDelayClock' type='SFNode'>
              <TimeSensor USE='TimeDelayClock'/>
            </field>
            <field accessType='initializeOnly' name='priorDelayInterval' type='SFTime' value='1'/>
            <field accessType='initializeOnly' name='delayStarted' type='SFBool' value='false'/>
            <field accessType='initializeOnly' name='traceEnabled' type='SFBool'/>
            <IS>
              <connect nodeField='description' protoField='description'/>
              <connect nodeField='delayCompleteTime' protoField='delayCompleteTime'/>
              <connect nodeField='traceEnabled' protoField='traceEnabled'/>
            </IS>
            <![CDATA[
ecmascript:

//  inputOnly events are handled by functions,
//  initializeOnly fields are variable objects,
//  outputOnly events are handled by setting values

function initialize ()
{
	priorDelayInterval = LocalTimeDelayClock.cycleInterval;
	tracePrint ('initial delayInterval=' + priorDelayInterval + ' seconds');
}
function tracePrint (outputString)
{
	if (traceEnabled) Browser.println ('[TimeDelaySensor] ' + outputString);
}
function set_description (newDescription)
{
    description = newDescription;
}
function set_fraction (currentFraction, timestamp)  // from LocalTimeDelayClock
{
	if (priorDelayInterval != LocalTimeDelayClock.cycleInterval)
	{
		priorDelayInterval = LocalTimeDelayClock.cycleInterval;
		tracePrint ('changed delayInterval=' + priorDelayInterval + ' seconds');
	}
	if (!delayStarted)
	{
		delayStarted = true;
		tracePrint ('delay start time=' + timestamp);
	}
	tracePrint ('set_fraction=' + currentFraction);
	if (currentFraction >= 1.0)
	{
		delayCompleteTime = timestamp;  // send output event
		tracePrint ('delayCompleteTime=' + delayCompleteTime);
		delayStarted = false;
	}
}
]]>
          </Script>
          <ROUTE fromField='fraction_changed' fromNode='TimeDelayClock' toField='set_fraction' toNode='TimeDelayScript'/>
        </Group>
      </ProtoBody>
    </ProtoDeclare>
    <!-- ====================================== -->
    <!-- Example use -->
    <Anchor description='TimeDelaySensor Example' url='"TimeDelaySensorExample.x3d" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/TimeDelaySensorExample.x3d" "TimeDelaySensorExample.wrl" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Animation/TimeDelaySensorExample.wrl"'>
      <Shape>
        <Text string='"TimeDelaySensorPrototype" "defines a prototype" "" "Click text to see" "TimeDelaySensorExample scene"'>
          <FontStyle justify='"MIDDLE" "MIDDLE"' size='0.7'/>
        </Text>
        <Appearance>
          <Material diffuseColor='1 1 0.2'/>
        </Appearance>
      </Shape>
    </Anchor>
  </Scene>
</X3D>