application.js 7.26 KB
/******************************************************************************
 * Application implementation
 * ***************************************************************************/

/**
 * Creates an application runnable by the ARCS engine.
 * @class ARCS.Application
 * @classdesc The application is the master class of the ARCS engine. 
 * It is initialized using a structured object (possibly described in JSON, 
 * see {@link ARCS.Application#import}) 
 * to load all external scripts describing components, instanciate
 * all components and then start the application
 */
ARCS.Application = function () {
    var context = new ARCS.Context(),
        sheets = {},
        controller = {},
        dependencies = [],
        self = this,
        currentSheet = "",
        preProcess;
        

    /** 
     * Exports an object representing an application
     */    
    this.export = function() {
        var i;
        var description = { 
            context: context, 
            controller: context.getComponentName(controller), 
            sheets: sheets            
        } ;
        
        // first problem: when loaded by the editor, libraries are not the good ones
        //description.context.libraries = libraries;        
        return description;
    };
    
    this.getContext = function () {
        return context;
    };
        
    this.getSheetList = function() {
        return Object.keys(sheets);
    };
        
    this.getSheet = function (sName) {
        return sheets[sName];
    };
            
    this.addSheet = function (sName, sheet) {
        sheets[sName] = sheet;
        sheet.setContext(context);
    };

    
    this.removeSheet = function (sName) {
        delete sheets[sName];
    };
        
    preProcess = function () {
        // first, we should instanciate components
        var i, temp, sheetList; 

        temp = context.getComponent(controller); //[controller].instance;
        controller = temp;
        // then we should work on sheets
        sheetList = Object.keys(sheets);
        for (i = 0; i < sheetList.length; i++) {
            temp = new ARCS.Sheet(context);
            temp.import(sheets[sheetList[i]], context);
            sheets[sheetList[i]] = temp;
        }

        ARCS.Component.connect(controller, "requestSheet", self, "setSheet");
        ARCS.Component.connect(controller, "requestTermination", self, "finish");
        controller.start();
    };
    
    
    this.setController = function (ctrlName) {
        controller = context.getComponent(ctrlName); //[ctrlName].instance;
    };
    
    /**
     * Sets the current sheet of the application. This method is in fact designed
     * as a slot and may be triggered by a statemachine. If a sheet is already the
     * current one, then it is deactivated before activating this new sheet.
     * This method may warn that it is trying to activate a hollow sheet. It is 
     * not inherently an error by itself but it may indicate a problem in your
     * application.
     * @param sheetName {string} name of the sheet to set as a current sheet.
     */
    this.setSheet = function (sheetname) {
        if (sheets.hasOwnProperty(sheetname)) {
            if (currentSheet) {
                sheets[currentSheet].deactivate();
            }
        
            currentSheet = sheetname;
            sheets[currentSheet].activate();
        } else {
            console.warn('[ARCS] Tried to activate hollow sheet named: ' + sheetname);
        }
    };
    /**
     * This is the end my friend. This triggers the end of the application
     */
    this.finish = function () {
        if (currentSheet) {
            sheets[currentSheet].deactivate();
        }
    };
    
    
    
    /**
     * Imports a structured object describing the application. The structured object
     * may be described itself in a JSON format.
     * @param object {object} structured object describing an application.
     *   
     * @example
     * // JSON format of an application description
     * {
     *      context : {
     *              libraries : [ "library1", "library2"],
     *              components : [
     *                      // this could be also properties from context
     *                      name1: { type: "type", value: "value if needed" }
     *              ],
     *              constants : [
     *                      // the same observation applies here
     *                      name1: { representation : {JSON/objectRepresentation ? } }
     *              ]
     *      },
     *      controller : controllerId,
     *      sheets : {
     *              sheetId : {     
     *                      preconnections : [
     *                              { 
     *                                      destination: "id", 
     *                                      slot : "slot name",
     *                                      value : JSON/objectRepresentation ?
     *                              }, {...}, {...}
     *                      ],
     *                      postconnections : [
     *                              { 
     *                                      destination: "id", 
     *                                      slot : "slot name",
     *                                      value : JSON/objectRepresentation ?
     *                              }, {...}, {...}
     *                      ],
     *                      connections : [
     *                              {
     *                                      source: "id",
     *                                      destination: "id",
     *                                      slot: "slot name",
     *                                      signal: "signal name"
     *                              }, {...}, {...}
     *                      ],
     *                      cleanups : [
     *                              { 
     *                                      destination: "id", 
     *                                      slot : "slot name",
     *                                      value : JSON/objectRepresentation ?
     *                              }, {...}, {...}
     *                      ]
     *              },
     *              { ... }
     *      }
     * }
     * 
     */
    this.import = function (object) {
        context = new ARCS.Context(object.context/*.components*/);
        sheets = object.sheets;
        controller = object.controller;
        if (controller === undefined) {
            console.error("[ARCS] Undefined controller. Cannot start application.");
        }
    };

    /**
     * Registers a factory using a key. If a factory was previously existing using 
     * the same key, then it is overridden.
     * @param key {string} name of the factory
     * @param factory {object} component factory to register.
     */
    this.setFactory = function (key, factory) {
        factories[key] = factory;
    };

    this.setDependency = function (key) {
        dependencies[key] = {};
    };

    /**
     * Starts the application
     */
    this.start = function () {
        console.log("[ARCS] Starting application...");
        context.instanciate().then(preProcess);
    };
};

ARCS.Application.setDependency = function (app, key) {
    app.setDependency(key);
};



ARCS.Component.create(ARCS.Application);
ARCS.Application.slot("setSheet");
ARCS.Application.slot("finish");