Эффективный способ запуска нескольких скриптов с использованием javax.script

Я занимаюсь разработкой игры, в которой я хотел бы иметь несколько сценариев, которые реализуют одну и ту же структуру. Каждый сценарий должен быть запущен в отдельной области видимости, чтобы код не перекрывал другие сценарии. Например:

structure.js

function OnInit() {
    // Define resources to load, collision vars, etc.
}

function OnLoop() {
    // Every loop
}

function ClickEvent() {
   // Someone clicked me
}

// Other fun functions

Теперь, допустим, у меня есть: "BadGuy.js", "ReallyReallyBadGuy.js", "OtherBadGuy.js" - все они выглядят как выше с точки зрения структуры. В игре всякий раз, когда происходит событие, я бы хотел вызвать соответствующую функцию.

Проблема сводится к эффективности и скорости. Я нашел рабочее решение, создав механизм для каждого экземпляра скрипта (используя getEngineByName), но это просто не кажется мне идеальным.

Если нет лучшего решения, я, вероятно, прибегну к каждому сценарию, имеющему свои уникальные имена классов / функций. Т.е.

BadGuy.js

var BadGuy = new Object();

BadGuy.ClickEvent = function() {
}

1 ответ

Я не думаю, что вам нужно создавать новый ScriptEngine для каждого "парня". Вы можете управлять ими в одном движке. Так что с предварительными извинениями за убийство вас сценарий игры.....

  1. Получить один экземпляр двигателя Rhino.
  2. Выполните операторы eval(script) для добавления новых JS-объектов в движок вместе с различными режимами поведения (или функциями), которые вы хотите, чтобы эти объекты поддерживали.
  3. У вас есть несколько вариантов выбора для каждого из них, но если у каждого "парня" есть уникальное имя, вы всегда можете ссылаться на них по имени и вызывать именованный метод против него.
  4. Для более чувствительных к производительности операций (возможно, своего рода циклический цикл обработки событий) вы можете предварительно скомпилировать скрипт в том же движке, который затем может быть выполнен без необходимости повторной оценки источника.

Вот пример, который я написал в Groovy.

import javax.script.*;
sem = new ScriptEngineManager();
engine = sem.getEngineByExtension("js");
engine.getBindings(ScriptContext.ENGINE_SCOPE).put("out", System.out);
eventLoop = "for(guy in allGuys) { out.println(allGuys[guy].Action(action)); }; "
engine.eval("var allGuys = []");
engine.eval("var BadGuy = new Object(); allGuys.push(BadGuy); BadGuy.ClickEvent = function() { return 'I am a BadGuy' }; BadGuy.Action = function(activity) { return 'I am doing ' + activity + ' in a BAD way' }");
engine.eval("var GoodGuy = new Object(); allGuys.push(GoodGuy); GoodGuy.ClickEvent = function() { return 'I am a GoodGuy' }; GoodGuy.Action = function(activity) { return 'I am doing ' + activity + ' in a GOOD way' }");
CompiledScript executeEvents = engine.compile(eventLoop);
println engine.invokeMethod(engine.get("BadGuy"), "ClickEvent");
println engine.invokeMethod(engine.get("GoodGuy"), "ClickEvent");
engine.getBindings(ScriptContext.ENGINE_SCOPE).put("action", "knitting");
executeEvents.eval();
Другие вопросы по тегам