diff --git a/library/src/main/java/renetik/android/event/registration/CSHasChangeValue.kt b/library/src/main/java/renetik/android/event/registration/CSHasChangeValue.kt index f72f63a..645d2ee 100644 --- a/library/src/main/java/renetik/android/event/registration/CSHasChangeValue.kt +++ b/library/src/main/java/renetik/android/event/registration/CSHasChangeValue.kt @@ -17,12 +17,23 @@ import kotlin.properties.Delegates.notNull interface CSHasChangeValue : CSValue, CSHasChange { companion object { - @Deprecated("Use hasChangeValue") + class DelegateValue( + var value: Return, val onChange: ArgFunc?, + val function: (Return) -> Unit + ) { + operator fun invoke(newValue: Return) { + if (value != newValue) { + value = newValue + onChange?.invoke(newValue) + function(newValue) + } + } + } + fun CSHasChangeValue.delegate( parent: CSHasRegistrations? = null, onChange: ArgFunc? = null, ): CSHasChangeValue = delegate(parent, from = { it }, onChange) - @Deprecated("Use hasChangeValue") inline fun CSHasChangeValue.delegate( parent: CSHasRegistrations? = null, crossinline from: (T) -> Return, @@ -31,20 +42,12 @@ interface CSHasChangeValue : CSValue, CSHasChange { object : CSHasChangeValue { override val value: Return get() = from(property.value) override fun onChange(function: (Return) -> Unit): CSRegistration { - var value: Return = value - return property.onChange { - val newValue = from(it) - if (value != newValue) { - value = newValue - onChange?.invoke(newValue) - function(newValue) - } - }.registerTo(parent) + val value = DelegateValue(value, onChange, function) + return property.onChange { value(from(it)) }.registerTo(parent) } } } - @Deprecated("Use hasChangeValue") inline fun Pair< CSHasChangeValue, CSHasChangeValue >.delegate( @@ -54,29 +57,14 @@ interface CSHasChangeValue : CSValue, CSHasChange { ): CSHasChangeValue = object : CSHasChangeValue { override val value: Return get() = from(first.value, second.value) override fun onChange(function: (Return) -> Unit): CSRegistration { - var value: Return = value + val value = DelegateValue(value, onChange, function) return CSRegistration( - first.onChange { - val newValue = from(it, second.value) - if (value != newValue) { - value = newValue - onChange?.invoke(newValue) - function(newValue) - } - }.registerTo(parent), - second.onChange { - val newValue = from(first.value, it) - if (value != newValue) { - value = newValue - onChange?.invoke(newValue) - function(newValue) - } - }.registerTo(parent), - ) + first.onChange { value(from(it, second.value)) }, + second.onChange { value(from(first.value, it)) }, + ).registerTo(parent) } } - @Deprecated("Use hasChangeValue") inline fun Triple, CSHasChangeValue, @@ -86,30 +74,18 @@ interface CSHasChangeValue : CSValue, CSHasChange { noinline onChange: ArgFunc? = null, ): CSHasChangeValue = object : CSHasChangeValue { override val value: Return - get() = from( - first.value, second.value, third.value - ) + get() = from(first.value, second.value, third.value) - override fun onChange(function: (Return) -> Unit) = CSRegistration( - first.onChange { - val value = from(it, second.value, third.value) - onChange?.invoke(value) - function(value) - }.registerTo(parent), - second.onChange { - val value = from(first.value, it, third.value) - onChange?.invoke(value) - function(value) - }.registerTo(parent), - third.onChange { - val value = from(first.value, second.value, it) - onChange?.invoke(value) - function(value) - }.registerTo(parent) - ) + override fun onChange(function: (Return) -> Unit): CSRegistration { + val value = DelegateValue(value, onChange, function) + return CSRegistration( + first.onChange { value(from(it, second.value, third.value)) }, + second.onChange { value(from(first.value, it, third.value)) }, + third.onChange { value(from(first.value, second.value, it)) } + ).registerTo(parent) + } } - @Deprecated("Use hasChangeValue") @JvmName("delegateChild") inline fun CSHasChangeValue.delegate( @@ -120,33 +96,22 @@ interface CSHasChangeValue : CSValue, CSHasChange { object : CSHasChangeValue { override val value: ChildValue get() = child(property.value).value override fun onChange(function: (ChildValue) -> Unit): CSRegistration { + val value = DelegateValue(value, onChange, function) var childRegistration: CSRegistration? = null - var isPaused = false val parentRegistration = property.action { parentValue -> childRegistration?.cancel() val childItem = child(parentValue) - if (childRegistration != null) childItem.also { - if (!isPaused) { - onChange?.invoke(it.value) - function(it.value) - } - } - childRegistration = childItem.onChange { childValue -> - if (!isPaused) { - onChange?.invoke(childValue) - function(childValue) - } - } + if (childRegistration != null) childItem.also { value(it.value) } + childRegistration = childItem.onChange(value::invoke) } - return CSRegistration(isActive = true, - onPause = { isPaused = true }, onResume = { isPaused = false }, - onCancel = { parentRegistration.cancel(); childRegistration?.cancel() }) - .registerTo(parent) + return CSRegistration( + { parentRegistration }, { childRegistration } + ).registerTo(parent) } } } - @Deprecated("Use hasChangeValue") + @JvmName("delegateNullable") inline fun CSHasChangeValue.delegateNullable( @@ -157,30 +122,19 @@ interface CSHasChangeValue : CSValue, CSHasChange { object : CSHasChangeValue { override val value: ChildValue? get() = child(property.value)?.value override fun onChange(function: (ChildValue?) -> Unit): CSRegistration { + val value = DelegateValue(value, onChange, function) var childRegistration: CSRegistration? = null var isInitialized = false - var isPaused = false val parentRegistration = property.action { parentValue -> childRegistration?.cancel() val childItem = child(parentValue) - if (isInitialized) childItem.also { - if (!isPaused) { - onChange?.invoke(it?.value) - function(it?.value) - } - } + if (isInitialized) childItem.also { value(it?.value) } isInitialized = true - childRegistration = childItem?.onChange { childValue -> - if (!isPaused) { - onChange?.invoke(childValue) - function(childValue) - } - } + childRegistration = childItem?.onChange(value::invoke) } - return CSRegistration(isActive = true, - onPause = { isPaused = true }, onResume = { isPaused = false }, - onCancel = { parentRegistration.cancel(); childRegistration?.cancel() }) - .registerTo(parent) + return CSRegistration( + { parentRegistration }, { childRegistration } + ).registerTo(parent) } } } diff --git a/library/src/main/java/renetik/android/event/registration/CSHasRegistrations+.kt b/library/src/main/java/renetik/android/event/registration/CSHasRegistrations+.kt index 58d7e5f..47f623a 100644 --- a/library/src/main/java/renetik/android/event/registration/CSHasRegistrations+.kt +++ b/library/src/main/java/renetik/android/event/registration/CSHasRegistrations+.kt @@ -9,11 +9,6 @@ fun CSRegistration.registerTo(registrations: CSHasRegistrations?): CSRegistratio fun CSHasRegistrations.register(registration: CSRegistration): CSRegistration = registrations.register(registration) -//@AnyThread -//fun -// Parent.register(registration: T): CSRegistration = -// this?.let { registrations.register(registration) } ?: registration - operator fun CSHasRegistrations.plus(registration: CSRegistration): CSRegistration = register(registration) diff --git a/library/src/main/java/renetik/android/event/registration/CSRegistration+.kt b/library/src/main/java/renetik/android/event/registration/CSRegistration+.kt index 2acc33a..52e3f67 100644 --- a/library/src/main/java/renetik/android/event/registration/CSRegistration+.kt +++ b/library/src/main/java/renetik/android/event/registration/CSRegistration+.kt @@ -4,6 +4,14 @@ import renetik.android.core.lang.Func import renetik.android.event.registration.CSRegistration.Companion.CSRegistration import java.io.Closeable +val CSRegistrationEmpty = object : CSRegistration { + override val isActive: Boolean = false + override val isCanceled: Boolean = false + override fun resume() = Unit + override fun pause() = Unit + override fun cancel() = Unit +} + fun CSRegistration(vararg registrations: CSRegistration?) = CSRegistration(registrations.asList()) @@ -13,6 +21,14 @@ fun CSRegistration(registrations: List) = CSRegistration( onPause = { registrations.forEach { if (it?.isActive == true) it.pause() } }, onCancel = { registrations.forEach { it?.cancel() } }) +fun CSRegistration( + vararg registrations: () -> CSRegistration?, +) = CSRegistration(isActive = true, + onPause = { registrations.forEach { it()?.pause() } }, + onResume = { registrations.forEach { it()?.resume() } }, + onCancel = { registrations.forEach { it()?.cancel() } } +) + inline fun List.paused(function: Func) { onEach { it.pause() } function() diff --git a/library/src/main/java/renetik/android/event/registration/CSRegistrationsMap.kt b/library/src/main/java/renetik/android/event/registration/CSRegistrationsMap.kt index a5e8361..c88af01 100644 --- a/library/src/main/java/renetik/android/event/registration/CSRegistrationsMap.kt +++ b/library/src/main/java/renetik/android/event/registration/CSRegistrationsMap.kt @@ -111,11 +111,6 @@ class CSRegistrationsMap(private val parent: Any) : CSRegistrations, CSHasRegist override fun pause() = registration.pause() override fun cancel() = cancel(registration) } -// return CSRegistration( -// isActive = registration.isActive, -// onResume = { registration.resume() }, -// onPause = { registration.pause() }, -// onCancel = { cancel(registration) }) } @Synchronized diff --git a/library/src/test/java/renetik/android/event/registration/CSHasChangeValueTest.kt b/library/src/test/java/renetik/android/event/registration/CSHasChangeValueTest.kt index 1a90acf..237e9a6 100644 --- a/library/src/test/java/renetik/android/event/registration/CSHasChangeValueTest.kt +++ b/library/src/test/java/renetik/android/event/registration/CSHasChangeValueTest.kt @@ -6,6 +6,8 @@ import renetik.android.core.lang.value.CSValue.Companion.value import renetik.android.core.lang.variable.plusAssign import renetik.android.event.property.CSProperty import renetik.android.event.property.CSProperty.Companion.property +import renetik.android.event.registration.CSHasChangeValue.Companion.delegate +import renetik.android.event.registration.CSHasChangeValue.Companion.delegateNullable import renetik.android.event.registration.CSHasChangeValue.Companion.hasChangeValue import renetik.android.event.registration.CSHasChangeValue.Companion.hasChangeValueNullable import renetik.android.testing.CSAssert.assert @@ -14,7 +16,7 @@ class CSHasChangeValueTest { @Test fun delegate() { val property = property(0) - val isRecorded = property.hasChangeValue(from = { it > 1 }) + val isRecorded = property.delegate(from = { it > 1 }) val isRecordedUser1 = isRecorded.hasChangeValue(from = { "$it" }) val isRecordedUser2 = isRecorded.hasChangeValue(from = { "$it" }) assert(expected = false, actual = isRecorded.value) @@ -29,7 +31,7 @@ class CSHasChangeValueTest { @Test fun delegateChild() { val property = property>>(value(property(5))) - val delegateChild = property.hasChangeValue(child = { it.value }) + val delegateChild = property.delegate(child = { it.value }) testDelegateChildProperty(property, delegateChild) } @@ -61,7 +63,7 @@ class CSHasChangeValueTest { @Test fun delegateNullableChild() { val property = property>?>(null) - val delegateChild = property.hasChangeValueNullable(child = { it?.value }) + val delegateChild = property.delegateNullable(child = { it?.value }) testDelegateNullableChildProperty(property, delegateChild) } @@ -76,20 +78,25 @@ class CSHasChangeValueTest { property: CSProperty>?>, delegateChild: CSHasChangeValue ) { - var delegateChildValue1: Int? = null - var delegateChildValue2: Int? = null - delegateChild.onChange { delegateChildValue1 = it } - delegateChild.action { delegateChildValue2 = it } - assert(expected = null, actual = delegateChildValue1) - assert(expected = null, actual = delegateChildValue2) + var delegateChildOnChangeValue: Int? = null + var delegateChildActionValue: Int? = null + val delegateChildOnChange = delegateChild.onChange { delegateChildOnChangeValue = it } + delegateChild.action { delegateChildActionValue = it } + assert(expected = null, actual = delegateChildOnChangeValue) + assert(expected = null, actual = delegateChildActionValue) property.value = value(property(7)) - assert(expected = 7, actual = delegateChildValue1) - assert(expected = 7, actual = delegateChildValue2) + assert(expected = 7, actual = delegateChildOnChangeValue) + assert(expected = 7, actual = delegateChildActionValue) property.value?.value?.value = 6 - assert(expected = 6, actual = delegateChildValue1) - assert(expected = 6, actual = delegateChildValue2) + assert(expected = 6, actual = delegateChildOnChangeValue) + assert(expected = 6, actual = delegateChildActionValue) + delegateChildOnChange.pause() + property.value?.value?.value = 5 + assert(expected = 6, actual = delegateChildOnChangeValue) + assert(expected = 5, actual = delegateChildActionValue) + delegateChildOnChange.resume() property.value = null - assert(expected = null, actual = delegateChildValue1) - assert(expected = null, actual = delegateChildValue2) + assert(expected = null, actual = delegateChildOnChangeValue) + assert(expected = null, actual = delegateChildActionValue) } }