Question

I have gameboy script I found written in javascript I'm trying to get it to run in java. (I'm not looking for any java gameboy emulators).

I have a javascript with these two files

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

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.

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

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. (if it's possible that is).

I think I need context.compileString just can't figure it out.

Was it helpful?

Solution

Found solution just put this in any of your javascripts before running rhino on them.

There was also a bug that JavaAdapter couldn't be found make sure you use Rhino 1.7R5 where this bug is fixed.

Just 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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top