簡體   English   中英

如何讓Rhino運行自定義的javascript setTimeout函數,無休止的eval

[英]How to make Rhino to run custom javascript setTimeout function, endless eval

我有用javascript編寫的gameboy腳本我試圖讓它在java中運行。 (我不是在尋找任何java gameboy模擬器)。

我有這兩個文件的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(); 
}

我在另一個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])
}

現在,下面是我的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();
        }
    }    
}

我正在嘗試按順序檢索幀計數器,但是每次輸出都是frame = 1 ..這意味着腳本會在我想要的時候從頭開始重新啟動,繼續不停並繼續引用先前的變量,老實說它甚至不應該重啟它應該只是繼續使用setTimeout() function

另外,如果要問為什么Rhino總是占用50%的CPU和100 MB的ram,當它甚至沒有做任何事情時,可能應該在達到setTimeout無限循環時達到平衡。 (如果可能的話)。

我想我需要context.compileString只是無法搞清楚。

找到解決方案只需將它放在任何javascripts中,然后再運行rhino。

還有一個錯誤,無法找到JavaAdapter確保您使用Rhino 1.7R5修復此錯誤。

只需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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM