[英]How to make Rhino to run custom javascript setTimeout function, endless eval
I have gameboy script I found written in javascript I'm trying to get it to run in java. 我有用javascript编写的gameboy脚本我试图让它在java中运行。 (I'm not looking for any java gameboy emulators).
(我不是在寻找任何java gameboy模拟器)。
I have a javascript with these two files 我有这两个文件的JavaScript
function cout(e, t) {
java.lang.System.out.println("e = " + e + " t = " + t);
}
function setTimeout(expr, msec) {
if (typeof expr == "function") {
// save the global object and trailing args for later apply
var gobj = this;
var args = [].concat(arguments).slice(2);
var o = {actionPerformed: function(){expr.apply(gobj, args)}};
} else {
var o = {actionPerformed: function(){eval(expr)}};
}
var al = new java.awt.event.ActionListener(o);
var t = new javax.swing.Timer(msec, al);
t.start();
}
I have in another javascript file something like this 我在另一个javascript文件中有这样的东西
var frames = 0;
function tick() {
var a = (new Date().getTime() - tstart) - ttime;
while (a > settings[6]) {
ttime += settings[6];
a = (new Date().getTime() - tstart) - ttime;
gameboy.run()
frames++;
}
setTimeout(tick, settings[6])
}
Now below is my Java Rhino code modified one of those examples. 现在,下面是我的Java Rhino代码修改其中一个示例。
public class GameBoyJS {
/**
* Main entry point.
*
* Process arguments as would a normal Java program. Also
* create a new Context and associate it with the current thread.
* Then set up the execution environment and begin to
* execute scripts.
*/
public GameBoyJS()
{
Context context = Context.enter();
try {
Scriptable globalScope = context.initStandardObjects();
Reader base64LibReader = new InputStreamReader(getClass().getResourceAsStream("js/base64.js"));
//Reader msgpackLibReader = new InputStreamReader(getClass().getResourceAsStream("js/msgpack.js"));
Reader json2LibReader = new InputStreamReader(getClass().getResourceAsStream("js/json2.js"));
Reader terminalLibReader = new InputStreamReader(getClass().getResourceAsStream("js/terminal.js"));
//Reader resizeLibReader = new InputStreamReader(getClass().getResourceAsStream("js/resize.js"));
Reader GameBoyIOLibReader = new InputStreamReader(getClass().getResourceAsStream("js/GameBoyIO.js"));
Reader GameBoyCoreLibReader = new InputStreamReader(getClass().getResourceAsStream("js/GameBoyCore.js"));
//Reader XAudioServerLibReader = new InputStreamReader(getClass().getResourceAsStream("js/XAudioServer.js"));
//Replace this with your current gameboy rom file.
Reader RomLibReader = new InputStreamReader(getClass().getResourceAsStream("js/roms/crystal.js"));
//Put the files into javascript engine.
context.evaluateReader(globalScope, base64LibReader, "base64.js", 1, null);
//context.evaluateReader(globalScope, msgpackLibReader, "msgpack.js", 1, null);
context.evaluateReader(globalScope, json2LibReader, "json2.js", 1, null);
context.evaluateReader(globalScope, terminalLibReader, "terminal.js", 1, null);
//context.evaluateReader(globalScope, resizeLibReader, "resize.js", 1, null);
context.evaluateReader(globalScope, GameBoyIOLibReader, "GameBoyIO.js", 1, null);
context.evaluateReader(globalScope, GameBoyCoreLibReader, "GameBoyCore.js", 1, null);
//context.evaluateReader(globalScope, XAudioServerLibReader, "XAudioServer.js", 1, null);
context.evaluateReader(globalScope, RomLibReader, "crystal.js", 1, null);
// Add a global variable out that is a JavaScript reflection of the System.out variable:
Object wrappedOut = Context.javaToJS(System.out, globalScope);
ScriptableObject.putProperty(globalScope, "out", wrappedOut);
String code = "cout('Gameboy frame finished' + frames);";
context.evaluateString(globalScope, code, "<mem>", 1, null);
// Tried a hack here (this below is stupid but just to prove my suspensions)
for(int i = 0;i <=50; i++) {
context.evaluateString(globalScope, code, "<mem>", 1, null);
System.out.println("okay next frame");
}
} catch(IOException ioe) {
ioe.printStackTrace();
} finally {
Context.exit();
}
}
}
I'm trying to retrieve the frames counter in order, But every time the output is frame=1.. meaning the script keeps getting restarted from the beginning when I want it, to keep going non-stop and keep references of previous variables, honestly it shouldn't even restart it should just keep going forever with that setTimeout() function
我正在尝试按顺序检索帧计数器,但是每次输出都是frame = 1 ..这意味着脚本会在我想要的时候从头开始重新启动,继续不停并继续引用先前的变量,老实说它甚至不应该重启它应该只是继续使用
setTimeout() function
Also if it's too much to ask why does Rhino always take 50% of my CPU and 100 MB of ram when it's not even doing anything probably should level out when it gets to that setTimeout endless loop. 另外,如果要问为什么Rhino总是占用50%的CPU和100 MB的ram,当它甚至没有做任何事情时,可能应该在达到setTimeout无限循环时达到平衡。 (if it's possible that is).
(如果可能的话)。
I think I need context.compileString
just can't figure it out. 我想我需要
context.compileString
只是无法搞清楚。
Found solution just put this in any of your javascripts before running rhino on them. 找到解决方案只需将它放在任何javascripts中,然后再运行rhino。
There was also a bug that JavaAdapter couldn't be found make sure you use Rhino 1.7R5 where this bug is fixed. 还有一个错误,无法找到JavaAdapter确保您使用Rhino 1.7R5修复此错误。
Just google for rhino-1.7R5-SNAPSHOT.jar
只需google for
rhino-1.7R5-SNAPSHOT.jar
(function(global) {
var timer = new java.util.Timer();
var counter = 1;
var ids = {};
global.setTimeout = function(fn, delay) {
var id = counter;
counter += 1;
ids[id] = new JavaAdapter(java.util.TimerTask, { run : fn });
timer.schedule(ids[id], delay);
return id;
};
global.clearTimeout = function(id) {
ids[id].cancel();
timer.purge();
delete ids[id];
};
global.setInterval = function(fn, delay) {
var id = counter;
counter += 1;
ids[id] = new JavaAdapter(java.util.TimerTask, { run : fn });
timer.schedule(ids[id], delay, delay);
return id;
};
global.clearInterval = global.clearTimeout;
// exports object in case of "isCommonJS"
global.exports = {};
})(this);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.