API Docs for: 0.2.0
Show:

File: src\scene\director.js

/**
 * @module Lyria
 * @submodule Scene
 */
define('lyria/scene/director', ['root', 'mixin', 'jquery', 'lyria/eventmap', 'lyria/scene', 'lyria/viewport'], function(root, mixin, $, EventMap, Scene, Viewport) {'use strict';

  /**
   * The scene director is the manager for all scenes
   *
   */
  return (function() {

    /**
     * The scene director constructor
     * Attaches a scene director to a container, the parent is optional
     * 
     * @class Director
     * @constructor
     * 
     * @param {Object} container
     * @param {Object} parent
     */
    function SceneDirector(container, parent) {
      mixin(SceneDirector.prototype, new EventMap());

      if ( container instanceof Viewport) {
        this.viewport = container;
      } else {
        this.viewport = new Viewport(container, parent);
      }

      /**
       * All scenes
       * 
       * @property sceneList
       * @type {Object} 
       */
      this.sceneList = {};
      
      /**
       * The current scene 
       *
       * @property currentScene
       * @type {Scene}
       */
      this.currentScene = null;
    }

    // Properties
    SceneDirector.prototype.sceneClassName = 'scene';

    // Methods
    
    /**
     * Adds a scene to the scene director
     * 
     * @method add
     * @param {Object} scene
     * @param {Object} options
     */
    SceneDirector.prototype.add = function(scene, options) {

      if (!( scene instanceof Scene)) {
        if (this.scenes && !$.isEmptyObject(this.scenes)) {
          scene = this.scenes[scene];
        } else {
          // TODO: Don't throw a string. Throw an error
          throw 'No valid scene found.';
        }
      }

      scene.parent = this;
      this.sceneList[scene.name] = scene;

      if (this.viewport.$element) {
        if ($('#' + scene.name).length === 0) {
          this.viewport.$element.prepend($(root.document.createElement('div')).attr('id', scene.name).attr('class', SceneDirector.prototype.sceneClassName));

          if (!scene.async) {
            if (scene.content) {
              $('#' + scene.name).html(scene.content);
            }
          }

          // Bind events
          if (scene.events && !$.isEmptyObject(scene.events)) {
            $.each(scene.events, function(key, value) {
              if (( typeof value === 'object') && (key !== 'delegate')) {
                $(scene.events.delegate).on(value, key, {
                  scene: scene
                });
              }
            });
          }

          // Data binding
          if (scene.template.data && !$.isEmptyObject(scene.template.data)) {
            $('#' + scene.name + ' [data-bind]').each(function() {
              var $dataElem = $(this);
              
              var prop = $dataElem.data('bind');

              scene.template.data.watch(prop, function(id, oldval, newval) {
                if (oldval !== newval) {
                  $dataElem.html(newval);
                }

                return newval;
              });
            });
          }
        }
      }

      return this;
    };

    /**
     * Shows a specified scene
     * 
     * @method show
     * @param {String} scene
     * @param {Object} options
     * @param {Function} callback
     */
    SceneDirector.prototype.show = function(scene, options, callback) {
      this.trigger('scene:change', scene);

      // More than one scene visible at the same time
      if ($('.' + SceneDirector.prototype.sceneClassName + ':visible')) {
        $('.' + SceneDirector.prototype.sceneClassName).hide();
      }

      if (this.currentScene) {
        if (this.currentScene.transition && this.currentScene.length) {
          $('#' + this.currentScene).hide(this.currentScene.transition.length, function() {
            $('.' + SceneDirector.prototype.sceneClassName).hide();
          });
        } else {
          $('.' + SceneDirector.prototype.sceneClassName).hide();
        }

        this.currentScene.trigger('deactivate', options);
      }

      var self = this;

      $.each(this.sceneList, function(key, value) {
        if (key === scene) {

          if (scene.transition && scene.transition.length) {
            $('#' + scene).show(scene.transition.length);
          } else {
            $('#' + scene).show();
          }

          self.currentScene = value;

          self.currentScene.trigger('active', options);

          if (callback) {
            callback(scene);
          }

          return false;
        }
      });
    };

    /**
     * Refreshes a scene
     * 
     * @method refresh
     * @param {String} scene
     */
    SceneDirector.prototype.refresh = function(scene) {
      var sceneObj = (scene) ? this.sceneList[scene] : this.currentScene;

      // Re-compile scene template
      sceneObj.refresh();

      if (sceneObj.content) {
        $('#' + sceneObj.name).html(sceneObj.content);
      }
    };

    /**
     * Triggers the render event of the current scene
     * 
     * @method render
     */
    SceneDirector.prototype.render = function() {
      this.currentScene.trigger('render');
    };

    /**
     * Triggers the update event of the current scene
     * 
     * @param {Number} dt
     */
    SceneDirector.prototype.update = function(dt) {
      this.currentScene.trigger('update', dt);
    };

    return SceneDirector;

  })();
});