diff --git a/BTLib/build.gradle b/BTLib/build.gradle
index 4e610808..b057ceca 100644
--- a/BTLib/build.gradle
+++ b/BTLib/build.gradle
@@ -64,4 +64,6 @@ dependencies {
api libs.coroutines.core
api libs.coroutines.android
+
+ api libs.datastore.preferences
}
diff --git a/BTLib/src/main/java/com/offsetnull/bt/service/ConnectionCallback.java b/BTLib/src/main/java/com/offsetnull/bt/service/ConnectionCallback.java
deleted file mode 100644
index 91d88470..00000000
--- a/BTLib/src/main/java/com/offsetnull/bt/service/ConnectionCallback.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package com.offsetnull.bt.service;
-
-public interface ConnectionCallback {
- boolean isWindowShowing();
-
- void dataIncoming(byte[] seq);
-
- void processedDataIncoming(CharSequence seq);
-
- void htmlDataIncoming(String html);
-
- void rawDataIncoming(byte[] raw);
-
- void rawBufferIncoming(byte[] incoming);
-
- void loadSettings();
-
- void displayXMLError(String error);
-
- void displaySaveError(String error);
-
- void displayPluginSaveError(String plugin, String error);
-
- void executeColorDebug(int arg);
-
- void invokeDirtyExit();
-
- void showMessage(String message, boolean longtime);
-
- void showDialog(String message);
-
- void doVisualBell();
-
- void setScreenMode(boolean fullscreen);
-
- void showKeyBoard(
- String txt, boolean popup, boolean add, boolean flush, boolean clear, boolean close);
-
- void doDisconnectNotice(String display);
-
- void doLineBreak(int i);
-
- void reloadButtons(String setName);
-
- void clearAllButtons();
-
- void updateMaxVitals(int hp, int mana, int moves);
-
- void updateVitals(int hp, int mana, int moves);
-
- void updateEnemy(int hp);
-
- void updateVitals2(int hp, int mp, int maxhp, int maxmana, int enemy);
-
- void luaOmg(int stateIndex);
-
- void updateTriggerDebugString(String str);
-
- int getPort();
-
- String getHost();
-
- String getDisplay();
-
- void switchTo(String connection);
-
- void reloadBuffer();
-
- void loadWindowSettings();
-
- void markWindowsDirty();
-
- void markSettingsDirty();
-
- void setKeepLast(boolean keep);
-
- void setOrientation(int orientation);
-
- void setKeepScreenOn(boolean value);
-
- void setUseFullscreenEditor(boolean value);
-
- void setUseSuggestions(boolean value);
-
- void setCompatibilityMode(boolean value);
-
- void setRegexWarning(boolean value);
-}
diff --git a/BTLib/src/main/java/com/offsetnull/bt/service/ConnectionPluginCallback.java b/BTLib/src/main/java/com/offsetnull/bt/service/ConnectionPluginCallback.java
deleted file mode 100644
index f602c9c0..00000000
--- a/BTLib/src/main/java/com/offsetnull/bt/service/ConnectionPluginCallback.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) Dan Block 2013
- */
-package com.offsetnull.bt.service;
-
-import android.content.Context;
-
-/** Callback interface for plugins to interact with their parent Connection. */
-public interface ConnectionPluginCallback {
- /** Sets the plugin system dirty bit. */
- void setTriggersDirty();
-
- /**
- * Finds a window by name.
- *
- * @param name Desired window name.
- * @return The WindowToken associated with name. null if window does not exist.
- */
- WindowToken getWindowByName(String name);
-
- /**
- * Interrogates the foreground window as to its visibility state.
- *
- * @return The foreground window visibility state.
- */
- boolean isWindowShowing();
-
- /**
- * Attaches a window settings changed listener to the target window.
- *
- * @param w WindowToken to attach a listener to.
- */
- void attatchWindowSettingsChangedListener(WindowToken w);
-
- /**
- * Gets the status bar height.
- *
- * @return The status bar height.
- */
- int getStatusBarHeight();
-
- /**
- * Gets the title bar height.
- *
- * @return The title bar height.
- */
- int getTitleBarHeight();
-
- /** Causes an immediate rebuild of the trigger system. */
- void buildTriggerSystem();
-
- /**
- * Gets the display name for the Connection.
- *
- * @return The display name.
- */
- String getDisplayName();
-
- /**
- * Gets the host name for the Connection.
- *
- * @return The host name.
- */
- String getHostName();
-
- /**
- * Gets the port number for the Connection.
- *
- * @return The port number.
- */
- int getPort();
-
- /**
- * Gets the application context.
- *
- * @return The application context.
- */
- Context getContext();
-
- /**
- * Gets the default SettingsChangedListener used by the parent Connection.
- *
- * @return The SettingsChangedListener.
- */
- SettingsChangedListener getSettingsListener();
-
- /**
- * Calls a function in a target plugin.
- *
- * @param plugin The target plugin.
- * @param function The target function.
- * @param data Arugment to supply to target
- */
- void callPlugin(String plugin, String function, String data);
-
- /**
- * Tests weather a plugin supports a given function.
- *
- * @param plugin The target plugin.
- * @param function The target function name to test.
- * @return True if plugin supports function. False if not or plugin does
- * not exist.
- */
- boolean pluginSupports(String plugin, String function);
-}
diff --git a/BTLib/src/main/java/com/offsetnull/bt/service/SettingsChangedListener.java b/BTLib/src/main/java/com/offsetnull/bt/service/SettingsChangedListener.java
deleted file mode 100644
index 2f7c80e8..00000000
--- a/BTLib/src/main/java/com/offsetnull/bt/service/SettingsChangedListener.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) Dan Block 2013
- */
-package com.offsetnull.bt.service;
-
-/**
- * Quick little interface to give the settings system a callback to call when a setting has changed.
- */
-public interface SettingsChangedListener {
- /**
- * The method to call when a setting has changed.
- *
- * @param key The key of the setting that changed.
- * @param value The new value of the setting.
- */
- void updateSetting(String key, String value);
-}
diff --git a/BTLib/src/main/java/com/offsetnull/bt/service/WindowCallback.java b/BTLib/src/main/java/com/offsetnull/bt/service/WindowCallback.java
deleted file mode 100644
index f8056188..00000000
--- a/BTLib/src/main/java/com/offsetnull/bt/service/WindowCallback.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.offsetnull.bt.service;
-
-public interface WindowCallback {
- boolean isWindowShowing();
-
- void rawDataIncoming(byte[] raw);
-
- void resetWithRawDataIncoming(byte[] raw);
-
- void redraw();
-
- String getName();
-
- void shutdown();
-
- void xcallS(String function, String str);
-
- void xcallB(String function, byte[] raw);
-
- void clearText();
-
- void updateSetting(String key, String value);
-
- void setEncoding(String value);
-}
diff --git a/BTLib/src/main/kotlin/com/offsetnull/bt/service/ConnectionCallback.kt b/BTLib/src/main/kotlin/com/offsetnull/bt/service/ConnectionCallback.kt
new file mode 100644
index 00000000..3d69319d
--- /dev/null
+++ b/BTLib/src/main/kotlin/com/offsetnull/bt/service/ConnectionCallback.kt
@@ -0,0 +1,109 @@
+package com.offsetnull.bt.service
+
+@Suppress("TooManyFunctions")
+interface ConnectionCallback {
+ fun isWindowShowing(): Boolean
+ fun dataIncoming(seq: ByteArray)
+ fun processedDataIncoming(seq: CharSequence)
+ fun htmlDataIncoming(html: String)
+ fun rawDataIncoming(raw: ByteArray)
+ fun rawBufferIncoming(incoming: ByteArray)
+ fun loadSettings()
+ fun displayXMLError(error: String)
+ fun displaySaveError(error: String)
+ fun displayPluginSaveError(plugin: String, error: String)
+ fun executeColorDebug(arg: Int)
+ fun invokeDirtyExit()
+ fun showMessage(message: String, longtime: Boolean)
+ fun showDialog(message: String)
+ fun doVisualBell()
+ fun setScreenMode(fullscreen: Boolean)
+ fun showKeyBoard(
+ txt: String,
+ popup: Boolean,
+ add: Boolean,
+ flush: Boolean,
+ clear: Boolean,
+ close: Boolean,
+ )
+ fun doDisconnectNotice(display: String)
+ fun doLineBreak(i: Int)
+ fun reloadButtons(setName: String)
+ fun clearAllButtons()
+ fun updateMaxVitals(hp: Int, mana: Int, moves: Int)
+ fun updateVitals(hp: Int, mana: Int, moves: Int)
+ fun updateEnemy(hp: Int)
+ fun updateVitals2(hp: Int, mp: Int, maxhp: Int, maxmana: Int, enemy: Int)
+ fun luaOmg(stateIndex: Int)
+ fun updateTriggerDebugString(str: String)
+ fun getPort(): Int
+ fun getHost(): String
+ fun getDisplay(): String
+ fun switchTo(connection: String)
+ fun reloadBuffer()
+ fun loadWindowSettings()
+ fun markWindowsDirty()
+ fun markSettingsDirty()
+ fun setKeepLast(keep: Boolean)
+ fun setOrientation(orientation: Int)
+ fun setKeepScreenOn(value: Boolean)
+ fun setUseFullscreenEditor(value: Boolean)
+ fun setUseSuggestions(value: Boolean)
+ fun setCompatibilityMode(value: Boolean)
+ fun setRegexWarning(value: Boolean)
+}
+
+/** Sealed event hierarchy for future Flow-based replacement of [ConnectionCallback]. */
+sealed interface ConnectionEvent {
+ data class DataIncoming(val seq: ByteArray) : ConnectionEvent
+ data class ProcessedDataIncoming(val seq: CharSequence) : ConnectionEvent
+ data class HtmlDataIncoming(val html: String) : ConnectionEvent
+ data class RawDataIncoming(val raw: ByteArray) : ConnectionEvent
+ data class RawBufferIncoming(val incoming: ByteArray) : ConnectionEvent
+ data object LoadSettings : ConnectionEvent
+ data class DisplayXMLError(val error: String) : ConnectionEvent
+ data class DisplaySaveError(val error: String) : ConnectionEvent
+ data class DisplayPluginSaveError(val plugin: String, val error: String) : ConnectionEvent
+ data class ExecuteColorDebug(val arg: Int) : ConnectionEvent
+ data object InvokeDirtyExit : ConnectionEvent
+ data class ShowMessage(val message: String, val longtime: Boolean) : ConnectionEvent
+ data class ShowDialog(val message: String) : ConnectionEvent
+ data object DoVisualBell : ConnectionEvent
+ data class SetScreenMode(val fullscreen: Boolean) : ConnectionEvent
+ data class ShowKeyBoard(
+ val txt: String,
+ val popup: Boolean,
+ val add: Boolean,
+ val flush: Boolean,
+ val clear: Boolean,
+ val close: Boolean,
+ ) : ConnectionEvent
+ data class DoDisconnectNotice(val display: String) : ConnectionEvent
+ data class DoLineBreak(val i: Int) : ConnectionEvent
+ data class ReloadButtons(val setName: String) : ConnectionEvent
+ data object ClearAllButtons : ConnectionEvent
+ data class UpdateMaxVitals(val hp: Int, val mana: Int, val moves: Int) : ConnectionEvent
+ data class UpdateVitals(val hp: Int, val mana: Int, val moves: Int) : ConnectionEvent
+ data class UpdateEnemy(val hp: Int) : ConnectionEvent
+ data class UpdateVitals2(
+ val hp: Int,
+ val mp: Int,
+ val maxhp: Int,
+ val maxmana: Int,
+ val enemy: Int,
+ ) : ConnectionEvent
+ data class LuaOmg(val stateIndex: Int) : ConnectionEvent
+ data class UpdateTriggerDebugString(val str: String) : ConnectionEvent
+ data class SwitchTo(val connection: String) : ConnectionEvent
+ data object ReloadBuffer : ConnectionEvent
+ data object LoadWindowSettings : ConnectionEvent
+ data object MarkWindowsDirty : ConnectionEvent
+ data object MarkSettingsDirty : ConnectionEvent
+ data class SetKeepLast(val keep: Boolean) : ConnectionEvent
+ data class SetOrientation(val orientation: Int) : ConnectionEvent
+ data class SetKeepScreenOn(val value: Boolean) : ConnectionEvent
+ data class SetUseFullscreenEditor(val value: Boolean) : ConnectionEvent
+ data class SetUseSuggestions(val value: Boolean) : ConnectionEvent
+ data class SetCompatibilityMode(val value: Boolean) : ConnectionEvent
+ data class SetRegexWarning(val value: Boolean) : ConnectionEvent
+}
diff --git a/BTLib/src/main/kotlin/com/offsetnull/bt/service/ConnectionPluginCallback.kt b/BTLib/src/main/kotlin/com/offsetnull/bt/service/ConnectionPluginCallback.kt
new file mode 100644
index 00000000..592a9310
--- /dev/null
+++ b/BTLib/src/main/kotlin/com/offsetnull/bt/service/ConnectionPluginCallback.kt
@@ -0,0 +1,32 @@
+package com.offsetnull.bt.service
+
+import android.content.Context
+
+@Suppress("TooManyFunctions")
+interface ConnectionPluginCallback {
+ fun setTriggersDirty()
+ fun getWindowByName(name: String): WindowToken?
+ fun isWindowShowing(): Boolean
+ fun attatchWindowSettingsChangedListener(w: WindowToken)
+ fun getStatusBarHeight(): Int
+ fun getTitleBarHeight(): Int
+ fun buildTriggerSystem()
+ fun getDisplayName(): String
+ fun getHostName(): String
+ fun getPort(): Int
+ fun getContext(): Context
+ fun getSettingsListener(): SettingsChangedListener
+ fun callPlugin(plugin: String, function: String, data: String)
+ fun pluginSupports(plugin: String, function: String): Boolean
+}
+
+/** Sealed event hierarchy for future Flow-based replacement of [ConnectionPluginCallback]. */
+sealed interface PluginEvent {
+ data object SetTriggersDirty : PluginEvent
+ data object BuildTriggerSystem : PluginEvent
+ data class CallPlugin(
+ val plugin: String,
+ val function: String,
+ val data: String,
+ ) : PluginEvent
+}
diff --git a/BTLib/src/main/kotlin/com/offsetnull/bt/service/SettingsChangedListener.kt b/BTLib/src/main/kotlin/com/offsetnull/bt/service/SettingsChangedListener.kt
new file mode 100644
index 00000000..30927783
--- /dev/null
+++ b/BTLib/src/main/kotlin/com/offsetnull/bt/service/SettingsChangedListener.kt
@@ -0,0 +1,10 @@
+package com.offsetnull.bt.service
+
+interface SettingsChangedListener {
+ fun updateSetting(key: String, value: String)
+}
+
+/** Sealed event hierarchy for future Flow-based replacement of [SettingsChangedListener]. */
+sealed interface SettingsEvent {
+ data class SettingChanged(val key: String, val value: String) : SettingsEvent
+}
diff --git a/BTLib/src/main/kotlin/com/offsetnull/bt/service/WindowCallback.kt b/BTLib/src/main/kotlin/com/offsetnull/bt/service/WindowCallback.kt
new file mode 100644
index 00000000..b7443317
--- /dev/null
+++ b/BTLib/src/main/kotlin/com/offsetnull/bt/service/WindowCallback.kt
@@ -0,0 +1,29 @@
+package com.offsetnull.bt.service
+
+@Suppress("TooManyFunctions")
+interface WindowCallback {
+ fun isWindowShowing(): Boolean
+ fun rawDataIncoming(raw: ByteArray)
+ fun resetWithRawDataIncoming(raw: ByteArray)
+ fun redraw()
+ fun getName(): String
+ fun shutdown()
+ fun xcallS(function: String, str: String)
+ fun xcallB(function: String, raw: ByteArray)
+ fun clearText()
+ fun updateSetting(key: String, value: String)
+ fun setEncoding(value: String)
+}
+
+/** Sealed event hierarchy for future Flow-based replacement of [WindowCallback]. */
+sealed interface WindowEvent {
+ data class RawDataIncoming(val raw: ByteArray) : WindowEvent
+ data class ResetWithRawDataIncoming(val raw: ByteArray) : WindowEvent
+ data object Redraw : WindowEvent
+ data object Shutdown : WindowEvent
+ data class XcallS(val function: String, val str: String) : WindowEvent
+ data class XcallB(val function: String, val raw: ByteArray) : WindowEvent
+ data object ClearText : WindowEvent
+ data class UpdateSetting(val key: String, val value: String) : WindowEvent
+ data class SetEncoding(val value: String) : WindowEvent
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index b92766e9..85fb5593 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -14,6 +14,7 @@ activityCompose = "1.12.4"
lifecycle = "2.10.0"
room = "2.8.4"
coroutines = "1.10.2"
+datastore = "1.1.7"
[libraries]
appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
@@ -33,6 +34,7 @@ room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" }
+datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }