123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- "use strict";
- // Copyright 2012 United States Government, as represented by the Secretary of Defense, Under
- // Secretary of Defense (Personnel & Readiness).
- //
- // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- // in compliance with the License. You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software distributed under the License
- // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- // or implied. See the License for the specific language governing permissions and limitations under
- // the License.
- /// vwf/view.js is the common implementation of all Virtual World Framework views. Views
- /// interpret information from the simulation, present it to the user, and accept user input
- /// influencing the simulation.
- ///
- /// Views are outside of the simulation. Unlike models, they may accept external input--such as
- /// pointer and key events from a user--but may only affect the simulation indirectly through the
- /// synchronization server.
- ///
- /// vwf/view and all deriving views are loaded as RequireJS (http://requirejs.org) modules.
- ///
- /// @module vwf/view
- /// @requires logger
- /// @requires vwf/api/kernel
- /// @requires vwf/api/view
- define( [ "module", "logger", "vwf/api/kernel", "vwf/api/view" ], function( module, logger, kernel_api, view_api ) {
- // TODO: most of this is the same between vwf/model.js and vwf/view.js. Find a way to share.
- var label = module.id.replace( /\//g, "." );
- logger.for( label ).debug( "loading" );
- var exports = {
- module: module,
- logger: logger.for( label ),
- load: function( module, initializer, viewGenerator, kernelGenerator ) {
- var instance = Object.create( this );
- instance.module = module;
- instance.logger = logger.for( instance.module.id.replace( /\//g, "." ), instance );
-
- instance.logger.debug( "loading" );
- if ( typeof initializer == "function" || initializer instanceof Function ) {
- initializer = initializer();
- }
- for ( var key in initializer ) {
- instance[key] = initializer[key];
- }
- viewGenerator && Object.keys( view_api ).forEach( function( viewFunctionName ) {
- if ( ! instance.hasOwnProperty( viewFunctionName ) ) {
- instance[viewFunctionName] = viewGenerator.call( instance, viewFunctionName );
- instance[viewFunctionName] || delete instance[viewFunctionName];
- }
- } );
- kernelGenerator && Object.keys( kernel_api ).forEach( function( kernelFunctionName ) {
- if ( ! instance.hasOwnProperty( kernelFunctionName ) ) {
- instance[kernelFunctionName] = kernelGenerator.call( instance, kernelFunctionName );
- instance[kernelFunctionName] || delete instance[kernelFunctionName];
- }
- } );
- return instance;
- },
- create: function( kernel, view, stages, state, parameters ) {
- this.logger.debug( "creating" );
- // Interpret create( kernel, stages, ... ) as create( kernel, undefined, stages, ... )
- if ( view && view.length !== undefined ) { // is an array?
- parameters = state;
- state = stages;
- stages = view;
- view = undefined;
- }
- // Append this driver's stages to the pipeline to be placed in front of this driver.
- if ( ! view ) {
- stages = Array.prototype.concat.apply( [], ( this.pipeline || [] ).map( function( stage ) {
- return ( stages || [] ).concat( stage );
- } ) ).concat( stages || [] );
- } else {
- stages = ( stages || [] ).concat( this.pipeline || [] );
- }
- // Create the driver stage using its module as its prototype.
- var instance = Object.create( this );
- // Attach the reference to the stage to the right through the view API.
- viewize.call( instance, view, view_api );
- // Create the pipeline to the left and attach the reference to the stage to the left
- // through the kernel API.
- kernelize.call( instance,
- stages.length ?
- stages.pop().create( kernel, instance, stages ) :
- kernel,
- kernel_api );
- // Attach the shared state object.
- instance.state = state || {};
- // Call the driver's initialize().
- initialize.apply( instance, parameters );
- // Call viewize() on the driver.
- function viewize( view, view_api ) {
- Object.getPrototypeOf( this ) && viewize.call( Object.getPrototypeOf( this ), view, view_api ); // depth-first recursion through the prototypes
- this.hasOwnProperty( "viewize" ) && this.viewize.call( instance, view, view_api ); // viewize() from the bottom up
- }
- // Call kernelize() on the driver.
- function kernelize( kernel, kernel_api ) {
- Object.getPrototypeOf( this ) && kernelize.call( Object.getPrototypeOf( this ), kernel, kernel_api ); // depth-first recursion through the prototypes
- this.hasOwnProperty( "kernelize" ) && this.kernelize.call( instance, kernel, kernel_api ); // kernelize() from the bottom up
- }
- // Call initialize() on the driver.
- function initialize( /* parameters */ ) {
- Object.getPrototypeOf( this ) && initialize.apply( Object.getPrototypeOf( this ), arguments ); // depth-first recursion through the prototypes
- this.hasOwnProperty( "initialize" ) && this.initialize.apply( instance, arguments ); // initialize() from the bottom up
- }
- // Return the driver stage. For the actual driver, return the leftmost stage in the
- // pipeline.
- if ( ! view ) {
- while ( instance.kernel !== kernel ) {
- instance = instance.kernel;
- }
- }
- return instance;
- },
- kernelize: function( kernel, kernel_api ) {
- this.kernel = kernel;
- },
-
- };
- return exports;
- } );
|