2013-12-21 09:58:40 +01:00
|
|
|
/*************************************************************************
|
2013-12-21 10:09:11 +01:00
|
|
|
## Require - Node.js-style module loading in ScriptCraft
|
2013-12-21 09:58:40 +01:00
|
|
|
|
2013-12-21 10:09:11 +01:00
|
|
|
#### (Experimental as of 2013-12-21)
|
2013-12-21 09:58:40 +01:00
|
|
|
|
|
|
|
Node.js is a server-side javascript environment with an excellent
|
|
|
|
module loading system based on CommonJS. Modules in Node.js are really
|
|
|
|
simple. Each module is in its own javascript file and all variables
|
2013-12-21 10:09:11 +01:00
|
|
|
and functions within the file are private to that file/module only.
|
|
|
|
There is a very concise explanation of CommonJS modules at...
|
|
|
|
|
|
|
|
[http://wiki.commonjs.org/wiki/Modules/1.1.1.][cjsmodules]
|
2013-12-21 09:58:40 +01:00
|
|
|
|
|
|
|
If you want to export a variable or function you use the module.export
|
|
|
|
property.
|
|
|
|
|
|
|
|
For example imagine you have 3 files program.js, inc.js and math.js ...
|
|
|
|
|
2013-12-21 10:09:11 +01:00
|
|
|
### math.js
|
2013-12-21 09:58:40 +01:00
|
|
|
|
|
|
|
exports.add = function(a,b){
|
|
|
|
return a + b;
|
|
|
|
}
|
|
|
|
|
2013-12-21 10:09:11 +01:00
|
|
|
### inc.js
|
2013-12-21 09:58:40 +01:00
|
|
|
|
|
|
|
var math = require('./math');
|
|
|
|
exports.increment = function(n){
|
|
|
|
return math.add(n, 1);
|
|
|
|
}
|
|
|
|
|
2013-12-21 10:09:11 +01:00
|
|
|
### program.js
|
2013-12-21 09:58:40 +01:00
|
|
|
|
|
|
|
var inc = require('./inc').increment;
|
|
|
|
var a = 7;
|
|
|
|
a = inc(a);
|
|
|
|
print(a);
|
|
|
|
|
|
|
|
You can see from the above sample code that programs can use modules
|
|
|
|
and modules themeselves can use other modules. Modules have full
|
|
|
|
control over what functions and properties they want to provide to
|
|
|
|
others.
|
|
|
|
|
|
|
|
## Important
|
|
|
|
|
|
|
|
Although ScriptCraft now supports Node.js style modules, it does not
|
|
|
|
support node modules. Node.js and Rhino are two very different
|
|
|
|
Javascript environments. ScriptCraft uses Rhino Javascript, not
|
|
|
|
Node.js.
|
|
|
|
|
2013-12-21 10:09:11 +01:00
|
|
|
Right now, the base directory is for relative modules is 'js-plugins'.
|
|
|
|
Modules can be loaded using relative or absolute paths. Per the CommonJS
|
|
|
|
module specification, the '.js' suffix is optional.
|
|
|
|
|
|
|
|
[cjsmodules]: http://wiki.commonjs.org/wiki/Modules/1.1.1.
|
|
|
|
|
2013-12-21 09:58:40 +01:00
|
|
|
***/
|
|
|
|
(function(__plugin, __engine, verbose){
|
|
|
|
/*
|
|
|
|
wph 20131215 Experimental
|
|
|
|
*/
|
|
|
|
var _loadedModules = {};
|
|
|
|
|
|
|
|
var _require = function(parentFile, path)
|
|
|
|
{
|
|
|
|
var _canonize = function(file){
|
|
|
|
return "" + file.canonicalPath.replaceAll("\\\\","/");
|
|
|
|
};
|
|
|
|
|
|
|
|
var file = new java.io.File(parentFile, path);
|
|
|
|
if (!file.exists())
|
|
|
|
{
|
|
|
|
if (path.match(/\.js$/i)){
|
|
|
|
__plugin.logger.warning('require("' + path + '") failed. File [' + file.canonicalPath + '] not found');
|
|
|
|
return;
|
|
|
|
}else{
|
|
|
|
path = path + '.js';
|
|
|
|
file = new java.io.File(parentFile, path);
|
|
|
|
if (!file.exists()){
|
|
|
|
__plugin.logger.warning('require("' + path + '") failed. File [' + file.canonicalPath + '] not found');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (file.isDirectory()){
|
|
|
|
__plugin.logger.warning('require("' + path + '") directories not yet supported. ' + file.canonicalPath);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var canonizedFilename = _canonize(file);
|
|
|
|
|
|
|
|
var moduleInfo = _loadedModules[canonizedFilename];
|
|
|
|
if (moduleInfo){
|
|
|
|
return moduleInfo;
|
|
|
|
}
|
|
|
|
if (verbose){
|
|
|
|
print("loading module " + canonizedFilename);
|
|
|
|
}
|
|
|
|
var reader = new java.io.FileReader(file);
|
|
|
|
var br = new java.io.BufferedReader(reader);
|
|
|
|
var code = "";
|
|
|
|
while ((r = br.readLine()) !== null) code += r + "\n";
|
|
|
|
|
|
|
|
var head = "(function(exports,module,require,__filename,__dirname){ ";
|
|
|
|
|
|
|
|
moduleInfo = {
|
|
|
|
loaded: false,
|
|
|
|
id: canonizedFilename,
|
|
|
|
exports: {}
|
|
|
|
};
|
|
|
|
var tail = "})";
|
|
|
|
code = head + code + tail;
|
|
|
|
|
|
|
|
_loadedModules[canonizedFilename] = moduleInfo;
|
|
|
|
moduleInfo.main = __engine.eval(code);
|
|
|
|
moduleInfo.main(moduleInfo.exports,
|
|
|
|
moduleInfo,
|
|
|
|
_requireClosure(file.parentFile),
|
|
|
|
canonizedFilename,
|
|
|
|
"" + parentFile?parentFile.canonicalPath:"");
|
|
|
|
moduleInfo.loaded = true;
|
|
|
|
return moduleInfo;
|
|
|
|
};
|
|
|
|
|
|
|
|
var _requireClosure = function(parent){
|
|
|
|
return function(path){
|
|
|
|
var module = _require(parent, path);
|
|
|
|
return module.exports;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
return _requireClosure(new java.io.File("./"));
|
|
|
|
})
|