[EMAIL PROTECTED] a écrit :

> On Jan 10, 12:58 pm, Christophe Grand <[EMAIL PROTECTED]> wrote:
>> [EMAIL PROTECTED] a écrit :
>>
>>> Hi,
>>> I am starting to get pretty serious about using Rhino as a general
>>> purpose server-side language, and one of the main issues that I still
>>> need to solve is package/namespace management. I strongly suspect that
>>> someone has developed a solution to this already, but if not then I

...

> What you describe is absolutely what I'm looking for. If you can
> provide code that would be wonderful, and if not I would certainly
> appreciate any description you could give. This sounds like such a
> common thing to need, I'm surprised that a standard for this has not
> emerged yet. If you are willing to share your code, perhaps it could
> become the basis for a library?
> 
> Many Thanks,
> Ben Reesman

I'm all for making a library (or a libraries repository) for Rhino based 
on a package system -- I thought about that when I created this package 
and put it aside, waiting to have more time...


Meanwhile, here is the code. Two remarks:
* it's not thread-safe (a couple of calls to sync may solve this issue),
* it depends on :
Function.prototype.autovarargs = function() {
        var f = this;
        return function() {
                if (arguments.length > 1) {
                        return Array.prototype.map.call(arguments, f, this);
                } else {
                        return f.apply(this, arguments);
                }
        }
};


// A package system for javascript
// Christophe Grand, 2007
Package = (function() {
        var caller = "";
        var dependencies = {};
        var packages = {};

        var unitPkgName = undefined;
        
        // returned package may be a stub -- in case of recursive dependencies
        function importPackage(name) {
                if (packages[name] === undefined) {
                        dependencies[name] = dependencies[name] || {};
                        Package.loader(name);
                }
                dependencies[name][caller] = true;
                return packages[name];
        }
                
        var Package = function(name, def) {
                if (unitPkgName && unitPkgName !== name) {
                        if (app.log) log("Trying to define package: '" + 
String(name) + "' 
while package '" + String(unitPkgName) + "' expected.");
                        return;
                }
                if (app.log) log("Loading package: '" + String(name) + "'");
                if (packages[name] === undefined) {
                        var pkg = {};
                        packages[name] = pkg;
                        dependencies[name] = dependencies[name] || {};
                        var ccaller = caller;
                        caller = name;
                        try {
                                def(pkg);
                        } finally {
                                caller = ccaller;
                        }
                } else {
                        if (app.log) log("Package '" + String(name) + "' 
already loaded!");
                }
        }
        
        // Unload specified packages and packages depending on them
        Package.unload = function() {
                var unloaded = [];
                function unload(name) {
                        var pkg = packages[name];
                        if (pkg === undefined) {
                                if (name === "") {
                                        needReboot = true;
                                }
                                return;
                        }
        
                        if (app.log) log("Unloading package: '" + String(name) 
+ "'");
                        packages[name] = undefined;
                        unloaded.push(name);
        
                        var dependents = dependencies[name];
                        if (dependents !== undefined) {
                                dependencies[name] = undefined;
                                for(var dependent in dependents) {
                                        unload(dependent);
                                }
                        }
                        if (Package.onUnload) Package.onUnload(name, pkg);
                };
        
                var unloadVarArgs = unload.autovarargs();
                unloadVarArgs.apply(this, arguments);
                return unloaded;
        }
        
        // Unload specified packages and packages depending on them
        // and reload them all
        Package.reload = function() {
                const unloaded = Package.unload.apply(this, arguments);
                unloaded.forEach(Package.get);
        }
        
        Package.unloadAll = function() {
                for(var name in packages) {
                        try {
                                Package.unload(name);
                        } catch (e) {
                                log(e);
                        }
                }
        }

        // Package.defineOnly executes f but only allow declaration of Package 
"name".
        // Package.defineOnly is called from loaders implementations
        Package.defineOnly = function(name, f) {
                var bak = unitPkgName;
                unitPkgName = name;
                try {
                        f();
                } finally {
                        unitPkgName = bak;
                }
        };

        Package.get = importPackage.autovarargs();
        
        // loader is a function taking one arg (the package name)
        Package.loader = undefined;
        
        // onUnload is an optional callback taking two args (the package name 
and the package)
        Package.onUnload = undefined;
        
        return Package;
}) ();
_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino

Reply via email to