Skip to content

Commit 1b81b63

Browse files
committed
refactor: add RimeWrapper to deploy rime in async manner
1 parent fe85155 commit 1b81b63

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package com.osfans.trime.ime.core
2+
3+
import android.os.Looper
4+
import androidx.core.os.HandlerCompat
5+
import com.osfans.trime.core.Rime
6+
import com.osfans.trime.data.DataDirectoryChangeListener
7+
import com.osfans.trime.data.theme.Theme
8+
import kotlinx.coroutines.CoroutineScope
9+
import kotlinx.coroutines.Dispatchers
10+
import kotlinx.coroutines.Runnable
11+
import kotlinx.coroutines.flow.MutableStateFlow
12+
import kotlinx.coroutines.flow.asStateFlow
13+
import kotlinx.coroutines.launch
14+
import kotlinx.coroutines.sync.Mutex
15+
import kotlinx.coroutines.sync.withLock
16+
import timber.log.Timber
17+
import java.util.Collections
18+
import kotlin.system.measureTimeMillis
19+
20+
object RimeWrapper {
21+
private var mainThreadHandler = HandlerCompat.createAsync(Looper.getMainLooper())
22+
private val mutex = Mutex()
23+
private val myThreadSafeList = Collections.synchronizedList(mutableListOf<Runnable>())
24+
private val _statusStateFlow = MutableStateFlow(Status.UN_INIT)
25+
val statusStateFlow = _statusStateFlow.asStateFlow()
26+
27+
fun startup(r: Runnable? = null) {
28+
r.let {
29+
myThreadSafeList.add(it)
30+
}
31+
if (mutex.tryLock()) {
32+
if (_statusStateFlow.value == Status.UN_INIT) {
33+
Timber.d("Starting in a thread")
34+
_statusStateFlow.value = Status.IN_PROGRESS
35+
mutex.unlock()
36+
37+
val scope = CoroutineScope(Dispatchers.IO)
38+
scope.launch {
39+
measureTimeMillis {
40+
Rime.getInstance(false)
41+
Theme.get()
42+
}.also {
43+
Timber.d("Startup completed. It takes ${it / 1000} seconds")
44+
}
45+
46+
mutex.withLock {
47+
_statusStateFlow.value = Status.READY
48+
}
49+
50+
notifyUnlock()
51+
}
52+
} else {
53+
mutex.unlock()
54+
}
55+
}
56+
}
57+
58+
suspend fun deploy(): Boolean {
59+
return if (mutex.tryLock() && _statusStateFlow.value != Status.IN_PROGRESS) {
60+
_statusStateFlow.value = Status.IN_PROGRESS
61+
mutex.unlock()
62+
63+
DataDirectoryChangeListener.directoryChangeListeners.forEach {
64+
it.onDataDirectoryChange()
65+
}
66+
67+
Rime.deploy()
68+
69+
mutex.withLock {
70+
_statusStateFlow.value = Status.READY
71+
}
72+
Timber.d("Rime Deployed")
73+
true
74+
} else {
75+
false
76+
}
77+
}
78+
79+
private fun notifyUnlock() {
80+
Timber.d("notifying unlock")
81+
while (myThreadSafeList.isNotEmpty()) {
82+
myThreadSafeList.removeFirstOrNull()?.let {
83+
mainThreadHandler.post(it)
84+
}
85+
}
86+
Timber.d("Unlock totally Completed")
87+
}
88+
89+
fun runCheck() {
90+
if (isReady()) {
91+
notifyUnlock()
92+
}
93+
}
94+
95+
fun isReady(): Boolean {
96+
return _statusStateFlow.value == Status.READY
97+
}
98+
99+
fun runAfterStarted(r: Runnable) {
100+
myThreadSafeList.add(r)
101+
runCheck()
102+
}
103+
}
104+
105+
enum class Status {
106+
UN_INIT,
107+
IN_PROGRESS,
108+
READY,
109+
}

0 commit comments

Comments
 (0)