bebraw
12/12/2010 - 11:39 AM

main.js

// the system is attached to the main app in some other place like this
// I'm not too fond of CD global...
APP.tools = new Tools();
APP.tools.load();

// actual class
var Tools = new Class(PluginSystem, {
    _dir: 'src/tools',
    _defaultMethods: [
        'initialize',
        'down',
        'move',
        'drag',
        'up'
    ],
    _defaultAttributes: {
        instant: false,
        refresh: true,
        buffered: true,
        undoable: false,
        options: {}
    },
    initialize: function() {
        // set up some initial states (_pluginsLoaded can access these later) 
    },
    _pluginsLoaded: function() {
        // do something cool now that plugins have been loaded
    }
});
// simple plugin system utilizing RequireJS
var PluginSystem = new Class({
    _choices: {},
    _dir: '',
    _defaultMethods: [],
    _defaultAttributes: {}, // attr-value pairs
    load: function() {
        this._storage = {};

        var scope = this;
        require(this._moduleNames(this._choices, this._dir), function() {
            scope._pluginsLoaded();
        });
    },
    _pluginsLoaded: function() {
        
    },
    _moduleNames: function(choices, dir) {
        var ret = [];

        choices.each(function(choice) {
            // make sure modules are loaded in order
            ret.push('order!' + dir + '/' + choice + '.js');
        });

        return ret;
    },
    get: function(index) {
        if(isString(index)) {
            return this._storage[index];
        }

        return this._storage[this.getName(index)];
    },
    getName: function(index) {
        return Object.keys(this._storage)[index];
    },
    register: function(name, plugin) {
        this._defaultMethods.each(function(funcName) {
            if(!(funcName in plugin)) {
                plugin[funcName] = function() {}
            }
        });

        for(var attrName in this._defaultAttributes) {
            var attrValue = this._defaultAttributes[attrName];

            if(!(attrName in plugin)) {
                plugin[attrName] = attrValue;
            }
        }

        this._storage[name] = plugin;
    }
});
function getModules() {
    function constructPaths(root, moduleNames) {
        var ret = [];

        moduleNames.each(function(lib) {
            ret.push('src/' + root + '/' + lib + '.js');
        });

        return ret;
    }
    var ret = ['src/conf.js', 'src/local.js', 'src/application.js',
        'order!src/utils/plugin.js'];
    var modules = {
        'libs': ['json', 'shortcut'],
        'utils': ['misc', 'math', 'configuration']
    };

    for(var moduleRoot in modules) {
        var moduleNames = modules[moduleRoot];

        ret = ret.concat(constructPaths(moduleRoot, moduleNames));
    }

    return ret;
}

require(getModules(), function() {
    require.ready(function() {
        APP = new Application(); // note that the app is bound to a global!
        APP.init();
    });
});