score.js 2.57 KB
define("mec/score", ['jquery'], function () {
    var isObject = type("Object");
    var isFunction = type("Function");

    function IOC(config) {
        this.getController = IOC.getModule(config.controller);
        this.getModel = IOC.getModule(config.model);
        this.getView = IOC.getModule(config.view);
    };

    IOC.prototype.getComponent = function (type, cb) {
        var _getController = this.getController(type);
        var _getModel = this.getModel(type); 
        var _getView = this.getView(type);

        $.when(_getController, _getModel, _getView).then(
            function (Controller, Model, View) {
                var m = new Model(type);
                var v = new View(type);
                var c = new Controller(m, v);

                cb(c);
            }
        );
    };

    IOC.getModule = function (mod) {
        var rel = "";
        var _getModName = function () {
            return mod;
        };

        if (isObject(mod)) {
            _getModName = toFunction(mod.module);
            rel = mod.inherit || "";
        }

        return function (type) {
            var t = $.Deferred();
            var modName = _getModName(type);

            if (!rel) {
                require([modName], function (Mod) {
                    return t.resolve(Mod);
                });
                return t;
            }

            require([rel], function (Rel) {
                if (!modName) return t.resolve(Rel);
                
                require([modName], function (Mod) {
                    var NewMod = function () {
                        Rel.apply(this, arguments);
                        Mod.apply(this, arguments);
                    };

                    IOC.inherit(Rel, Mod);

                    return t.resolve(IOC.inherit(Mod, NewMod));
                });
            });

            return t;
        };
    }

    IOC.inherit = function (Parent, Child) {
        var childpt = Child.prototype;
        var parentpt = Parent.prototype;

        for (var k in parentpt) {
            if (parentpt.hasOwnProperty(k) && !childpt.hasOwnProperty(k)) {
                childpt[k] = parentpt[k];
            }
        }

        return Child;
    }

    function type(typename) {
        return function (o) {
            return Object.prototype.toString.call(o) == '[object ' + typename + ']';
        };
    }

    function toFunction(o) {
        if (isFunction(o)) return o;

        return function () {
            return o;
        };
    }

    return {
        init: function (config) {
            return new IOC(config);
        }
    }
});