<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Start of a Script Expander for X3D JSON — X3D -> X3DOM scripting.  I have no clue how initialization, shutdown or event processing will work.</div><div class=""><br class=""></div><div class="">This code is currently a MESS.  This is not an example of how I like to present myself and I present it here in order to stimulate someone else to help with X3D bits I have little knowledge of.  I will continue working on this, but some guidance would be welcome.</div><div class=""><br class=""></div><div class="">John</div><div class=""><br class=""></div><div class=""><a href="https://github.com/coderextreme/X3DJSONLD/blob/master/Script.js" class="">https://github.com/coderextreme/X3DJSONLD/blob/master/Script.js</a></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">// X3D JSON Script Expander</div><div class=""><br class=""></div><div class="">var content = '';</div><div class="">// read content into buffer</div><div class="">process.stdin.resume();</div><div class="">process.stdin.on('data', function(buf) { content += buf.toString(); });</div><div class=""><br class=""></div><div class="">function Package(package, name) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>this.initializers = [];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>this.getters = {};</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>this.setters = {};</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>this.values = {};</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>this.types = {};</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>this.packages = {};</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>if (typeof package === 'undefined' || package.name === "") {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">            </span>if (typeof name === 'undefined') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>this.name = "";</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>} else {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                  </span>this.name = name;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>} else {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">          </span>if (typeof name === 'undefined') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>this.name = package.name;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>} else {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                  </span>this.name = package.name+'.'+name;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>package.packages[name] = this;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>// initialize children packages</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>// add package to parent so you can find the package without full path</div><div class="">}</div><div class=""><br class=""></div><div class="">Package.prototype.find = function (name) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>if (typeof this.packages[name] === 'undefined') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>// there is no package, so global package</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>return new Package(undefined, name);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>} else {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">          </span>return this.packages[name];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>}</div><div class="">}</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">function processPrototypes(object, clazz, package) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>var p;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>if (typeof object === "object") {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>for (p in object) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                       </span>var name = object[p]["@name"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                  </span>if (typeof name === 'undefined') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                </span>name = object[p]["@DEF"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                       </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                 </span>if (p.toLowerCase() === 'script') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                               </span>var script = new Package(package, name);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>processPrototypes(object[p], clazz, script);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                      </span>} else if (p.toLowerCase() === 'route') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                         </span>processRoutes(object[p], clazz, package);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                 </span>} else if (p.toLowerCase() === 'field' && object['@language'] !== 'GLSL') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                               </span>processFields(object[p], package);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                </span>clazz.push('var ' +  package.name +  ' = function(' +  package.initializers.join(', ') + ') {');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                   </span>clazz.push('var that = this;');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                   </span>clazz.push('this.setters = {};');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                 </span>clazz.push('this.getters = {};');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                 </span>for (var v in package.values) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                           </span>if (package.types[v].indexOf("MF") === 0) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                                     </span>clazz.push('var that.' + v + ' = ['+ package.values[v] + '];');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                           </span>} else {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                                  </span>clazz.push('var that.' + v + ' = '+ package.values[v] + ';');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                             </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                 </span></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                  </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                 </span>for (var v in package.getters) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                          </span>clazz.push('this.getters.' + v +  ' = function () { return that.' +  v +  '; };');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                 </span></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                  </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                         </span>processSource(object['#sourceText'], clazz, package);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                             </span>clazz.push('}');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>processPrototypes(object[p], clazz, package);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>} else if (p.toLowerCase() === '@use') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>var name = object["@USE"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                              </span>object["@USE"] = name;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>// object[p] is not an object</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>} else if (p.toLowerCase() === '@def') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>var name = object["@DEF"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                              </span>object["@DEF"] = name;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>// object[p] is not an object</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>} else {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>processPrototypes(object[p], clazz, package);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">function processRoutes(routes, clazz, package) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>clazz.push("this.runRoute = function() {");</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>var r;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>for (r in routes) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>var route = routes[r];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">            </span>var fromNode = route["@fromNode"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">              </span>var fromField = route["@fromField"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">            </span>var toNode = route["@toNode"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">          </span>var toField = route["@toField"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>clazz.push(package.name+'.this.'+toNode+'.setters.'+toField+'('+package.name+'.this.'+fromNode+'.getters.'+fromField+'());');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>clazz.push("};");</div><div class="">}</div><div class=""><br class=""></div><div class="">function processFields(fields, package) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>var f;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>for (f in fields) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>var object = fields[f];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>var name = object["@name"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">             </span>package.types[name] = object["@type"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">          </span>switch(object['@accessType']) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>case 'initializeOnly':</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                    </span>// these should be in order, so it's an array</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>package.initializers.push(name);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                  </span>package.values[name] = object["@value"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>break;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">            </span>case 'inputOutput':</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                       </span>// setters should be looked up by name</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                    </span>package.setters[name] = object;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                   </span>package.getters[name] = object;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                   </span>package.values[name] = object["@value"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>break;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">            </span>case 'inputOnly':</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                 </span>// setters should be looked up by name</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                    </span>package.setters[name] = object;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                   </span>package.values[name] = object["@value"];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>break;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">            </span>case 'outputOnly':</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>break;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                    </span>package.getters[name] = object;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>default:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                  </span>break;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">            </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">function processSource(lines, clazz, package) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>if (typeof lines !== 'undefined') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>var functions = lines.join("\n").split("function");</div><div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>var f;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">            </span>for (var f = 1; f < functions.length; f++) {  // skip ecmascript:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                 </span>var func = functions[f];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                  </span>var sp = func.indexOf('(');</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                       </span>var name = func.substr(0, sp).trim();</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>var funcvar = 'this.' + name;  //  a non setter function</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>if (typeof package.setters[name] !== 'undefined') {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                               </span>funcvar = 'this.setters.' + name; // a setter function</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                    </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                 </span>clazz.push(funcvar + ' = function ' + func.substr(sp));</div><div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">process.stdin.on('end', function() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>var object = JSON.parse(content);</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>var clazz = [];</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>processPrototypes(object, clazz, new Package());</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>console.log(clazz.join('\n'));</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>//console.log(JSON.stringify(object, null, 2));</div><div class="">});</div><div class=""><br class=""></div></body></html>