diff --git a/src/main/resources/api/msp.js b/src/main/resources/api/msp.js index 842d504..bc5cd39 100644 --- a/src/main/resources/api/msp.js +++ b/src/main/resources/api/msp.js @@ -9,6 +9,5 @@ exports = module.exports = { permission: impl('permission'), server: impl('server'), task: impl('task'), - item: impl('item'), - player: impl('player') + item: impl('item') }; \ No newline at end of file diff --git a/src/main/resources/api/player.js b/src/main/resources/api/player.js deleted file mode 100644 index eec4798..0000000 --- a/src/main/resources/api/player.js +++ /dev/null @@ -1,2 +0,0 @@ -/*global Java, base, module, exports, require*/ -module.exports = require('./msp.js').player; \ No newline at end of file diff --git a/src/main/resources/api/wrapper.js b/src/main/resources/api/wrapper.js index 129f8ac..0e38a78 100644 --- a/src/main/resources/api/wrapper.js +++ b/src/main/resources/api/wrapper.js @@ -1,5 +1,5 @@ /*global Java, base, module, exports, require*/ -var player = require('./player'); +var player = requireInternal('wrapper/player'); module.exports = { player: player.$ } \ No newline at end of file diff --git a/src/main/resources/internal/bukkit/player.js b/src/main/resources/internal/bukkit/wrapper/player.js similarity index 54% rename from src/main/resources/internal/bukkit/player.js rename to src/main/resources/internal/bukkit/wrapper/player.js index a9262a7..0606713 100644 --- a/src/main/resources/internal/bukkit/player.js +++ b/src/main/resources/internal/bukkit/wrapper/player.js @@ -1,12 +1,17 @@ +/** + * Bukkit 玩家方法代理类 + * Created by 蒋天蓓 on 2018/1/5 0009. + */ /*global Java, base, module, exports, require*/ +var ref = require('reflect'); var Player = { - createNew: function (inner) { + createNew: function createNew(inner) { var player = {}; player.handler = inner; player.sendMessage = function (msg) { this.handler.sendMessage(msg); }; - return player; + return Object.assign(ref.mapToObject(inner), player); } }; diff --git a/src/main/resources/internal/sponge/player.js b/src/main/resources/internal/sponge/player.js deleted file mode 100644 index d7e642b..0000000 --- a/src/main/resources/internal/sponge/player.js +++ /dev/null @@ -1,14 +0,0 @@ -/*global Java, base, module, exports, require*/ -var Player = { - createNew: function (inner) { - var player = {}; - var Text = Java.type('org.spongepowered.api.text.Text'); - player.handler = inner; - player.sendMessage = function (msg) { - this.handler.sendMessage(Text.of(msg)); - }; - return player; - } -}; - -exports.$ = Player.createNew; \ No newline at end of file diff --git a/src/main/resources/internal/sponge/wrapper/player.js b/src/main/resources/internal/sponge/wrapper/player.js new file mode 100644 index 0000000..c54451b --- /dev/null +++ b/src/main/resources/internal/sponge/wrapper/player.js @@ -0,0 +1,19 @@ +/** + * Sponge 玩家方法代理类 + * Created by 蒋天蓓 on 2018/1/5 0009. + */ +/*global Java, base, module, exports, require*/ +var ref = require('reflect'); +var Text = Java.type('org.spongepowered.api.text.Text'); +var Player = { + createNew: function createNew(inner) { + var player = {}; + player.handler = inner; + player.sendMessage = function (msg) { + this.handler.sendMessage(Text.of(msg)); + }; + return Object.assign(ref.mapToObject(inner), player); + } +}; + +exports.$ = Player.createNew; \ No newline at end of file diff --git a/src/main/resources/modules/reflect.js b/src/main/resources/modules/reflect.js index 19544fb..ee7d57f 100644 --- a/src/main/resources/modules/reflect.js +++ b/src/main/resources/modules/reflect.js @@ -33,26 +33,10 @@ function Reflect(obj) { } }; - this.method = function (name, clazzs) { - try { - return this.class.getMethod(name, clazzs); - } catch (ex) { - return this.class.getDeclaredMethod(name, clazzs); - } - }; - - this.cacheMethod = function (name, clazzs) { - var mkey = this.class.name + '.' + name + ':' + clazzs.join(':'); - if (!methodCache[mkey]) { - methodCache[mkey] = this.method(name, clazzs); - } - return methodCache[mkey]; - }; - this.call = function () { var name = arguments[0]; var params = Array.prototype.slice.call(arguments, 1); - var method = this.cacheMethod(name, types(params)); + var method = declaredMethod(this.class, name, types(params)); return on(method.invoke(this.get(), params)); }; @@ -61,11 +45,7 @@ function Reflect(obj) { }; this.set = function (name, value) { - try { - this.class.getField(name).set(this.obj, value); - } catch (ex) { - accessible(this.class.getDeclaredField(name)).set(this.obj, value); - } + accessible(declaredField(this.class, name)).set(this.obj, value); return this; }; @@ -132,9 +112,74 @@ function declaredField(clazz, name) { return field; } +function declaredMethod(clazz, name, clazzs) { + var mkey = clazz.name + '.' + name + ':' + (clazzs || []).join(':'); + if (!methodCache[mkey]) { + try { + methodCache[mkey] = clazz.getMethod(name, clazzs); + } catch (ex) { + methodCache[mkey] = clazz.getDeclaredMethod(name, clazzs); + } + } + return methodCache[mkey]; +} + +function declaredMethod(clazz, name, clazzs) { + var mkey = clazz.name + '.' + name + ':' + (clazzs || []).join(':'); + if (!methodCache[mkey]) { + try { + methodCache[mkey] = clazz.getMethod(name, clazzs); + } catch (ex) { + methodCache[mkey] = clazz.getDeclaredMethod(name, clazzs); + } + } + return methodCache[mkey]; +} + +function declaredMethods(clazz) { + return clazz.declaredMethods; +} + +var classMethodsCache = []; + +function mapToObject(javaObj) { + if (!javaObj || !javaObj.class) { throw new TypeError('参数 %s 不是一个Java对象!'.format(javaObj)) } + var target = {}; + getJavaObjectMethods(javaObj).forEach(function proxyMethod(t){ mapMethod(target, javaObj, t) }) + return target; +} + +function getJavaObjectMethods(javaObj) { + var className = javaObj.class.name + if (!classMethodsCache[className]) { + var names = []; + var methods = javaObj.class.methods; + for (var i in methods){ + names.push(methods[i].name); + } + classMethodsCache[className] = names; + } + return classMethodsCache[className]; +} + +function mapMethod (target, source, name) { + target[name] = function __SimpleDynamicMethod__() { + if (arguments.length > 0) { + return source[name](Array.prototype.slice.call(arguments)); + } else { + return source[name](); + } + }; +} + function on(obj) { + if (!obj || !obj.class) { throw new TypeError('参数 %s 不是一个Java对象!'.format(obj)) } return new Reflect(obj); } -exports.on = on; -exports.accessible = accessible; \ No newline at end of file +exports = module.exports = { + on: on, + accessible: accessible, + declaredMethods: declaredMethods, + mapToObject: mapToObject +}