com.itangcent.intellij.extend.rx.AutoComputer.kt Maven / Gradle / Ivy
Show all versions of guice-action Show documentation
package com.itangcent.intellij.extend.rx
import com.google.common.cache.Cache
import com.google.common.cache.CacheBuilder
import com.intellij.util.containers.Stack
import com.itangcent.common.utils.IDUtils
import com.itangcent.common.utils.changePropertyValue
import com.itangcent.common.utils.getPropertyValue
import com.itangcent.intellij.extend.rx.AutoComputerUtils.mergeFilter
import org.apache.commons.lang3.StringUtils
import java.awt.Component
import java.awt.EventQueue
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import javax.swing.*
import javax.swing.event.*
import javax.swing.text.JTextComponent
import kotlin.jvm.internal.CallableReference
import kotlin.reflect.*
import kotlin.reflect.jvm.isAccessible
class AutoComputer {
private val throttleHelper: ThrottleHelper = ThrottleHelper()
private val listeners = ConcurrentHashMap, () -> Unit>()
private val passiveListeners = ConcurrentHashMap, () -> Unit>()
private val wrapCache: Cache = CacheBuilder
.newBuilder()
.build()
private var pool: (() -> Unit) -> Unit = { it() }
private var mode = Mode.ALL
fun mode(mode: Mode): AutoComputer {
this.mode = mode
return this
}
fun withMode(mode: Mode, action: () -> Unit): AutoComputer {
val olderMode = this.mode
this.mode = mode
try {
action()
} finally {
this.mode = olderMode
}
return this
}
/**
* set value,and compute
*/
fun value(property: KMutableProperty0, value: T) {
property.safeSet(value)
val getter: AGetter = this.wrapGetter(property)
call(getter)
}
/**
* set value,and compute
*/
@Suppress("UNCHECKED_CAST")
fun value(setter: ASetter, value: T?) {
if (!mode.allowed(setter)) {
return
}
setter.set(value)
if (setter is AGetter<*>) {
call(setter as AGetter)
}
}
/**
* set value,and compute
*/
public fun value(target: Any, property: String, value: T?) {
value(wrapBeanProperty(target, property), value)
}
//region try compute---------------------------------------------------------------
internal fun call(getter: AGetter) {
if (!this.mode.allowed(getter)) {
return
}
val action = listeners[getter as AGetter<*>]
var doAction = false
try {
if (action != null) {
doAction = pushAction(action)
if (doAction) {
//入栈成功,可执行
val actionStack = actionThreadLocal.get()
val rootThread = Thread.currentThread()
pool {
if (Thread.currentThread() != rootThread) {
actionThreadLocal.set(actionStack)
try {
action()
} finally {
actionThreadLocal.remove()
}
} else {
action()
}
}
}
//如果入栈失败,说明此Action在本次响应中已执行,则不再循环执行
}
//call relative
listeners.keys
.filter { isRelative(it, getter) }
.forEach { listeners[it]?.invoke() }
//call relative,重新计算子节点
passiveListeners.keys
.filter { isSon(it, getter) }
.forEach { passiveListeners[it]?.invoke() }
} finally {
if (doAction) {
popAction()
}
}
}
private val actionThreadLocal: ThreadLocal Unit>> = ThreadLocal Unit>>()
private fun pushAction(action: () -> Unit): Boolean {
var actionStack = actionThreadLocal.get()
return when {
actionStack == null -> {
actionStack = Stack(1)
actionThreadLocal.set(actionStack)
actionStack.push(action)
true
}
actionStack.contains(action) -> false
else -> {
actionStack.push(action)
true
}
}
}
private fun popAction() {
val actionStack = actionThreadLocal.get()
actionStack.pop()
if (actionStack.isEmpty()) {
actionThreadLocal.remove()
}
}
//endregion try compute---------------------------------------------------------------
private fun isRelative(getter: AGetter<*>, anotherGetter: AGetter<*>): Boolean {
return when {
getter == anotherGetter -> false
getter !is HasProperty<*> -> false
anotherGetter !is HasProperty<*> -> false
getter.getProperty().target() != anotherGetter.getProperty().target() -> false
getter.getProperty().name().startsWith(anotherGetter.getProperty().name() + ".") -> true
anotherGetter.getProperty().name().startsWith(getter.getProperty().name() + ".") -> true
else -> false
}
}
/**
* setter is son of getter
*/
private fun isSon(setter: ASetter<*>, getter: AGetter<*>): Boolean {
return when {
setter == getter -> false
setter !is HasProperty<*> -> false
getter !is HasProperty<*> -> false
setter.getProperty().target() != getter.getProperty().target() -> false
setter.getProperty().name().startsWith(getter.getProperty().name() + ".") -> true
else -> false
}
}
fun bind(property: KMutableProperty0): AutoBind0 {
val wrapSetter = wrapSetter(property)
return buildBind(this, wrapSetter)
}
fun bind(component: JTextComponent): AutoBind0 {
val wrapSetter = wrapJTextComponent(component)
return buildBind(this, wrapSetter)
}
fun bindText(component: AbstractButton): AutoBind0 {
val wrapSetter = wrapJButtonTextComponent(component)
return buildBind(this, wrapSetter)
}
fun bind(component: JCheckBox): AutoBind0 {
val wrapSetter = wrapJCheckBoxComponentWrap(component)
return buildBind(this, wrapSetter)
}
fun bind(component: JLabel): AutoBind0 {
val wrapSetter = wrapJLabel(component)
return buildBind(this, wrapSetter)
}
fun bindEnable(component: JComponent): AutoBind0 {
val wrapSetter = wrapComponentEnable(component)
return buildBind(this, wrapSetter)
}
fun bindVisible(component: JComponent): AutoBind0 {
val wrapSetter = wrapComponentVisible(component)
return buildBind(this, wrapSetter)
}
fun bindName(component: JComponent): AutoBind0 {
val wrapSetter = wrapComponentName(component)
return buildBind(this, wrapSetter)
}
fun bindIndex(component: JList<*>): AutoBind0 {
val wrapSetter = wrapJListIndexComponent(component)
return buildBind(this, wrapSetter)
}
fun bind(component: JList<*>): AutoBind0?> {
val wrapSetter = wrapJListComponent(component)
return buildBind(this, wrapSetter)
}
fun bindIndex(component: JComboBox<*>): AutoBind0 {
val wrapSetter = wrapJComboBoxIndexComponent(component)
return buildBind(this, wrapSetter)
}
fun bind(component: JComboBox): AutoBind0 {
val wrapSetter = wrapJComboBoxComponent(component)
return buildBind(this, wrapSetter)
}
fun bind(target: Any, property: String): AutoBind0 {
val wrapSetter: ASetter = wrapBeanProperty(target, property)
return buildBind(this, wrapSetter)
}
fun bind(target: Any, property: String, type: KClass): AutoBind0 {
val wrapSetter: ASetter = wrapBeanProperty(target, property)
return buildBind(this, wrapSetter)
}
//region ***************listen***************-------------------------------
fun listen(property: KMutableProperty0): ListenAble {
val wrapGetter = wrapGetter(property)
return ListenAble(this, wrapGetter)
}
fun listen(component: JTextComponent): ListenAble {
val wrapGetter = wrapJTextComponent(component)
return ListenAble(this, wrapGetter)
}
fun listenText(component: AbstractButton): ListenAble {
val wrapGetter = wrapJButtonTextComponent(component)
return ListenAble(this, wrapGetter)
}
fun listen(component: JCheckBox): ListenAble {
val wrapGetter = wrapJCheckBoxComponentWrap(component)
return ListenAble(this, wrapGetter)
}
fun listen(component: JLabel): ListenAble {
val wrapGetter = wrapJLabel(component)
return ListenAble(this, wrapGetter)
}
fun listenEnable(component: JComponent): ListenAble {
val wrapGetter = wrapComponentEnable(component)
return ListenAble(this, wrapGetter)
}
fun listenVisible(component: JComponent): ListenAble {
val wrapGetter = wrapComponentVisible(component)
return ListenAble(this, wrapGetter)
}
fun listenName(component: JComponent): ListenAble {
val wrapGetter = wrapComponentName(component)
return ListenAble(this, wrapGetter)
}
fun listenIndex(component: JList<*>): ListenAble {
val wrapGetter = wrapJListIndexComponent(component)
return ListenAble(this, wrapGetter)
}
fun listen(component: JList<*>): ListenAble> {
val wrapGetter = wrapJListComponent(component)
return ListenAble(this, wrapGetter)
}
fun listenIndex(component: JComboBox<*>): ListenAble {
val wrapGetter = wrapJComboBoxIndexComponent(component)
return ListenAble(this, wrapGetter)
}
fun listen(component: JComboBox): ListenAble {
val wrapGetter = wrapJComboBoxComponent(component)
return ListenAble(this, wrapGetter)
}
fun listen(target: Any, property: String): ListenAble {
val wrapGetter: AGetter = wrapBeanProperty(target, property)
return ListenAble(this, wrapGetter)
}
fun listen(
target: Any,
property: String,
type: KClass
): ListenAble {
val wrapGetter: AGetter = wrapBeanProperty(target, property)
return ListenAble(this, wrapGetter)
}
@Suppress("UNCHECKED_CAST")
internal fun singleListen(
wrapGetter: AGetter,
action: (T?) -> Unit
) {
addListeners({
action(wrapGetter.get())
}, wrapGetter as AGetter)
}
//endregion ***************listen***************-------------------------------
@Suppress("UNCHECKED_CAST")
private fun wrapSetter(property: KMutableProperty0): ASetter {
return wrapCache.get(property) {
KMutableProperty0Wrap(property, parseProperty(property))
} as ASetter
}
private fun wrapComponentEnable(component: Component): ComponentEnableWrap {
return wrapCache.get(component to "enable") {
ComponentEnableWrap(component)
} as ComponentEnableWrap
}
private fun wrapComponentVisible(component: Component): ComponentVisibleWrap {
return wrapCache.get(component to "visible") {
ComponentVisibleWrap(component)
} as ComponentVisibleWrap
}
private fun wrapComponentName(component: Component): ComponentNameWrap {
return wrapCache.get(component to "name") {
ComponentNameWrap(component)
} as ComponentNameWrap
}
internal fun wrapJTextComponent(component: JTextComponent): JTextComponentWrap {
return wrapCache.get(component) {
JTextComponentWrap(component)
} as JTextComponentWrap
}
internal fun wrapJButtonTextComponent(component: AbstractButton): JButtonTextComponentWrap {
return wrapCache.get(component) {
JButtonTextComponentWrap(component)
} as JButtonTextComponentWrap
}
internal fun wrapJCheckBoxComponentWrap(component: JCheckBox): JCheckBoxComponentWrap {
return wrapCache.get(component) {
JCheckBoxComponentWrap(component)
} as JCheckBoxComponentWrap
}
internal fun wrapJLabel(component: JLabel): JLabelWrap {
return wrapCache.get(component) {
JLabelWrap(component)
} as JLabelWrap
}
internal fun wrapJListIndexComponent(component: JList<*>): JListComponentIndexWrap {
return wrapCache.get(component to "index") {
JListComponentIndexWrap(component)
} as JListComponentIndexWrap
}
internal fun wrapJListComponent(component: JList<*>): JListComponentWrap {
return wrapCache.get(component) {
JListComponentWrap(component)
} as JListComponentWrap
}
internal fun wrapJComboBoxIndexComponent(component: JComboBox<*>): JComboBoxComponentIndexWrap {
return wrapCache.get(component to "index") {
JComboBoxComponentIndexWrap(component)
} as JComboBoxComponentIndexWrap
}
@Suppress("UNCHECKED_CAST")
internal fun wrapJComboBoxComponent(component: JComboBox): JComboBoxComponentWrap {
return wrapCache.get(component) {
JComboBoxComponentWrap(component)
} as JComboBoxComponentWrap
}
@Suppress("UNCHECKED_CAST")
internal fun wrapBeanProperty(target: Any, property: String): BeanPropertyWrap {
return wrapCache.get(Pair(target, property)) {
val tinyProperty = StringUtils.removeStart(property, "this.")
val lastDot = StringUtils.lastIndexOf(tinyProperty, ".")
val targetExp = StringUtils.substring(tinyProperty, 0, lastDot)
val propertyExp = StringUtils.substring(tinyProperty, lastDot + 1)
val targetGetter: () -> Any?
when {
//空,直接取target
StringUtils.isBlank(targetExp) -> targetGetter = { target }
//一级,直接读属性
targetExp.indexOf('.') == -1 -> targetGetter = { target.getPropertyValue(targetExp) }
//多级,多次读属性,有一级为空,即返回null
else -> {
val properties = targetExp.split('.')
targetGetter = {
var result: Any? = null
for (p in properties) {
result = target.getPropertyValue(p)
if (result == null)
break
}
result
}
}
}
val propertySetter: (Any, T?) -> Unit = { any: Any, t: T? -> any.changePropertyValue(propertyExp, t) }
val propertyGetter: ((Any) -> T?) = { any -> any.getPropertyValue(propertyExp) as T? }
BeanPropertyWrap(targetGetter, propertySetter, propertyGetter, BeanProperty(target, tinyProperty))
} as BeanPropertyWrap
}
@Suppress("UNCHECKED_CAST")
internal fun wrapGetter(property: KProperty0): AGetter {
return if (property is KMutableProperty0) {
wrapCache.get(property) {
KMutableProperty0Wrap(property, parseProperty(property))
} as AGetter
} else {
wrapCache.get(property) {
KProperty0Wrap(property, parseProperty(property))
} as AGetter
}
}
private fun parseProperty(property: KProperty0<*>): AProperty {
return when (property) {
is CallableReference -> BeanProperty(property.boundReceiver, property.name)
else -> BeanProperty(null, property.name)
}
}
private fun addListeners(exp: () -> Unit, vararg properties: AGetter) {
for (property in properties) {
mergeListeners(exp, property)
}
}
private fun addListeners(exp: () -> Unit, properties: List>) {
for (property in properties) {
mergeListeners(exp, property)
}
}
private fun mergeListeners(exp: () -> Unit, property: AGetter) {
val old = listeners[property]
if (old == null) {
property.onListen(this)
listeners[property] = exp
} else {
listeners[property] = {
old()
exp()
}
}
}
private fun addPassiveListeners(property: ASetter, exp: () -> Unit) {
val old = passiveListeners[property]
if (old == null) {
passiveListeners[property] = exp
} else {
passiveListeners[property] = {
old()
exp()
}
}
// val put = passiveListeners.put(property, exp)
// Assert.assertNull("a property should not bind twice!", put)
}
fun listenOn(pool: (() -> Unit) -> Unit): AutoComputer {
this.pool = pool
return this
}
class AutoBindData {
var computer: AutoComputer
var filter: (Filter)? = null
var property: ASetter
var params: MutableList>
var linkedParams: MutableList>? = null
constructor(computer: AutoComputer, property: ASetter, params: MutableList>) {
this.computer = computer
this.property = property
this.params = params
}
}
abstract class AutoBind {
protected var core: AutoBindData
constructor(core: AutoBindData) {
this.core = core
}
@Suppress("UNCHECKED_CAST")
fun link(param: KProperty0): C {
val getter: AGetter = core.computer.wrapGetter(param)
if (core.linkedParams == null) {
core.linkedParams = ArrayList()
core.linkedParams!!.add(getter)
}
return this as C
}
@Suppress("UNCHECKED_CAST")
open fun eval(exp: E) {
// val evalFun: () -> Unit = { pool { evalFun(exp) } }
var evalFun: () -> Unit = evalFun(exp)
val wrapPool = pool
if (wrapPool != null) {
val wrapFun = evalFun
evalFun = { wrapPool(wrapFun) }
}
val wrapFilter = core.filter
if (wrapFilter != null) {
val wrapFun = evalFun
evalFun = {
if (wrapFilter()) {
wrapFun()
}
}
}
core.computer.addPassiveListeners(core.property as ASetter, evalFun)
core.computer.addListeners(evalFun, core.params)
if (core.linkedParams != null) {
for (kProperty in (core.linkedParams as List>)) {
core.computer.addListeners(evalFun, kProperty)
}
}
}
fun throttle(cd: Long): C {
return throttle(core.property, cd)
}
fun throttle(specialKey: Any, cd: Long): C {
val throttleFilter = { computer().throttleHelper.acquire(specialKey, cd) }
return filter(throttleFilter)
}
@Suppress("UNCHECKED_CAST")
fun filter(newFilter: Filter): C {
val filter = this.core.filter
if (filter == null) {
this.core.filter = newFilter
} else {
this.core.filter = {
filter() && newFilter()
}
}
return this as C
}
private var pool: ((() -> Unit) -> Unit)? = null
@Suppress("UNCHECKED_CAST")
fun listenOn(pool: (() -> Unit) -> Unit): C {
this.pool = pool
return this as C
}
protected fun computer(): AutoComputer {
return core.computer
}
protected abstract fun evalFun(exp: E): () -> Unit
}
class AutoBind0 : AutoBind T, AutoBind0> {
constructor(core: AutoBindData) : super(core)
@Suppress("UNCHECKED_CAST")
fun with(param: KProperty0
): AutoBind1 {
val wrapGetter: AGetter = computer().wrapGetter(param) as AGetter
return withGetter(wrapGetter)
}
@Suppress("UNCHECKED_CAST")
fun
with(target: Any, property: String): AutoBind1 {
val wrapGetter: AGetter = computer().wrapBeanProperty
(target, property) as AGetter
return withGetter(wrapGetter)
}
fun
with(target: Any, property: String, type: KClass
): AutoBind1 {
return with(target, property)
}
@Suppress("UNCHECKED_CAST")
fun with(param: JTextComponent): AutoBind1 {
val wrapGetter: AGetter = computer().wrapJTextComponent(param)
return withGetter(wrapGetter)
}
@Suppress("UNCHECKED_CAST")
fun with(param: JLabel): AutoBind1 {
val wrapGetter: AGetter = computer().wrapJLabel(param)
return withGetter(wrapGetter)
}
@Suppress("UNCHECKED_CAST")
fun withIndex(param: JList<*>): AutoBind1 {
val wrapGetter: AGetter = computer().wrapJListIndexComponent(param)
return withGetter(wrapGetter)
}
fun withEnable(component: JComponent): AutoBind1 {
val wrapGetter: AGetter = computer().wrapComponentEnable(component)
return withGetter(wrapGetter)
}
fun withVisible(component: JComponent): AutoBind1 {
val wrapGetter: AGetter = computer().wrapComponentVisible(component)
return withGetter(wrapGetter)
}
fun withName(component: JComponent): AutoBind1 {
val wrapGetter: AGetter = computer().wrapComponentName(component)
return withGetter(wrapGetter)
}
fun with(component: JList<*>): AutoBind1?> {
val wrapGetter: AGetter?> = computer().wrapJListComponent(component)
return withGetter(wrapGetter)
}
fun withIndex(component: JComboBox<*>): AutoBind1 {
val wrapGetter: AGetter = computer().wrapJComboBoxIndexComponent(component)
return withGetter(wrapGetter)
}
fun with(component: JComboBox
): AutoBind1 {
val wrapGetter: AGetter = computer().wrapJComboBoxComponent(component)
return withGetter(wrapGetter)
}
@Suppress("UNCHECKED_CAST")
fun
withGetter(getter: AGetter
): AutoBind1 {
this.core.params.add(getter as AGetter)
return AutoBind1(core)
}
internal fun peakCore(): AutoBindData {
return core
}
override fun evalFun(exp: () -> T): () -> Unit {
return { computer().value(core.property, exp()) }
}
}
@Suppress("UNCHECKED_CAST")
class AutoBind1 : AutoBind T, AutoBind1> {
constructor(core: AutoBindData) : super(core)
@Suppress("UNCHECKED_CAST")
fun with(param: KProperty0): AutoBind2 {
val wrapGetter: AGetter = computer().wrapGetter(param) as AGetter
return withGetter(wrapGetter)
}
@Suppress("UNCHECKED_CAST")
fun with(target: Any, property: String): AutoBind2 {
val wrapGetter: AGetter = computer().wrapBeanProperty(target, property) as AGetter
return withGetter(wrapGetter)
}
fun with(target: Any, property: String, type: KClass): AutoBind2 {
return with(target, property)
}
@Suppress("UNCHECKED_CAST")
fun with(param: JTextComponent): AutoBind2 {
val wrapGetter: AGetter = computer().wrapJTextComponent(param)
return withGetter(wrapGetter)
}
@Suppress("UNCHECKED_CAST")
fun with(param: JLabel): AutoBind2 {
val wrapGetter: AGetter = computer().wrapJLabel(param)
return withGetter(wrapGetter)
}
@Suppress("UNCHECKED_CAST")
fun withIndex(param: JList<*>): AutoBind2 {
val wrapGetter: AGetter = computer().wrapJListIndexComponent(param)
return withGetter(wrapGetter)
}
fun withEnable(component: JComponent): AutoBind2 {
val wrapGetter: AGetter = computer().wrapComponentEnable(component)
return withGetter(wrapGetter)
}
fun withVisible(component: JComponent): AutoBind2 {
val wrapGetter: AGetter = computer().wrapComponentVisible(component)
return withGetter(wrapGetter)
}
fun withName(component: JComponent): AutoBind2 {
val wrapGetter: AGetter = computer().wrapComponentName(component)
return withGetter(wrapGetter)
}
fun with(component: JList<*>): AutoBind2?> {
val wrapGetter: AGetter?> = computer().wrapJListComponent(component)
return withGetter(wrapGetter)
}
fun withIndex(component: JComboBox<*>): AutoBind2 {
val wrapGetter: AGetter = computer().wrapJComboBoxIndexComponent(component)
return withGetter(wrapGetter)
}
fun with(component: JComboBox): AutoBind2 {
val wrapGetter: AGetter = computer().wrapJComboBoxComponent(component)
return withGetter(wrapGetter)
}
@Suppress("UNCHECKED_CAST")
fun withGetter(getter: AGetter): AutoBind2 {
this.core.params.add(getter as AGetter)
return AutoBind2(core)
}
override fun evalFun(exp: (P1) -> T): () -> Unit {
return {
computer().value(core.property, exp(core.params[0].get() as P1))
}
}
}
class AutoBind2 : AutoBind T?, AutoBind2> {
constructor(core: AutoBindData) : super(core)
@Suppress("UNCHECKED_CAST")
fun with(param: KProperty0
): AutoBind3 {
val wrapGetter: AGetter = computer().wrapGetter(param) as AGetter
this.core.params.add(wrapGetter)
return AutoBind3(core)
}
@Suppress("UNCHECKED_CAST")
fun with(target: Any, property: String): AutoBind3 {
val wrapGetter: AGetter = computer().wrapBeanProperty(target, property) as AGetter
this.core.params.add(wrapGetter)
return AutoBind3(core)
}
fun with(target: Any, property: String, type: KClass
): AutoBind3 {
return with(target, property)
}
@Suppress("UNCHECKED_CAST")
fun with(param: JTextComponent): AutoBind3 {
val wrapGetter: AGetter = computer().wrapJTextComponent(param)
this.core.params.add(wrapGetter as AGetter)
return AutoBind3(core)
}
@Suppress("UNCHECKED_CAST")
fun with(param: JLabel): AutoBind3 {
val wrapGetter: AGetter = computer().wrapJLabel(param)
this.core.params.add(wrapGetter as AGetter)
return AutoBind3(core)
}
@Suppress("UNCHECKED_CAST")
fun withIndex(param: JList): AutoBind3 {
val wrapGetter: AGetter = computer().wrapJListIndexComponent(param)
return withGetter(wrapGetter)
}
fun withEnable(component: JComponent): AutoBind3 {
val wrapGetter: AGetter = computer().wrapComponentEnable(component)
return withGetter(wrapGetter)
}
fun withVisible(component: JComponent): AutoBind3 {
val wrapGetter: AGetter = computer().wrapComponentVisible(component)
return withGetter(wrapGetter)
}
fun withName(component: JComponent): AutoBind3 {
val wrapGetter: AGetter = computer().wrapComponentName(component)
return withGetter(wrapGetter)
}
fun with(component: JList<*>): AutoBind3?> {
val wrapGetter: AGetter?> = computer().wrapJListComponent(component)
return withGetter(wrapGetter)
}
fun withIndex(component: JComboBox<*>): AutoBind3 {
val wrapGetter: AGetter = computer().wrapJComboBoxIndexComponent(component)
return withGetter(wrapGetter)
}
fun with(component: JComboBox): AutoBind3 {
val wrapGetter: AGetter = computer().wrapJComboBoxComponent(component)
return withGetter(wrapGetter)
}
@Suppress("UNCHECKED_CAST")
private fun withGetter(wrapGetter: AGetter): AutoBind3 {
this.core.params.add(wrapGetter as AGetter)
return AutoBind3(core)
}
@Suppress("UNCHECKED_CAST")
override fun evalFun(exp: (P1?, P2?) -> T?): () -> Unit {
return {
computer().value(
core.property,
exp(this.core.params[0].get() as P1, this.core.params[1].get() as P2)
)
}
}
}
class AutoBind3(core: AutoBindData) :
AutoBind T?, AutoBind3>(core) {
@Suppress("UNCHECKED_CAST")
override fun evalFun(exp: (P1?, P2?, P3?) -> T?): () -> Unit {
return {
computer().value(
core.property, exp(
this.core.params[0].get() as P1,
this.core.params[1].get() as P2,
this.core.params[2].get() as P3
)
)
}
}
}
class ListenAble {
private val computer: AutoComputer
private val wrapGetter: AGetter
private var filter: (Filter)? = null
constructor(computer: AutoComputer, wrapGetter: AGetter) {
this.wrapGetter = wrapGetter
this.computer = computer
}
fun throttle(cd: Long): ListenAble {
return throttle(wrapGetter to IDUtils.shortUUID(), cd)
}
fun throttle(specialKey: Any, cd: Long): ListenAble {
val throttleFilter = { computer.throttleHelper.acquire(specialKey, cd) }
mergeFilter(this::filter, throttleFilter)
return this
}
fun filter(filter: Filter): ListenAble {
mergeFilter(this::filter, filter)
return this
}
fun action(action: (T?) -> Unit) {
var buildAction = action
if (this.filter != null) {
val wrapAction = buildAction
val filter = this.filter!!
buildAction = {
if (filter()) {
wrapAction(it)
}
}
}
this.computer.singleListen(wrapGetter, buildAction)
}
}
companion object {
fun buildBind(computer: AutoComputer, property: ASetter): AutoBind0 {
val data: AutoBindData = AutoBindData(computer, property, ArrayList())
return AutoBind0(data)
}
}
}
fun KMutableProperty.safeSet(value: T?) {
if (!this.isAccessible) {
this.isAccessible = true
}
this.setter.call(value)
}
fun KProperty.safeGet(): T? {
if (!this.isAccessible) {
this.isAccessible = true
}
return this.getter.call()
}
fun KProperty.safeGet(target: Any): T? {
if (!this.isAccessible) {
this.isAccessible = true
}
return this.getter.call(target)
}
//region define interface-------------------------------------------------------
enum class Mode {
REPAINT_UI_ONLY {
/**
* allow change from data
*/
override fun allowed(getter: AGetter<*>): Boolean {
return getter is DataListener
}
/**
* allow setter of ui
*/
override fun allowed(setter: ASetter<*>): Boolean {
return setter is UIListener
}
},
UPDATE_DATA_ONLY {
/**
* allow change from ui
*/
override fun allowed(getter: AGetter<*>): Boolean {
return getter is UIListener
}
/**
* allow setter of data
*/
override fun allowed(setter: ASetter<*>): Boolean {
return setter is DataListener
}
},
ALL {
override fun allowed(getter: AGetter<*>): Boolean {
return true
}
override fun allowed(setter: ASetter<*>): Boolean {
return true
}
};
abstract fun allowed(getter: AGetter<*>): Boolean
abstract fun allowed(setter: ASetter<*>): Boolean
}
interface ASetter {
fun set(value: T?)
}
interface AGetter {
fun get(): T?
fun onListen(computer: AutoComputer) {
}
}
interface AProperty {
fun target(): Any?
fun name(): String
}
interface HasProperty {
fun getProperty(): AProperty
}
class BeanProperty : AProperty {
private var target: Any? = null
private var name: String? = null
constructor()
constructor(target: Any?, name: String?) {
this.target = target
this.name = name
}
override fun target(): Any {
return target!!
}
override fun name(): String {
return name!!
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as BeanProperty
if (target != other.target) return false
if (name != other.name) return false
return true
}
override fun hashCode(): Int {
var result = target?.hashCode() ?: 0
result = 31 * result + (name?.hashCode() ?: 0)
return result
}
override fun toString(): String {
return "BeanProperty(target=$target, name=$name)"
}
}
private interface UIListener
private interface DataListener
//endregion define interface-------------------------------------------------------
//region wraps------------------------------------------------------------------
class KMutableProperty0Wrap : ASetter, AGetter, HasProperty, DataListener {
private val actualProperty: KMutableProperty0
private val aProperty: AProperty
constructor(property: KMutableProperty0, aProperty: AProperty) {
this.actualProperty = property
this.aProperty = aProperty
}
override fun set(value: T?) {
this.actualProperty.safeSet(value)
}
override fun get(): T? {
return this.actualProperty.safeGet()
}
override fun getProperty(): AProperty {
return this.aProperty
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is HasProperty<*>) return false
if (aProperty != other.getProperty()) return false
return true
}
override fun hashCode(): Int {
return aProperty.hashCode()
}
override fun toString(): String {
return "KMutableProperty0Wrap(aProperty=$aProperty)"
}
}
class KProperty0Wrap : AGetter, HasProperty, DataListener {
private val actualProperty: KProperty0
private val aProperty: AProperty
constructor(property: KProperty0, aProperty: AProperty) {
this.actualProperty = property
this.aProperty = aProperty
}
override fun get(): T? {
return this.actualProperty.safeGet()
}
override fun getProperty(): AProperty {
return this.aProperty
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is HasProperty<*>) return false
if (aProperty != other.getProperty()) return false
return true
}
override fun hashCode(): Int {
return aProperty.hashCode()
}
}
class JTextComponentWrap : ASetter