mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-06-13 13:47:47 +02:00
feat(scripting): config interface
- change onLaunched to onDispose - refactor JSModule extras
This commit is contained in:
@ -14,6 +14,8 @@ import coil.ImageLoader
|
||||
import coil.decode.VideoFrameDecoder
|
||||
import coil.disk.DiskCache
|
||||
import coil.memory.MemoryCache
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import me.rhunk.snapenhance.bridge.BridgeService
|
||||
@ -81,6 +83,8 @@ class RemoteSideContext(
|
||||
.components { add(VideoFrameDecoder.Factory()) }.build()
|
||||
}
|
||||
|
||||
val gson: Gson by lazy { GsonBuilder().setPrettyPrinting().create() }
|
||||
|
||||
fun reload() {
|
||||
log.verbose("Loading RemoteSideContext")
|
||||
runCatching {
|
||||
|
@ -6,18 +6,20 @@ import me.rhunk.snapenhance.RemoteSideContext
|
||||
import me.rhunk.snapenhance.bridge.scripting.IPCListener
|
||||
import me.rhunk.snapenhance.bridge.scripting.IScripting
|
||||
import me.rhunk.snapenhance.common.scripting.ScriptRuntime
|
||||
import me.rhunk.snapenhance.common.scripting.impl.ConfigInterface
|
||||
import me.rhunk.snapenhance.common.scripting.impl.ConfigTransactionType
|
||||
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
|
||||
import me.rhunk.snapenhance.scripting.impl.IPCListeners
|
||||
import me.rhunk.snapenhance.scripting.impl.RemoteManagerIPC
|
||||
import me.rhunk.snapenhance.scripting.impl.ui.InterfaceBuilder
|
||||
import me.rhunk.snapenhance.scripting.impl.RemoteScriptConfig
|
||||
import me.rhunk.snapenhance.scripting.impl.ui.InterfaceManager
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
||||
class RemoteScriptManager(
|
||||
private val context: RemoteSideContext,
|
||||
val context: RemoteSideContext,
|
||||
) : IScripting.Stub() {
|
||||
val runtime = ScriptRuntime(context.androidContext, context.log)
|
||||
private val userInterfaces = mutableMapOf<String, MutableMap<String, InterfaceBuilder>>()
|
||||
|
||||
private val cachedModuleInfo = mutableMapOf<String, ModuleInfo>()
|
||||
private val ipcListeners = IPCListeners()
|
||||
@ -40,19 +42,15 @@ class RemoteScriptManager(
|
||||
|
||||
fun init() {
|
||||
runtime.buildModuleObject = { module ->
|
||||
putConst("ipc", this, RemoteManagerIPC(module.moduleInfo, context.log, ipcListeners))
|
||||
putConst("im", this, InterfaceManager(module.moduleInfo, context.log) { name, interfaceBuilder ->
|
||||
userInterfaces.getOrPut(module.moduleInfo.name) {
|
||||
mutableMapOf()
|
||||
}[name] = interfaceBuilder
|
||||
})
|
||||
module.extras["ipc"] = RemoteManagerIPC(module.moduleInfo, context.log, ipcListeners)
|
||||
module.extras["im"] = InterfaceManager(module.moduleInfo, context.log)
|
||||
module.extras["config"] = RemoteScriptConfig(this@RemoteScriptManager, module.moduleInfo, context.log).also {
|
||||
it.load()
|
||||
}
|
||||
}
|
||||
|
||||
sync()
|
||||
enabledScripts.forEach { name ->
|
||||
if (getModuleDataFolder(name) == null) {
|
||||
context.log.warn("Module data folder not found for $name")
|
||||
}
|
||||
loadScript(name)
|
||||
}
|
||||
}
|
||||
@ -62,19 +60,17 @@ class RemoteScriptManager(
|
||||
runtime.load(name, content)
|
||||
}
|
||||
|
||||
fun getScriptInterface(scriptName: String, interfaceName: String)
|
||||
= userInterfaces[scriptName]?.get(interfaceName)
|
||||
|
||||
|
||||
private fun <R> getScriptInputStream(name: String, callback: (InputStream?) -> R): R {
|
||||
val file = getScriptsFolder()?.findFile(name) ?: return callback(null)
|
||||
return context.androidContext.contentResolver.openInputStream(file.uri)?.use(callback) ?: callback(null)
|
||||
}
|
||||
|
||||
private fun getModuleDataFolder(moduleFileName: String): DocumentFile? {
|
||||
val folderName = moduleFileName.substringBeforeLast(".js")
|
||||
val folder = getScriptsFolder() ?: return null
|
||||
return folder.findFile(folderName) ?: folder.createDirectory(folderName)
|
||||
fun getModuleDataFolder(moduleFileName: String): File {
|
||||
return context.androidContext.filesDir.resolve("modules").resolve(moduleFileName).also {
|
||||
if (!it.exists()) {
|
||||
it.mkdirs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getScriptsFolder() = runCatching {
|
||||
@ -114,4 +110,35 @@ class RemoteScriptManager(
|
||||
context.log.error("Failed to send message for $eventName", it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun configTransaction(
|
||||
module: String?,
|
||||
action: String,
|
||||
key: String?,
|
||||
value: String?,
|
||||
save: Boolean
|
||||
): String? {
|
||||
val scriptConfig = runtime.getModuleByName(module ?: return null)?.extras?.get("config") as? ConfigInterface ?: return null.also {
|
||||
context.log.warn("Failed to get config interface for $module")
|
||||
}
|
||||
val transactionType = ConfigTransactionType.fromKey(action)
|
||||
|
||||
return runCatching {
|
||||
scriptConfig.run {
|
||||
if (transactionType == ConfigTransactionType.GET) {
|
||||
return get(key ?: return@runCatching null, value)
|
||||
}
|
||||
when (transactionType) {
|
||||
ConfigTransactionType.SET -> set(key ?: return@runCatching null, value, save)
|
||||
ConfigTransactionType.SAVE -> save()
|
||||
ConfigTransactionType.LOAD -> load()
|
||||
ConfigTransactionType.DELETE -> delete()
|
||||
else -> {}
|
||||
}
|
||||
null
|
||||
}
|
||||
}.onFailure {
|
||||
context.log.error("Failed to perform config transaction", it)
|
||||
}.getOrDefault("")
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@ package me.rhunk.snapenhance.scripting.impl
|
||||
import android.os.DeadObjectException
|
||||
import me.rhunk.snapenhance.bridge.scripting.IPCListener
|
||||
import me.rhunk.snapenhance.common.logger.AbstractLogger
|
||||
import me.rhunk.snapenhance.common.scripting.IPCInterface
|
||||
import me.rhunk.snapenhance.common.scripting.Listener
|
||||
import me.rhunk.snapenhance.common.scripting.impl.IPCInterface
|
||||
import me.rhunk.snapenhance.common.scripting.impl.Listener
|
||||
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
|
@ -0,0 +1,57 @@
|
||||
package me.rhunk.snapenhance.scripting.impl
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import me.rhunk.snapenhance.common.logger.AbstractLogger
|
||||
import me.rhunk.snapenhance.common.scripting.impl.ConfigInterface
|
||||
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
|
||||
import me.rhunk.snapenhance.scripting.RemoteScriptManager
|
||||
import java.io.File
|
||||
|
||||
class RemoteScriptConfig(
|
||||
private val remoteScriptManager: RemoteScriptManager,
|
||||
moduleInfo: ModuleInfo,
|
||||
private val logger: AbstractLogger,
|
||||
) : ConfigInterface() {
|
||||
private val configFile = File(remoteScriptManager.getModuleDataFolder(moduleInfo.name), "config.json")
|
||||
private var config = JsonObject()
|
||||
|
||||
override fun get(key: String, defaultValue: Any?): String? {
|
||||
return config[key]?.asString ?: defaultValue?.toString()
|
||||
}
|
||||
|
||||
override fun set(key: String, value: Any?, save: Boolean) {
|
||||
when (value) {
|
||||
is Int -> config.addProperty(key, value)
|
||||
is Double -> config.addProperty(key, value)
|
||||
is Boolean -> config.addProperty(key, value)
|
||||
is Long -> config.addProperty(key, value)
|
||||
is Float -> config.addProperty(key, value)
|
||||
is Byte -> config.addProperty(key, value)
|
||||
is Short -> config.addProperty(key, value)
|
||||
else -> config.addProperty(key, value?.toString())
|
||||
}
|
||||
|
||||
if (save) save()
|
||||
}
|
||||
|
||||
override fun save() {
|
||||
configFile.writeText(config.toString())
|
||||
}
|
||||
|
||||
override fun load() {
|
||||
runCatching {
|
||||
if (!configFile.exists()) {
|
||||
save()
|
||||
return@runCatching
|
||||
}
|
||||
config = remoteScriptManager.context.gson.fromJson(configFile.readText(), JsonObject::class.java)
|
||||
}.onFailure {
|
||||
logger.error("Failed to load config file", it)
|
||||
save()
|
||||
}
|
||||
}
|
||||
|
||||
override fun delete() {
|
||||
configFile.delete()
|
||||
}
|
||||
}
|
@ -12,15 +12,15 @@ import org.mozilla.javascript.annotations.JSFunction
|
||||
|
||||
class InterfaceBuilder {
|
||||
val nodes = mutableListOf<Node>()
|
||||
var onLaunchedCallback: (() -> Unit)? = null
|
||||
var onDisposeCallback: (() -> Unit)? = null
|
||||
|
||||
|
||||
private fun createNode(type: NodeType, block: Node.() -> Unit): Node {
|
||||
return Node(type).apply(block).also { nodes.add(it) }
|
||||
}
|
||||
|
||||
fun onLaunched(block: () -> Unit) {
|
||||
onLaunchedCallback = block
|
||||
fun onDispose(block: () -> Unit) {
|
||||
onDisposeCallback = block
|
||||
}
|
||||
|
||||
fun row(block: (InterfaceBuilder) -> Unit) = RowColumnNode(NodeType.ROW).apply {
|
||||
@ -66,14 +66,25 @@ class InterfaceBuilder {
|
||||
|
||||
class InterfaceManager(
|
||||
private val moduleInfo: ModuleInfo,
|
||||
private val logger: AbstractLogger,
|
||||
private val registerInterface: (String, InterfaceBuilder) -> Unit,
|
||||
private val logger: AbstractLogger
|
||||
) {
|
||||
@JSFunction
|
||||
fun create(name: String, callback: Function) {
|
||||
logger.info("Creating interface $name for ${moduleInfo.name}")
|
||||
private val interfaces = mutableMapOf<String, () -> InterfaceBuilder?>()
|
||||
|
||||
fun buildInterface(name: String): InterfaceBuilder? {
|
||||
return interfaces[name]?.invoke()
|
||||
}
|
||||
|
||||
@JSFunction fun create(name: String, callback: Function) {
|
||||
interfaces[name] = {
|
||||
val interfaceBuilder = InterfaceBuilder()
|
||||
runCatching {
|
||||
Context.enter()
|
||||
callback.call(Context.getCurrentContext(), callback, callback, arrayOf(interfaceBuilder))
|
||||
registerInterface(name, interfaceBuilder)
|
||||
Context.exit()
|
||||
interfaceBuilder
|
||||
}.onFailure {
|
||||
logger.error("Failed to create interface $name for ${moduleInfo.name}", it)
|
||||
}.getOrNull()
|
||||
}
|
||||
}
|
||||
}
|
@ -147,8 +147,14 @@ fun ScriptInterface(interfaceBuilder: InterfaceBuilder) {
|
||||
DrawNode(node)
|
||||
}
|
||||
|
||||
LaunchedEffect(interfaceBuilder) {
|
||||
interfaceBuilder.onLaunchedCallback?.invoke()
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
runCatching {
|
||||
interfaceBuilder.onDisposeCallback?.invoke()
|
||||
}.onFailure {
|
||||
AbstractLogger.directError("Error running onDisposed callback", it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import androidx.compose.ui.unit.sp
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
|
||||
import me.rhunk.snapenhance.scripting.impl.ui.InterfaceManager
|
||||
import me.rhunk.snapenhance.ui.manager.Section
|
||||
import me.rhunk.snapenhance.ui.util.pullrefresh.PullRefreshIndicator
|
||||
import me.rhunk.snapenhance.ui.util.pullrefresh.pullRefresh
|
||||
@ -88,7 +89,8 @@ class ScriptsSection : Section() {
|
||||
@Composable
|
||||
fun ScriptSettings(script: ModuleInfo) {
|
||||
val settingsInterface = remember {
|
||||
context.scriptManager.getScriptInterface(script.name, "settings")
|
||||
val module = context.scriptManager.runtime.getModuleByName(script.name) ?: return@remember null
|
||||
(module.extras["im"] as? InterfaceManager)?.buildInterface("settings")
|
||||
} ?: run {
|
||||
Text(
|
||||
text = "This module does not have any settings",
|
||||
@ -101,7 +103,6 @@ class ScriptsSection : Section() {
|
||||
ScriptInterface(interfaceBuilder = settingsInterface)
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
var scriptModules by remember {
|
||||
|
@ -10,4 +10,6 @@ interface IScripting {
|
||||
void registerIPCListener(String channel, String eventName, IPCListener listener);
|
||||
|
||||
void sendIPCMessage(String channel, String eventName, in String[] args);
|
||||
|
||||
@nullable String configTransaction(String module, String action, @nullable String key, @nullable String value, boolean save);
|
||||
}
|
@ -18,6 +18,7 @@ class JSModule(
|
||||
val moduleInfo: ModuleInfo,
|
||||
val content: String,
|
||||
) {
|
||||
val extras = mutableMapOf<String, Any>()
|
||||
private lateinit var moduleObject: ScriptableObject
|
||||
|
||||
fun load(block: ScriptableObject.() -> Unit) {
|
||||
@ -115,8 +116,10 @@ class JSModule(
|
||||
Undefined.instance
|
||||
}
|
||||
}
|
||||
|
||||
block(moduleObject)
|
||||
extras.forEach { (key, value) ->
|
||||
moduleObject.putConst(key, moduleObject, value)
|
||||
}
|
||||
evaluateString(moduleObject, content, moduleInfo.name, 1, null)
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,10 @@ open class ScriptRuntime(
|
||||
}
|
||||
}
|
||||
|
||||
fun getModuleByName(name: String): JSModule? {
|
||||
return modules.values.find { it.moduleInfo.name == name }
|
||||
}
|
||||
|
||||
private fun readModuleInfo(reader: BufferedReader): ModuleInfo {
|
||||
val header = reader.readLine()
|
||||
if (!header.startsWith("// ==SE_module==")) {
|
||||
|
@ -0,0 +1,74 @@
|
||||
package me.rhunk.snapenhance.common.scripting.impl
|
||||
|
||||
import org.mozilla.javascript.annotations.JSFunction
|
||||
|
||||
|
||||
enum class ConfigTransactionType(
|
||||
val key: String
|
||||
) {
|
||||
GET("get"),
|
||||
SET("set"),
|
||||
SAVE("save"),
|
||||
LOAD("load"),
|
||||
DELETE("delete");
|
||||
|
||||
companion object {
|
||||
fun fromKey(key: String) = entries.find { it.key == key }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class ConfigInterface {
|
||||
@JSFunction fun get(key: String): String? = get(key, null)
|
||||
@JSFunction abstract fun get(key: String, defaultValue: Any?): String?
|
||||
|
||||
@JSFunction fun getInteger(key: String): Int? = getInteger(key, null)
|
||||
@JSFunction fun getInteger(key: String, defaultValue: Int?): Int? = get(key, defaultValue.toString())?.toIntOrNull() ?: defaultValue
|
||||
|
||||
@JSFunction fun getDouble(key: String): Double? = getDouble(key, null)
|
||||
@JSFunction fun getDouble(key: String, defaultValue: Double?): Double? = get(key, defaultValue.toString())?.toDoubleOrNull() ?: defaultValue
|
||||
|
||||
@JSFunction fun getBoolean(key: String): Boolean? = getBoolean(key, null)
|
||||
@JSFunction fun getBoolean(key: String, defaultValue: Boolean?): Boolean? = get(key, defaultValue.toString())?.toBoolean() ?: defaultValue
|
||||
|
||||
@JSFunction fun getLong(key: String): Long? = getLong(key, null)
|
||||
@JSFunction fun getLong(key: String, defaultValue: Long?): Long? = get(key, defaultValue.toString())?.toLongOrNull() ?: defaultValue
|
||||
|
||||
@JSFunction fun getFloat(key: String): Float? = getFloat(key, null)
|
||||
@JSFunction fun getFloat(key: String, defaultValue: Float?): Float? = get(key, defaultValue.toString())?.toFloatOrNull() ?: defaultValue
|
||||
|
||||
@JSFunction fun getByte(key: String): Byte? = getByte(key, null)
|
||||
@JSFunction fun getByte(key: String, defaultValue: Byte?): Byte? = get(key, defaultValue.toString())?.toByteOrNull() ?: defaultValue
|
||||
|
||||
@JSFunction fun getShort(key: String): Short? = getShort(key, null)
|
||||
@JSFunction fun getShort(key: String, defaultValue: Short?): Short? = get(key, defaultValue.toString())?.toShortOrNull() ?: defaultValue
|
||||
|
||||
|
||||
@JSFunction fun set(key: String, value: Any?) = set(key, value, false)
|
||||
@JSFunction abstract fun set(key: String, value: Any?, save: Boolean)
|
||||
|
||||
@JSFunction fun setInteger(key: String, value: Int?) = setInteger(key, value, false)
|
||||
@JSFunction fun setInteger(key: String, value: Int?, save: Boolean) = set(key, value, save)
|
||||
|
||||
@JSFunction fun setDouble(key: String, value: Double?) = setDouble(key, value, false)
|
||||
@JSFunction fun setDouble(key: String, value: Double?, save: Boolean) = set(key, value, save)
|
||||
|
||||
@JSFunction fun setBoolean(key: String, value: Boolean?) = setBoolean(key, value, false)
|
||||
@JSFunction fun setBoolean(key: String, value: Boolean?, save: Boolean) = set(key, value, save)
|
||||
|
||||
@JSFunction fun setLong(key: String, value: Long?) = setLong(key, value, false)
|
||||
@JSFunction fun setLong(key: String, value: Long?, save: Boolean) = set(key, value, save)
|
||||
|
||||
@JSFunction fun setFloat(key: String, value: Float?) = setFloat(key, value, false)
|
||||
@JSFunction fun setFloat(key: String, value: Float?, save: Boolean) = set(key, value, save)
|
||||
|
||||
@JSFunction fun setByte(key: String, value: Byte?) = setByte(key, value, false)
|
||||
@JSFunction fun setByte(key: String, value: Byte?, save: Boolean) = set(key, value, save)
|
||||
|
||||
@JSFunction fun setShort(key: String, value: Short?) = setShort(key, value, false)
|
||||
@JSFunction fun setShort(key: String, value: Short?, save: Boolean) = set(key, value, save)
|
||||
|
||||
@JSFunction abstract fun save()
|
||||
@JSFunction abstract fun load()
|
||||
@JSFunction abstract fun delete()
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package me.rhunk.snapenhance.common.scripting
|
||||
package me.rhunk.snapenhance.common.scripting.impl
|
||||
|
||||
typealias Listener = (Array<out String?>) -> Unit
|
||||
|
@ -1,12 +1,11 @@
|
||||
package me.rhunk.snapenhance.core.scripting
|
||||
|
||||
import android.content.Context
|
||||
import me.rhunk.snapenhance.bridge.scripting.IPCListener
|
||||
import me.rhunk.snapenhance.bridge.scripting.IScripting
|
||||
import me.rhunk.snapenhance.common.logger.AbstractLogger
|
||||
import me.rhunk.snapenhance.common.scripting.IPCInterface
|
||||
import me.rhunk.snapenhance.common.scripting.Listener
|
||||
import me.rhunk.snapenhance.common.scripting.ScriptRuntime
|
||||
import me.rhunk.snapenhance.core.scripting.impl.CoreIPC
|
||||
import me.rhunk.snapenhance.core.scripting.impl.CoreScriptConfig
|
||||
import me.rhunk.snapenhance.core.scripting.impl.ScriptHooker
|
||||
|
||||
class CoreScriptRuntime(
|
||||
@ -18,34 +17,14 @@ class CoreScriptRuntime(
|
||||
fun connect(scriptingInterface: IScripting) {
|
||||
scriptingInterface.apply {
|
||||
buildModuleObject = { module ->
|
||||
putConst("ipc", this, object: IPCInterface() {
|
||||
override fun onBroadcast(channel: String, eventName: String, listener: Listener) {
|
||||
registerIPCListener(channel, eventName, object: IPCListener.Stub() {
|
||||
override fun onMessage(args: Array<out String?>) {
|
||||
listener(args)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun on(eventName: String, listener: Listener) {
|
||||
onBroadcast(module.moduleInfo.name, eventName, listener)
|
||||
}
|
||||
|
||||
override fun emit(eventName: String, vararg args: String?) {
|
||||
broadcast(module.moduleInfo.name, eventName, *args)
|
||||
}
|
||||
|
||||
override fun broadcast(channel: String, eventName: String, vararg args: String?) {
|
||||
sendIPCMessage(channel, eventName, args)
|
||||
}
|
||||
})
|
||||
putConst("hooker", this, ScriptHooker(module.moduleInfo, logger, androidContext.classLoader).also {
|
||||
module.extras["ipc"] = CoreIPC(this@apply, module.moduleInfo)
|
||||
module.extras["hooker"] = ScriptHooker(module.moduleInfo, logger, androidContext.classLoader).also {
|
||||
scriptHookers.add(it)
|
||||
})
|
||||
}
|
||||
module.extras["config"] = CoreScriptConfig(this@apply, module.moduleInfo)
|
||||
}
|
||||
|
||||
scriptingInterface.enabledScripts.forEach { path ->
|
||||
enabledScripts.forEach { path ->
|
||||
runCatching {
|
||||
load(path, scriptingInterface.getScriptContent(path))
|
||||
}.onFailure {
|
||||
@ -54,3 +33,4 @@ class CoreScriptRuntime(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package me.rhunk.snapenhance.core.scripting.impl
|
||||
|
||||
import me.rhunk.snapenhance.bridge.scripting.IPCListener
|
||||
import me.rhunk.snapenhance.bridge.scripting.IScripting
|
||||
import me.rhunk.snapenhance.common.scripting.impl.IPCInterface
|
||||
import me.rhunk.snapenhance.common.scripting.impl.Listener
|
||||
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
|
||||
|
||||
class CoreIPC(
|
||||
private val scripting: IScripting,
|
||||
private val moduleInfo: ModuleInfo
|
||||
) : IPCInterface() {
|
||||
override fun onBroadcast(channel: String, eventName: String, listener: Listener) {
|
||||
scripting.registerIPCListener(channel, eventName, object: IPCListener.Stub() {
|
||||
override fun onMessage(args: Array<out String?>) {
|
||||
listener(args)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun on(eventName: String, listener: Listener) {
|
||||
onBroadcast(moduleInfo.name, eventName, listener)
|
||||
}
|
||||
|
||||
override fun emit(eventName: String, vararg args: String?) {
|
||||
broadcast(moduleInfo.name, eventName, *args)
|
||||
}
|
||||
|
||||
override fun broadcast(channel: String, eventName: String, vararg args: String?) {
|
||||
scripting.sendIPCMessage(channel, eventName, args)
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package me.rhunk.snapenhance.core.scripting.impl
|
||||
|
||||
import me.rhunk.snapenhance.bridge.scripting.IScripting
|
||||
import me.rhunk.snapenhance.common.scripting.impl.ConfigInterface
|
||||
import me.rhunk.snapenhance.common.scripting.impl.ConfigTransactionType
|
||||
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
|
||||
|
||||
class CoreScriptConfig(
|
||||
private val scripting: IScripting,
|
||||
private val moduleInfo: ModuleInfo
|
||||
): ConfigInterface() {
|
||||
override fun get(key: String, defaultValue: Any?): String? {
|
||||
return scripting.configTransaction(moduleInfo.name, ConfigTransactionType.GET.key, key, defaultValue.toString(), false)
|
||||
}
|
||||
|
||||
override fun set(key: String, value: Any?, save: Boolean) {
|
||||
scripting.configTransaction(moduleInfo.name, ConfigTransactionType.SET.key, key, value.toString(), save)
|
||||
}
|
||||
|
||||
override fun save() {
|
||||
scripting.configTransaction(moduleInfo.name, ConfigTransactionType.SAVE.key, null, null, false)
|
||||
}
|
||||
|
||||
override fun load() {
|
||||
scripting.configTransaction(moduleInfo.name, ConfigTransactionType.LOAD.key, null, null, false)
|
||||
}
|
||||
|
||||
override fun delete() {
|
||||
scripting.configTransaction(moduleInfo.name, ConfigTransactionType.DELETE.key, null, null, false)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user