ui: add log items in buffered batches
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
2da80e8dee
commit
d7ccbd92e5
@ -185,36 +185,47 @@ class LogViewerActivity : AppCompatActivity() {
|
|||||||
return@withContext
|
return@withContext
|
||||||
}
|
}
|
||||||
val stdout = BufferedReader(InputStreamReader(process!!.inputStream, StandardCharsets.UTF_8))
|
val stdout = BufferedReader(InputStreamReader(process!!.inputStream, StandardCharsets.UTF_8))
|
||||||
var haveScrolled = false
|
|
||||||
val start = System.nanoTime()
|
var posStart = 0
|
||||||
var startPeriod = start
|
var timeLastNotify = System.nanoTime()
|
||||||
|
var priorModified = false
|
||||||
|
val bufferedLogLines = arrayListOf<LogLine>()
|
||||||
|
var timeout = 1000000000L / 2 // The timeout is initially small so that the view gets populated immediately.
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
val line = stdout.readLine() ?: break
|
val line = stdout.readLine() ?: break
|
||||||
rawLogLines.append(line)
|
rawLogLines.append(line)
|
||||||
rawLogLines.append('\n')
|
rawLogLines.append('\n')
|
||||||
val logLine = parseLine(line)
|
val logLine = parseLine(line)
|
||||||
withContext(Dispatchers.Main.immediate) {
|
|
||||||
if (logLine != null) {
|
if (logLine != null) {
|
||||||
recyclerView?.let {
|
bufferedLogLines.add(logLine)
|
||||||
val shouldScroll = haveScrolled && !it.canScrollVertically(1)
|
|
||||||
logLines.add(logLine)
|
|
||||||
if (haveScrolled) logAdapter.notifyDataSetChanged()
|
|
||||||
if (shouldScroll)
|
|
||||||
it.scrollToPosition(logLines.size - 1)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
logLines.lastOrNull()?.msg += "\n$line"
|
if (bufferedLogLines.isNotEmpty()) {
|
||||||
if (haveScrolled) logAdapter.notifyDataSetChanged()
|
bufferedLogLines.last().msg += "\n$line"
|
||||||
|
} else if (logLines.isNotEmpty()) {
|
||||||
|
logLines.last().msg += "\n$line"
|
||||||
|
priorModified = true
|
||||||
}
|
}
|
||||||
if (!haveScrolled) {
|
}
|
||||||
val end = System.nanoTime()
|
val timeNow = System.nanoTime()
|
||||||
val scroll = (end - start) > 1000000000L * 2.5 || !stdout.ready()
|
if ((timeNow - timeLastNotify) < timeout && stdout.ready())
|
||||||
if (logLines.isNotEmpty() && (scroll || (end - startPeriod) > 1000000000L / 4)) {
|
continue
|
||||||
logAdapter.notifyDataSetChanged()
|
timeout = 1000000000L * 5 / 2 // Increase the timeout after the initial view has something in it.
|
||||||
|
timeLastNotify = timeNow
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main.immediate) {
|
||||||
|
val isScrolledToBottomAlready = recyclerView?.canScrollVertically(1) == false
|
||||||
|
if (priorModified) {
|
||||||
|
logAdapter.notifyItemChanged(posStart - 1)
|
||||||
|
priorModified = false
|
||||||
|
}
|
||||||
|
logLines.addAll(bufferedLogLines)
|
||||||
|
bufferedLogLines.clear()
|
||||||
|
logAdapter.notifyItemRangeInserted(posStart, logLines.size - posStart)
|
||||||
|
posStart = logLines.size
|
||||||
|
|
||||||
|
if (isScrolledToBottomAlready) {
|
||||||
recyclerView?.scrollToPosition(logLines.size - 1)
|
recyclerView?.scrollToPosition(logLines.size - 1)
|
||||||
startPeriod = end
|
|
||||||
}
|
|
||||||
if (scroll) haveScrolled = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user