Reformatted

This commit is contained in:
Finn
2026-01-16 21:53:46 +01:00
parent 2a657f3a83
commit 1e95252f94
18 changed files with 155 additions and 151 deletions

View File

@@ -11,7 +11,8 @@ import java.util.Map;
*/
public final class JavaToLua {
private JavaToLua() { }
private JavaToLua() {
}
public static LuaValue coerce(Object v) {
if (v == null) return LuaValue.NIL;

View File

@@ -1,11 +1,6 @@
package org.openautonomousconnection.luascript.events;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.*;
import org.openautonomousconnection.luascript.security.LuaExecutionPolicy;
import org.openautonomousconnection.luascript.security.LuaSecurityManager;
@@ -29,6 +24,10 @@ public final class LuaEventDispatcher {
this.policy = Objects.requireNonNull(policy, "policy");
}
private static String key(String elementId, String event) {
return elementId + "\n" + event;
}
public void bind(String elementId, String eventName, String handlerPath) {
Objects.requireNonNull(elementId, "elementId");
Objects.requireNonNull(eventName, "eventName");
@@ -93,8 +92,4 @@ public final class LuaEventDispatcher {
t.set("data", d);
return t;
}
private static String key(String elementId, String event) {
return elementId + "\n" + event;
}
}

View File

@@ -7,27 +7,11 @@ import java.util.Objects;
/**
* Event passed from host into Lua.
*/
public final class UiEvent {
private final String targetId;
private final String type;
private final Map<String, Object> data;
public record UiEvent(String targetId, String type, Map<String, Object> data) {
public UiEvent(String targetId, String type, Map<String, Object> data) {
this.targetId = Objects.requireNonNull(targetId, "targetId");
this.type = Objects.requireNonNull(type, "type");
this.data = (data == null) ? Collections.emptyMap() : Collections.unmodifiableMap(data);
}
public String targetId() {
return targetId;
}
public String type() {
return type;
}
public Map<String, Object> data() {
return data;
}
}

View File

@@ -7,7 +7,8 @@ import java.util.Locale;
*/
public final class UiEventRegistry {
private UiEventRegistry() { }
private UiEventRegistry() {
}
public static String normalize(String eventName) {
if (eventName == null) throw new IllegalArgumentException("eventName is null");

View File

@@ -4,18 +4,28 @@ package org.openautonomousconnection.luascript.hosts;
* Host capability for console logging.
*/
public interface ConsoleHost {
/** @param message message */
/**
* @param message message
*/
void info(String message);
/** @param message message */
/**
* @param message message
*/
void log(String message);
/** @param message message */
/**
* @param message message
*/
void warn(String message);
/** @param message message */
/**
* @param message message
*/
void error(String message);
/** @param message message */
/**
* @param message message
*/
void exception(String message);
}

View File

@@ -24,6 +24,13 @@ public final class HostServices {
this.resources = b.resources;
}
/**
* @return builder
*/
public static Builder builder() {
return new Builder();
}
/**
* @return optional DomHost capability
*/
@@ -45,21 +52,20 @@ public final class HostServices {
return Optional.ofNullable(resources);
}
/** @return optional console host */
/**
* @return optional console host
*/
public Optional<ConsoleHost> console() {
return Optional.ofNullable(console);
}
/** @return optional ui host */
/**
* @return optional ui host
*/
public Optional<UiHost> ui() {
return Optional.ofNullable(ui);
}
/** @return builder */
public static Builder builder() {
return new Builder();
}
/**
* Builder for HostServices.
*/

View File

@@ -5,10 +5,10 @@ import org.openautonomousconnection.luascript.events.LuaEventDispatcher;
import org.openautonomousconnection.luascript.hosts.HostServices;
import org.openautonomousconnection.luascript.security.LuaExecutionPolicy;
import org.openautonomousconnection.luascript.security.LuaSecurityManager;
import org.openautonomousconnection.luascript.tables.console.ConsoleTable;
import org.openautonomousconnection.luascript.tables.DomTable;
import org.openautonomousconnection.luascript.tables.EventsTable;
import org.openautonomousconnection.luascript.tables.UiTable;
import org.openautonomousconnection.luascript.tables.console.ConsoleTable;
import java.util.Objects;

View File

@@ -17,7 +17,8 @@ import java.util.Objects;
*/
public final class LuaScriptBootstrap {
private LuaScriptBootstrap() { }
private LuaScriptBootstrap() {
}
public static void bootstrap(Globals globals, HostServices services, LuaEventDispatcher dispatcher) {
Objects.requireNonNull(globals, "globals");

View File

@@ -11,7 +11,8 @@ import java.util.Objects;
*/
public final class LuaScriptExecutor {
private LuaScriptExecutor() { }
private LuaScriptExecutor() {
}
public static void execute(Globals globals, String source, String chunkName) {
Objects.requireNonNull(globals, "globals");

View File

@@ -28,39 +28,6 @@ public final class LuaSecurityManager implements AutoCloseable {
});
}
/**
* Executes a Lua function guarded by the provided policy.
*
* @param globals globals/environment
* @param function function to execute
* @param args arguments
* @param policy execution policy
* @return results (Lua varargs)
*/
public Varargs callGuarded(Globals globals, LuaFunction function, Varargs args, LuaExecutionPolicy policy) {
Objects.requireNonNull(globals, "globals");
Objects.requireNonNull(function, "function");
Objects.requireNonNull(args, "args");
Objects.requireNonNull(policy, "policy");
Future<Varargs> f = executor.submit(() -> callWithHook(globals, function, args, policy));
try {
return f.get(policy.timeout().toMillis(), TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
f.cancel(true);
throw new LuaError("Lua execution timed out after " + policy.timeout().toMillis() + "ms");
} catch (ExecutionException e) {
Throwable c = e.getCause();
if (c instanceof LuaError le) throw le;
if (c instanceof RuntimeException re) throw re;
throw new RuntimeException(c);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted while waiting for Lua execution", e);
}
}
private static Varargs callWithHook(Globals globals, LuaFunction function, Varargs args, LuaExecutionPolicy policy) {
final LuaValue sethook = resolveAndHideDebugSetHook(globals);
@@ -136,6 +103,39 @@ public final class LuaSecurityManager implements AutoCloseable {
return sethook;
}
/**
* Executes a Lua function guarded by the provided policy.
*
* @param globals globals/environment
* @param function function to execute
* @param args arguments
* @param policy execution policy
* @return results (Lua varargs)
*/
public Varargs callGuarded(Globals globals, LuaFunction function, Varargs args, LuaExecutionPolicy policy) {
Objects.requireNonNull(globals, "globals");
Objects.requireNonNull(function, "function");
Objects.requireNonNull(args, "args");
Objects.requireNonNull(policy, "policy");
Future<Varargs> f = executor.submit(() -> callWithHook(globals, function, args, policy));
try {
return f.get(policy.timeout().toMillis(), TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
f.cancel(true);
throw new LuaError("Lua execution timed out after " + policy.timeout().toMillis() + "ms");
} catch (ExecutionException e) {
Throwable c = e.getCause();
if (c instanceof LuaError le) throw le;
if (c instanceof RuntimeException re) throw re;
throw new RuntimeException(c);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted while waiting for Lua execution", e);
}
}
@Override
public void close() {
executor.shutdownNow();

View File

@@ -2,10 +2,13 @@ package org.openautonomousconnection.luascript.tables;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.*;
import org.openautonomousconnection.luascript.utils.ScriptTable;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.ThreeArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
import org.openautonomousconnection.luascript.hosts.DomHost;
import org.openautonomousconnection.luascript.hosts.HostServices;
import org.openautonomousconnection.luascript.utils.ScriptTable;
import java.util.List;
import java.util.Map;
@@ -21,6 +24,17 @@ public final class DomTable extends ScriptTable {
super("dom");
}
private static LuaValue toLuaArray(List<String> values) {
LuaTable t = new LuaTable();
if (values == null || values.isEmpty()) return t;
int i = 1;
for (String v : values) {
t.set(i++, v == null ? LuaValue.NIL : LuaValue.valueOf(v));
}
return t;
}
@Override
protected void define(HostServices services) {
DomHost dom = services.dom().orElseThrow(() -> new IllegalStateException("DomHost not provided"));
@@ -165,15 +179,4 @@ public final class DomTable extends ScriptTable {
}
});
}
private static LuaValue toLuaArray(List<String> values) {
LuaTable t = new LuaTable();
if (values == null || values.isEmpty()) return t;
int i = 1;
for (String v : values) {
t.set(i++, v == null ? LuaValue.NIL : LuaValue.valueOf(v));
}
return t;
}
}

View File

@@ -3,11 +3,11 @@ package org.openautonomousconnection.luascript.tables;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.openautonomousconnection.luascript.utils.ScriptTable;
import org.openautonomousconnection.luascript.events.LuaEventDispatcher;
import org.openautonomousconnection.luascript.events.UiEventRegistry;
import org.openautonomousconnection.luascript.hosts.EventHost;
import org.openautonomousconnection.luascript.hosts.HostServices;
import org.openautonomousconnection.luascript.utils.ScriptTable;
/**
* events namespace for manual binding/unbinding.

View File

@@ -3,9 +3,9 @@ package org.openautonomousconnection.luascript.tables;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.openautonomousconnection.luascript.utils.ScriptTable;
import org.openautonomousconnection.luascript.hosts.HostServices;
import org.openautonomousconnection.luascript.hosts.UiHost;
import org.openautonomousconnection.luascript.utils.ScriptTable;
/**
* ui namespace for common UI operations.
@@ -55,7 +55,8 @@ public final class UiTable extends ScriptTable {
});
table().set("getText", new OneArgFunction() {
@Override public LuaValue call(LuaValue id) {
@Override
public LuaValue call(LuaValue id) {
String v = ui.getText(id.checkjstring());
return v == null ? LuaValue.NIL : LuaValue.valueOf(v);
}

View File

@@ -2,8 +2,8 @@ package org.openautonomousconnection.luascript.tables.console;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.openautonomousconnection.luascript.utils.ScriptTable;
import org.openautonomousconnection.luascript.hosts.HostServices;
import org.openautonomousconnection.luascript.utils.ScriptTable;
public class ConsoleLogTable extends ScriptTable {
/**

View File

@@ -22,48 +22,7 @@ import java.util.function.Consumer;
*/
public final class LuaGlobalsFactory {
private LuaGlobalsFactory() { }
/**
* Configuration options for creating a {@link Globals} instance.
*/
public static final class Options {
private boolean enableDebug;
private boolean sandbox;
private Consumer<Globals> hostApiConfigurer;
/**
* Enables or disables Lua debug library exposure.
*
* @param enableDebug true to enable debug lib, false otherwise
* @return this options instance
*/
public Options enableDebug(boolean enableDebug) {
this.enableDebug = enableDebug;
return this;
}
/**
* Enables or disables sandbox hardening (disables os/io/debug/luajava/package/require/loadfile/dofile).
*
* @param sandbox true to harden, false otherwise
* @return this options instance
*/
public Options sandbox(boolean sandbox) {
this.sandbox = sandbox;
return this;
}
/**
* Adds a hook to register host APIs (e.g. {@code host.ui.alert}).
*
* @param hostApiConfigurer configurer callback
* @return this options instance
*/
public Options hostApiConfigurer(Consumer<Globals> hostApiConfigurer) {
this.hostApiConfigurer = hostApiConfigurer;
return this;
}
private LuaGlobalsFactory() {
}
/**
@@ -134,4 +93,46 @@ public final class LuaGlobalsFactory {
g.set("host", host);
return host;
}
/**
* Configuration options for creating a {@link Globals} instance.
*/
public static final class Options {
private boolean enableDebug;
private boolean sandbox;
private Consumer<Globals> hostApiConfigurer;
/**
* Enables or disables Lua debug library exposure.
*
* @param enableDebug true to enable debug lib, false otherwise
* @return this options instance
*/
public Options enableDebug(boolean enableDebug) {
this.enableDebug = enableDebug;
return this;
}
/**
* Enables or disables sandbox hardening (disables os/io/debug/luajava/package/require/loadfile/dofile).
*
* @param sandbox true to harden, false otherwise
* @return this options instance
*/
public Options sandbox(boolean sandbox) {
this.sandbox = sandbox;
return this;
}
/**
* Adds a hook to register host APIs (e.g. {@code host.ui.alert}).
*
* @param hostApiConfigurer configurer callback
* @return this options instance
*/
public Options hostApiConfigurer(Consumer<Globals> hostApiConfigurer) {
this.hostApiConfigurer = hostApiConfigurer;
return this;
}
}
}