{ "X3D": {
    "encoding":"UTF-8",
    "@profile":"Immersive",
    "@version":"3.0",
    "@xsd:noNamespaceSchemaLocation":"https://www.web3d.org/specifications/x3d-3.0.xsd",
    "JSON schema":"https://www.web3d.org/specifications/x3d-4.0-JSONSchema.autogenerated.json",
    "head": {
        "meta": [
          {
            "@name":"title",
            "@content":"LoadSensorPrototype.x3d"
          },
          {
            "@name":"description",
            "@content":"LoadSensor prototype for VRML 97 use. Assumes correct loading of resources and provides output events based on timeOut delay."
          },
          {
            "@name":"created",
            "@content":"26 December 2003"
          },
          {
            "@name":"modified",
            "@content":"20 October 2019"
          },
          {
            "@name":"creator",
            "@content":"Don Brutzman"
          },
          {
            "@name":"hint",
            "@content":"Set LoadSensorScript traceEnabled true/false to enable/disable console trace text."
          },
          {
            "@name":"warning",
            "@content":"This LoadSensor implementation for VRML 97 only emulates LoadSensor events and cannot sense actual loading of watchList resources. Use an X3D-compliant browser for complete LoadSensor capability."
          },
          {
            "@name":"reference",
            "@content":"LoadSensorExample.x3d"
          },
          {
            "@name":"reference",
            "@content":"LoadSensorPrototypeInitializationTrace.txt"
          },
          {
            "@name":"identifier",
            "@content":"https://www.web3d.org/x3d/content/examples/Basic/development/LoadSensorPrototype.x3d"
          },
          {
            "@name":"generator",
            "@content":"X3D-Edit 3.3, https://www.web3d.org/x3d/tools/X3D-Edit"
          },
          {
            "@name":"license",
            "@content":"../license.html"
          },
          {
            "@name":"translated",
            "@content":"20 April 2026"
          },
          {
            "@name":"generator",
            "@content":"X3dToJson.xslt, https://www.web3d.org/x3d/stylesheets/X3dToJson.html"
          },
          {
            "@name":"reference",
            "@content":"X3D JSON encoding: https://www.web3d.org/wiki/index.php/X3D_JSON_Encoding"
          }
        ]
    },
    "Scene": {
        "-children":[
          { "WorldInfo":
            {
              "@title":"LoadSensorPrototype.x3d"
            }
          },
          { "ProtoDeclare":
            {
              "@name":"LoadSensor",
              "@appinfo":"LoadSensor monitors the progress and success of downloading URL elements over a network. Only nodes that contain a valid URL field (i.e. descendants of X3DUrlObject) may be specified as watchList children. Multiple nodes may be watched with a single LoadSensor.",
              "@documentation":"https://www.web3d.org/specifications/ISO-IEC-19775/Part01/components/networking.html#LoadSensor",
              "ProtoInterface": {
                  "field": [
                    {
                      "@name":"enabled",
                      "@accessType":"inputOutput",
                      "@appinfo":"Enables/disables the sensor node.",
                      "@type":"SFBool",
                      "@value":true
                    },
                    {
                      "@name":"timeOut",
                      "@accessType":"inputOutput",
                      "@appinfo":"Maximum time for which the LoadSensor will monitor loading starting from when the sensor becomes active. timeOut=0 ordinarily indicates an indefinite time out period; i.e. the LoadSensor will wait until loading has completed either with success or failure timeOut=0 causes immediate loading for this implementation.",
                      "@type":"SFTime",
                      "@value":0
                    },
                    {
                      "@name":"watchList",
                      "@accessType":"initializeOnly",
                      "@appinfo":"Zero or more nodes with url fields to monitor.",
                      "@type":"MFNode"
                    },
                    {
                      "@name":"set_watchList",
                      "@accessType":"inputOnly",
                      "@appinfo":"Change watchList MFNode array.",
                      "@type":"MFNode"
                    },
                    {
                      "@name":"isActive",
                      "@accessType":"outputOnly",
                      "@appinfo":"isActive=true when loading begins isActive=false when loading ends.",
                      "@type":"SFBool"
                    },
                    {
                      "@name":"isLoaded",
                      "@accessType":"outputOnly",
                      "@appinfo":"isLoaded=true when loading succeeds isLoaded=false when loading fails or timeOut reached.",
                      "@type":"SFBool"
                    },
                    {
                      "@name":"loadTime",
                      "@accessType":"outputOnly",
                      "@appinfo":"loadTime event is generated when loading has successfully completed.",
                      "@type":"SFTime"
                    },
                    {
                      "@name":"progress",
                      "@accessType":"outputOnly",
                      "@appinfo":"progress [0..1] indicates fraction of loading complete.",
                      "@type":"SFFloat"
                    },
                    {
                      "@name":"metadata",
                      "@accessType":"initializeOnly",
                      "@appinfo":"associated Metadata node.",
                      "@type":"SFNode"
                    }
                  ]
              },
              "ProtoBody": {
                  "-children":[
                    { "Group":
                      {
                        "-children":[
                          { "TimeSensor":
                            {
                              "@DEF":"Clock",
                              "@loop":true,
                              "IS": {
                                  "connect": [
                                    {
                                      "@nodeField":"enabled",
                                      "@protoField":"enabled"
                                    },
                                    {
                                      "@nodeField":"cycleInterval",
                                      "@protoField":"timeOut"
                                    }
                                  ]
                              }
                            }
                          },
                          { "Script":
                            {
                              "@DEF":"LoadSensorScript",
                              "@directOutput":true,
                              "field": [
                                {
                                  "@name":"ClockNode",
                                  "@accessType":"initializeOnly",
                                  "@type":"SFNode",
                                  "-children":[
                                    { "TimeSensor":
                                      {
                                        "@USE":"Clock"
                                      }
                                    }
                                  ]
                                },
                                {
                                  "@name":"loopStart",
                                  "@accessType":"outputOnly",
                                  "@type":"SFTime"
                                },
                                {
                                  "@name":"fraction",
                                  "@accessType":"inputOnly",
                                  "@type":"SFFloat"
                                },
                                {
                                  "@name":"priorFraction",
                                  "@accessType":"initializeOnly",
                                  "@type":"SFFloat",
                                  "@value":0
                                },
                                {
                                  "@name":"progress",
                                  "@accessType":"outputOnly",
                                  "@type":"SFFloat"
                                },
                                {
                                  "@name":"watchList",
                                  "@accessType":"initializeOnly",
                                  "@type":"MFNode"
                                },
                                {
                                  "@name":"set_watchList",
                                  "@accessType":"inputOnly",
                                  "@type":"MFNode"
                                },
                                {
                                  "@name":"isActive",
                                  "@accessType":"outputOnly",
                                  "@type":"SFBool"
                                },
                                {
                                  "@name":"isLoaded",
                                  "@accessType":"outputOnly",
                                  "@type":"SFBool"
                                },
                                {
                                  "@name":"loadTime",
                                  "@accessType":"outputOnly",
                                  "@type":"SFTime"
                                },
                                {
                                  "@name":"traceEnabled",
                                  "@accessType":"initializeOnly",
                                  "@type":"SFBool",
                                  "@value":false
                                }
                              ],
                              "IS": {
                                  "connect": [
                                    {
                                      "@nodeField":"watchList",
                                      "@protoField":"watchList"
                                    },
                                    {
                                      "@nodeField":"set_watchList",
                                      "@protoField":"set_watchList"
                                    },
                                    {
                                      "@nodeField":"isActive",
                                      "@protoField":"isActive"
                                    },
                                    {
                                      "@nodeField":"isLoaded",
                                      "@protoField":"isLoaded"
                                    },
                                    {
                                      "@nodeField":"loadTime",
                                      "@protoField":"loadTime"
                                    },
                                    {
                                      "@nodeField":"progress",
                                      "@protoField":"progress"
                                    }
                                  ]
                              },
                              "#sourceCode":[
"",
"",
"ecmascript:",
"",
"function initialize ()",
"{",
"\tenabled = ClockNode.enabled;",
"\ttracePrint ('initialize() enabled=' + enabled);",
"\tif (enabled)",
"\t{",
"\t\tisActive = true;",
"\t\t// isLoaded event only sent upon completion",
"\t\tprogress = 0.0;",
"\t\ttracePrintEvents ();",
"\t\ttimeOut = ClockNode.cycleInterval;",
"\t\ttracePrint ('timeOut=' + timeOut);",
"\t\tif (timeOut <= 0.0) // instantaneous, no loop",
"\t\t{",
"\t\t\tisActive = false;",
"\t\t\tisLoaded = true;",
"\t\t\tprogress = 1.0;",
"\t\t\tloadTime = timestamp;",
"\t\t\ttracePrintEvents ();",
"\t\t}",
"\t}",
"}",
"function fraction (value, timestamp)",
"{",
"\tenabled = ClockNode.enabled;",
"\tif (enabled)",
"\t\ttracePrint ('progress=' + value + ', priorFraction=' + priorFraction);",
"\t// use priorFraction to check for looping, then stop loop",
"\tif (enabled && ((value >=1) || (value < priorFraction)))",
"\t{",
"\t\tisActive = false;",
"\t\tisLoaded = true;",
"\t\tloadTime = timestamp;",
"\t\tprogress = 1;",
"\t\ttracePrintEvents ();",
"\t\ttracePrint ('complete');",
"                loopStart = true;",
"\t}",
"\telse progress= value; // output event",
"\tpriorFraction = progress;",
"}",
"function set_watchList (value, timestamp)",
"{",
"\twatchList = value;",
"}",
"function tracePrintEvents ()",
"{",
"\ttracePrint ('isActive=' + isActive);",
"\ttracePrint ('isLoaded=' + isLoaded);",
"\ttracePrint ('loadTime=' + loadTime);",
"\ttracePrint ('progress=' + progress);",
"}",
"function tracePrint (outputString)",
"{",
"\tif (traceEnabled) Browser.println ('[LoadSensor]' + outputString);",
"}",
"function alwaysPrint (outputString)",
"{",
"\tBrowser.println ('[LoadSensor]' + outputString);",
"}",
"",
""
]
                            }
                          },
                          { "ROUTE":
                            {
                              "@fromField":"loopStart",
                              "@fromNode":"LoadSensorScript",
                              "@toField":"startTime",
                              "@toNode":"Clock"
                            }
                          },
                          { "ROUTE":
                            {
                              "@fromField":"isActive",
                              "@fromNode":"LoadSensorScript",
                              "@toField":"enabled",
                              "@toNode":"Clock"
                            }
                          },
                          { "ROUTE":
                            {
                              "@fromField":"fraction_changed",
                              "@fromNode":"Clock",
                              "@toField":"fraction",
                              "@toNode":"LoadSensorScript"
                            }
                          },
                          { "Collision":
                            {
                              "@enabled":false,
                              "IS": {
                                  "connect": [
                                    {
                                      "@nodeField":"proxy",
                                      "@protoField":"metadata"
                                    }
                                  ]
                              }
                            }
                          }
                        ]
                      }
                    }
                  ]
              }
            }
          },
          {
            "#comment":"======================================"
          },
          {
            "#comment":"Example use"
          },
          { "Anchor":
            {
              "@description":"LoadSensorExample",
              "@parameter":["target=_blank"],
              "@url":["LoadSensorExample.x3d","https://www.web3d.org/x3d/content/examples/Basic/development/LoadSensorExample.x3d","LoadSensorExample.wrl","https://www.web3d.org/x3d/content/examples/Basic/development/LoadSensorExample.wrl"],
              "-children":[
                { "Shape":
                  {
                    "-geometry":
                      { "Text":
                        {
                          "@string":["LoadSensorPrototype","defines a prototype","Click on this text to see","LoadSensorExample scene"],
                          "-fontStyle":
                            { "FontStyle":
                              {
                                "@justify":["MIDDLE","MIDDLE"],
                                "@size":0.7
                              }
                            }
                        }
                      },
                    "-appearance":
                      { "Appearance":
                        {
                          "-material":
                            { "Material":
                              {
                                "@diffuseColor":[1,1,0.2]
                              }
                            }
                        }
                      }
                  }
                }
              ]
            }
          }
        ]
    }
  }
}