1 package com.android.graphics.bufferstreamsdemoapp 2 3 import androidx.compose.foundation.layout.Column 4 import androidx.compose.foundation.layout.fillMaxWidth 5 import androidx.compose.foundation.layout.height 6 import androidx.compose.foundation.layout.padding 7 import androidx.compose.foundation.layout.size 8 import androidx.compose.foundation.rememberScrollState 9 import androidx.compose.foundation.verticalScroll 10 import androidx.compose.material3.Card 11 import androidx.compose.material3.Text 12 import androidx.compose.runtime.Composable 13 import androidx.compose.runtime.mutableStateListOf 14 import androidx.compose.runtime.remember 15 import androidx.compose.ui.Modifier 16 import androidx.compose.ui.unit.dp 17 import java.util.Collections 18 19 /* 20 LogOutput centralizes logging: storing, displaying, adding, and clearing log messages with 21 thread safety. It is a singleton that's also accessed from C++. The private constructor will 22 not allow this class to be initialized, limiting it to getInstance(). 23 */ 24 class LogOutput private constructor() { 25 val logs = Collections.synchronizedList(mutableStateListOf<String>()) 26 27 @Composable LogOutputComposablenull28 fun LogOutputComposable() { 29 val rlogs = remember { logs } 30 31 Card(modifier = Modifier.fillMaxWidth().padding(16.dp).height(400.dp)) { 32 Column( 33 modifier = 34 Modifier.padding(10.dp).size(380.dp).verticalScroll(rememberScrollState())) { 35 for (log in rlogs) { 36 Text(log, modifier = Modifier.padding(0.dp)) 37 } 38 } 39 } 40 } 41 clearTextnull42 fun clearText() { 43 logs.clear() 44 } 45 addLognull46 fun addLog(log: String) { 47 logs.add(log) 48 } 49 50 companion object { 51 @Volatile private var instance: LogOutput? = null 52 53 @JvmStatic getInstancenull54 fun getInstance(): LogOutput { 55 if (instance == null) { 56 synchronized(this) { 57 if (instance == null) { 58 instance = LogOutput() 59 } 60 } 61 } 62 return instance!! 63 } 64 } 65 } 66