lm-sistemi-software-distrib.../src/main/kotlin/util/active/ActiveObjectHandler.kt

52 lines
1.3 KiB
Kotlin

package util.active
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit
class ActiveObjectHandler(private val target: Any) : InvocationHandler {
private val queue = LinkedBlockingQueue<Call>()
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any {
if (method != null && args != null)
queue.add(Call(method, args))
return Unit
}
fun start(): Job {
return GlobalScope.launch {
while (isActive || queue.isNotEmpty()) {
queue.poll(100, TimeUnit.MILLISECONDS)
?.executeOn(target) ?: continue
}
}
}
data class Call(val method: Method, val args: Array<out Any>) {
fun executeOn(target: Any) {
method.invoke(target, *args)
}
}
}
fun <T> Any.toActive(inter: Class<T>): Pair<T, Job> {
val active = ActiveObjectHandler(this)
val job = active.start()
return Pair(
Proxy.newProxyInstance(
this::class.java.classLoader,
arrayOf(inter),
active
) as T, job
)
}