kopia lustrzana https://github.com/jameshball/osci-render
Optimise Lua parsing for lower power machines
rodzic
c3df42c949
commit
9537bb2312
6
pom.xml
6
pom.xml
|
@ -201,6 +201,12 @@
|
|||
<artifactId>luaj-jse</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.bcel/bcel -->
|
||||
<dependency>
|
||||
<groupId>org.apache.bcel</groupId>
|
||||
<artifactId>bcel</artifactId>
|
||||
<version>6.5.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
<profile>
|
||||
|
|
|
@ -51,13 +51,11 @@ public class JavaAudioInput implements AudioInput {
|
|||
byte[] data = new byte[CHUNK_SIZE];
|
||||
microphone.start();
|
||||
while (!stopped) {
|
||||
if (microphone.available() >= CHUNK_SIZE) {
|
||||
microphone.read(data, 0, CHUNK_SIZE);
|
||||
for (int i = 0; i < CHUNK_SIZE / 2; i += 2 * STEP_SIZE) {
|
||||
short sample = (short) ((data[2 * i + 1] << 8) + data[2 * i]);
|
||||
for (AudioInputListener listener : listeners) {
|
||||
listener.transmit((double) sample / Short.MAX_VALUE);
|
||||
}
|
||||
microphone.read(data, 0, CHUNK_SIZE);
|
||||
for (int i = 0; i < CHUNK_SIZE / 2; i += 2 * STEP_SIZE) {
|
||||
short sample = (short) ((data[2 * i + 1] << 8) + data[2 * i]);
|
||||
for (AudioInputListener listener : listeners) {
|
||||
listener.transmit((double) sample / Short.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ public class Gui extends Application {
|
|||
@Override
|
||||
public void start(Stage stage) throws Exception {
|
||||
System.setProperty("prism.lcdtext", "false");
|
||||
System.setProperty("org.luaj.luajc", "true");
|
||||
|
||||
editor = new CodeEditor();
|
||||
editor.initialize();
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package sh.ball.parser.lua;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
import sh.ball.audio.FrameSource;
|
||||
import sh.ball.parser.FileParser;
|
||||
import sh.ball.shapes.Vector2;
|
||||
|
@ -10,7 +13,13 @@ import java.util.stream.Collectors;
|
|||
|
||||
public class LuaParser extends FileParser<FrameSource<Vector2>> {
|
||||
|
||||
private final LuaSampleSource sampleSource = new LuaSampleSource();
|
||||
private static final Globals globals = JsePlatform.standardGlobals();
|
||||
|
||||
static {
|
||||
org.luaj.vm2.luajc.LuaJC.install(globals);
|
||||
}
|
||||
|
||||
private final LuaSampleSource sampleSource = new LuaSampleSource(globals);
|
||||
|
||||
private String script;
|
||||
|
||||
|
@ -26,11 +35,9 @@ public class LuaParser extends FileParser<FrameSource<Vector2>> {
|
|||
|
||||
@Override
|
||||
public FrameSource<Vector2> parse() throws Exception {
|
||||
ScriptEngineManager sem = new ScriptEngineManager();
|
||||
Compilable e = (Compilable) sem.getEngineByName("luaj");
|
||||
CompiledScript compiledScript = e.compile(script);
|
||||
LuaFunction f = globals.load(new StringReader(script), "script").checkfunction();
|
||||
|
||||
sampleSource.setScript(script, compiledScript);
|
||||
sampleSource.setFunction(script, f);
|
||||
|
||||
return sampleSource;
|
||||
}
|
||||
|
|
|
@ -1,34 +1,40 @@
|
|||
package sh.ball.parser.lua;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.*;
|
||||
import org.luaj.vm2.lib.ThreeArgFunction;
|
||||
import org.luaj.vm2.lib.TwoArgFunction;
|
||||
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
||||
import sh.ball.audio.FrameSource;
|
||||
import sh.ball.shapes.Vector2;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleBindings;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public class LuaSampleSource implements FrameSource<Vector2> {
|
||||
|
||||
private Bindings bindings = new SimpleBindings();
|
||||
private CompiledScript lastWorkingScript;
|
||||
private final Globals globals;
|
||||
private final Map<LuaString, LuaValue> bindings = new HashMap<>();
|
||||
private final Set<LuaString> programDefinedVariables = new HashSet<>();
|
||||
private LuaFunction lastWorkingFunction;
|
||||
private String lastWorkingTextScript;
|
||||
private CompiledScript script;
|
||||
private LuaFunction function;
|
||||
private String textScript;
|
||||
private boolean active = true;
|
||||
private long step = 1;
|
||||
private Set<String> programDefinedVariables = new HashSet<>();
|
||||
|
||||
public void setScript(String textScript, CompiledScript script) {
|
||||
if (lastWorkingScript == null) {
|
||||
lastWorkingScript = script;
|
||||
public LuaSampleSource(Globals globals) {
|
||||
this.globals = globals;
|
||||
}
|
||||
|
||||
public void setFunction(String textScript, LuaFunction function) {
|
||||
if (lastWorkingFunction == null) {
|
||||
lastWorkingFunction = function;
|
||||
lastWorkingTextScript = textScript;
|
||||
}
|
||||
this.script = script;
|
||||
this.function = function;
|
||||
this.textScript = textScript;
|
||||
}
|
||||
|
||||
|
@ -37,31 +43,32 @@ public class LuaSampleSource implements FrameSource<Vector2> {
|
|||
try {
|
||||
boolean updatedFile = false;
|
||||
|
||||
bindings.put("step", (double) step);
|
||||
globals.setmetatable(new BindingsMetatable(bindings));
|
||||
bindings.put(LuaValue.valueOf("step"), LuaValue.valueOf((double) step));
|
||||
|
||||
LuaValue result;
|
||||
try {
|
||||
result = (LuaValue) script.eval(bindings);
|
||||
result = (LuaValue) LuaSampleSource.eval(function, globals);
|
||||
if (!lastWorkingTextScript.equals(textScript)) {
|
||||
lastWorkingScript = script;
|
||||
lastWorkingFunction = function;
|
||||
lastWorkingTextScript = textScript;
|
||||
updatedFile = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result = (LuaValue) lastWorkingScript.eval(bindings);
|
||||
result = (LuaValue) LuaSampleSource.eval(lastWorkingFunction, globals);
|
||||
}
|
||||
step++;
|
||||
|
||||
if (updatedFile) {
|
||||
// reset variables
|
||||
step = 1;
|
||||
List<String> variablesToRemove = new ArrayList<>();
|
||||
List<LuaString> variablesToRemove = new ArrayList<>();
|
||||
bindings.keySet().forEach(name -> {
|
||||
if (!programDefinedVariables.contains(name)) {
|
||||
variablesToRemove.add(name);
|
||||
}
|
||||
});
|
||||
variablesToRemove.forEach(name -> bindings.remove(name));
|
||||
variablesToRemove.forEach(bindings::remove);
|
||||
}
|
||||
|
||||
return new Vector2(result.get(1).checkdouble(), result.get(2).checkdouble());
|
||||
|
@ -94,11 +101,109 @@ public class LuaSampleSource implements FrameSource<Vector2> {
|
|||
}
|
||||
|
||||
public void setVariable(String variableName, Object value) {
|
||||
programDefinedVariables.add(variableName);
|
||||
bindings.put(variableName, value);
|
||||
programDefinedVariables.add(LuaValue.valueOf(variableName));
|
||||
bindings.put(LuaValue.valueOf(variableName), toLua(value));
|
||||
}
|
||||
|
||||
public void resetStep() {
|
||||
step = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2007 LuaJ. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit p ersons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
------------------------------
|
||||
|
||||
The below functions have all been modified by James Ball to optimise Lua parsing
|
||||
on machines with poorer performance.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
static class BindingsMetatable extends LuaTable {
|
||||
|
||||
BindingsMetatable(Map<LuaString, LuaValue> bindings) {
|
||||
this.rawset(LuaValue.INDEX, new TwoArgFunction() {
|
||||
public LuaValue call(LuaValue table, LuaValue key) {
|
||||
LuaValue value = bindings.get(key.checkstring());
|
||||
if (value == null) {
|
||||
return LuaValue.NIL;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.rawset(LuaValue.NEWINDEX, new ThreeArgFunction() {
|
||||
public LuaValue call(LuaValue table, LuaValue key, LuaValue value) {
|
||||
if (value == null || value.type() == LuaValue.TNIL) {
|
||||
bindings.remove(key.checkstring());
|
||||
} else {
|
||||
bindings.put(key.checkstring(), value);
|
||||
}
|
||||
return LuaValue.NONE;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static private LuaValue toLua(Object javaValue) {
|
||||
return javaValue == null? LuaValue.NIL:
|
||||
javaValue instanceof LuaValue? (LuaValue) javaValue:
|
||||
CoerceJavaToLua.coerce(javaValue);
|
||||
}
|
||||
|
||||
static private Object toJava(LuaValue luajValue) {
|
||||
return switch (luajValue.type()) {
|
||||
case LuaValue.TNIL -> null;
|
||||
case LuaValue.TSTRING -> luajValue.tojstring();
|
||||
case LuaValue.TUSERDATA -> luajValue.checkuserdata(Object.class);
|
||||
case LuaValue.TNUMBER -> luajValue.isinttype() ?
|
||||
(Object) luajValue.toint() :
|
||||
(Object) luajValue.todouble();
|
||||
default -> luajValue;
|
||||
};
|
||||
}
|
||||
|
||||
static private Object toJava(Varargs v) {
|
||||
final int n = v.narg();
|
||||
switch (n) {
|
||||
case 0: return null;
|
||||
case 1: return toJava(v.arg1());
|
||||
default:
|
||||
Object[] o = new Object[n];
|
||||
for (int i=0; i<n; ++i)
|
||||
o[i] = toJava(v.arg(i+1));
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
static private Object eval(LuaFunction f, Globals g) throws ScriptException {
|
||||
try {
|
||||
f = f.getClass().newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new ScriptException(e);
|
||||
}
|
||||
f.initupvalue1(g);
|
||||
return toJava(f.invoke(LuaValue.NONE));
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue