🏃 KitsuneScriptRunner
Klasa pomocnicza do uruchamiania skryptów z parametrami i dwukierunkową komunikacją.
Podstawowe użycie
import rip.nerd.kitsunescript.api.KitsuneScriptRunner
import rip.nerd.kitsunescript.runtime.HostFunction
import rip.nerd.kitsunescript.runtime.Value
val runner = KitsuneScriptRunner.createInstance("myScript")
runner.register("log", HostFunction { args, _ ->
println(args.joinToString(" ") { it.asString() })
Value.Null
})
runner.params = listOf("Alice", 25)
runner.onSend { value ->
println("Otrzymano: ${value.asString()}")
}
val result = runner.execute("""
log("Witaj " + global.params[0]);
global.send("Hello " + global.params[0]);
"done";
""")
println(result.value)
println(result.sendResults)
runner.dispose()
Host Functions - register()
Metoda register(name, fn) pozwala zarejestrować dowolną funkcję Kotlina, którą skrypt może wywoływać. Funkcja log() nie jest częścią stdlib - musisz ją zarejestrować samodzielnie.
runner.register("log", HostFunction { args, _ ->
println(args.joinToString(" ") { it.asString() })
Value.Null
})
runner.register("log", HostFunction { args, _ ->
val msg = args.joinToString(" ") { it.asString() }
runOnUiThread { textView.append(msg + "\n") }
Value.Null
})
runner.register("showToast", HostFunction { args, _ ->
val msg = args.firstOrNull()?.asString() ?: ""
runOnUiThread { Toast.makeText(context, msg, Toast.LENGTH_SHORT).show() }
Value.Null
})
runner.register("getDeviceName", HostFunction { _, _ ->
Value.Str(Build.MODEL)
})
💡 Uwaga
Zarejestrowane funkcje są dostępne w każdym wywołaniu execute(). Rejestracja jest zachowywana na instancji runnera, więc nie trzeba rejestrować ponownie po każdym uruchomieniu.
Dostępne w skrypcie
| Element | Opis |
global.params | Lista parametrów z Kotlina |
global.send(value) | Wyślij wartość do hosta |
global.instanceId | ID instancji |
emit(event, ...args) | Wyślij event do hosta |
on(event) { handler } | Nasłuchuj na eventy |
event.args | W handlerze on() - argumenty z emitToScript() |
event.name | W handlerze on() - nazwa eventu |
Eventy
runner.onScriptEvent("dataReady") { args ->
println("Dane: ${args.firstOrNull()}")
}
runner.emitToScript("refresh")
runner.emitToScript("update", 123, "newValue")
emit("dataReady", {status: "ok", data: [1,2,3]});
on("update") {
let id = event.args[0];
let value = event.args[1];
log("Update: " + id + " = " + value);
}
Result
| Pole | Typ | Opis |
value | Value | Zwrócona wartość |
sendResults | List<Value> | Wszystkie global.send() |
success | Boolean | Czy bez błędów? |
error | String? | Komunikat błędu |
SourceLoader - Import modułów
Aby używać import w skryptach, musisz skonfigurować SourceLoader który określa skąd ładować zewnętrzne pliki.
val runner = KitsuneScriptRunner.createInstance("myScript")
.withSourceLoader { path ->
context.assets.open("scripts/$path").bufferedReader().readText()
}
runner.execute("""
import "utils.ks" in utils;
import "math-helpers.ks" in math;
let result = utils.calculate(10, 20);
math.format(result);
""")
SourceLoader z plików
import java.io.File
val scriptsDir = File("/path/to/scripts")
val runner = KitsuneScriptRunner.createInstance("fileRunner")
.withSourceLoader { path ->
File(scriptsDir, path).readText()
}
SourceLoader z zasobów raw
val runner = KitsuneScriptRunner.createInstance("resourceRunner")
.withSourceLoader { path ->
val resName = path.replace(".ks", "").replace("/", "_")
val resId = context.resources.getIdentifier(resName, "raw", context.packageName)
context.resources.openRawResource(resId).bufferedReader().readText()
}
Właściwości instancji
| Właściwość | Typ | Opis |
params | List<Any?> | Parametry wejściowe dla skryptu |
maxSteps | Int | Max kroków wykonania (domyślnie 200,000) |
loadAllModules | Boolean | Ładować wszystkie moduły stdlib (domyślnie false) |
sourceLoader | SourceLoader? | Loader dla importowanych modułów |
Global variables w importowanych modułach
Gdy używasz KitsuneScriptRunner, obiekt global jest automatycznie dostępny w importowanych modułach. Zarejestrowane host functions (np. log) też są dostępne:
export fn greet() {
let name = global.params[0] ?? "World";
log("Hello from module, " + name);
return "Hello " + name;
}
import "helper.ks" in helper;
let greeting = helper.greet();
log("Result: " + greeting);
⚠️ Uwaga
global.send() jest definiowane w wrapper script głównego skryptu i nie jest dostępne w importowanych modułach. Używaj emit() zamiast tego, lub przekaż global.send jako argument.
Metody instancji
| Metoda | Opis |
register(name, fn) | Zarejestruj własną host function |
execute(script) | Uruchom skrypt synchronicznie |
executeSuspend(script) | Uruchom asynchronicznie (suspend) |
executeFile(path) | Załaduj i uruchom skrypt z pliku |
executeFileSuspend(path) | Załaduj i uruchom z pliku (suspend) |
withSourceLoader(loader) | Ustaw SourceLoader (fluent API) |
onSend(callback) | Callback dla global.send() |
onScriptEvent(event, handler) | Handler dla emit() ze skryptu |
removeScriptEventHandlers(event) | Usuń handlery dla eventu |
emitToScript(event, args) | Wyślij event do skryptu |
getSendResults() | Pobierz wszystkie wyniki send() |
dispose() | Zwolnij zasoby i usuń instancję |