Patch memory hole cleaner, and bounce version
Build and Test a3270 / Build Android APK (push) Successful in 6m47s

This commit is contained in:
2026-10-19 00:44:55 +00:00
parent 8608babb36
commit ffae82bab2
5 changed files with 28 additions and 15 deletions
+2 -2
View File
@@ -11,8 +11,8 @@ android {
applicationId "haus.nightmare.a3270" applicationId "haus.nightmare.a3270"
minSdk 24 minSdk 24
targetSdk 34 targetSdk 34
versionCode 9 versionCode 10
versionName "1.2.4" versionName "1.3.0"
} }
buildTypes { buildTypes {
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="9" android:versionCode="10"
android:versionName="1.2.4"> android:versionName="1.3.0">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -94,8 +94,8 @@ class TerminalViewModel(application: Application) : AndroidViewModel(application
private val inputExecutor = Executors.newSingleThreadExecutor() private val inputExecutor = Executors.newSingleThreadExecutor()
private val inputDispatcher = inputExecutor.asCoroutineDispatcher() private val inputDispatcher = inputExecutor.asCoroutineDispatcher()
// Non-blocking FIFO input channel buffer // Bounded FIFO input channel buffer (prevents unbounded queue growth if worker blocks)
private val inputChannel = Channel<TerminalInputAction>(Channel.UNLIMITED) private val inputChannel = Channel<TerminalInputAction>(256)
private val _connectionState = MutableStateFlow(ConnectionState.NOT_CONNECTED) private val _connectionState = MutableStateFlow(ConnectionState.NOT_CONNECTED)
val connectionState: StateFlow<ConnectionState> = _connectionState.asStateFlow() val connectionState: StateFlow<ConnectionState> = _connectionState.asStateFlow()
@@ -77,7 +77,12 @@ fun MacroDialog(
fun appendLog(msg: String) { fun appendLog(msg: String) {
val line = "[${java.text.SimpleDateFormat("HH:mm:ss", java.util.Locale.US).format(java.util.Date())}] $msg\n" val line = "[${java.text.SimpleDateFormat("HH:mm:ss", java.util.Locale.US).format(java.util.Date())}] $msg\n"
executionLog += line val combined = executionLog + line
executionLog = if (combined.length > 131072) {
combined.substring(combined.length - 131072)
} else {
combined
}
} }
DisposableEffect(client) { DisposableEffect(client) {
@@ -126,6 +126,15 @@ fun TerminalView(
} }
} }
val paint = remember {
Paint().apply {
isAntiAlias = true
typeface = Typeface.MONOSPACE
textAlign = Paint.Align.CENTER
}
}
var cachedGraphicsBitmap by remember { mutableStateOf<android.graphics.Bitmap?>(null) }
Box(modifier = modifier.fillMaxSize()) { Box(modifier = modifier.fillMaxSize()) {
Canvas( Canvas(
modifier = Modifier modifier = Modifier
@@ -289,12 +298,6 @@ fun TerminalView(
val offsetX = metrics.offsetX val offsetX = metrics.offsetX
val offsetY = metrics.offsetY val offsetY = metrics.offsetY
val paint = Paint().apply {
isAntiAlias = true
typeface = Typeface.MONOSPACE
textAlign = Paint.Align.CENTER
}
// Calculate optimal font size ensuring characters fit cleanly in cell without crowding // Calculate optimal font size ensuring characters fit cleanly in cell without crowding
val baseTextSize = cellHeight * 0.78f val baseTextSize = cellHeight * 0.78f
paint.textSize = baseTextSize paint.textSize = baseTextSize
@@ -335,8 +338,13 @@ fun TerminalView(
val gWidth = graphicsPlane.canvasWidth val gWidth = graphicsPlane.canvasWidth
val gHeight = graphicsPlane.canvasHeight val gHeight = graphicsPlane.canvasHeight
val rgb = graphicsPlane.rgbBuffer val rgb = graphicsPlane.rgbBuffer
if (gridW > 0 && gridH > 0 && rgb != null && gWidth > 0 && gHeight > 0) { if (gridW > 0 && gridH > 0 && rgb != null && gWidth > 0 && gHeight > 0 && rgb.size >= gWidth * gHeight) {
val bmp = android.graphics.Bitmap.createBitmap(rgb, gWidth, gHeight, android.graphics.Bitmap.Config.ARGB_8888) var bmp = cachedGraphicsBitmap
if (bmp == null || bmp.width != gWidth || bmp.height != gHeight || bmp.isRecycled) {
bmp = android.graphics.Bitmap.createBitmap(gWidth, gHeight, android.graphics.Bitmap.Config.ARGB_8888)
cachedGraphicsBitmap = bmp
}
bmp.setPixels(rgb, 0, gWidth, 0, 0, gWidth, gHeight)
drawContext.canvas.nativeCanvas.drawBitmap( drawContext.canvas.nativeCanvas.drawBitmap(
bmp, bmp,
null, null,