Skip to content

Commit a367f17

Browse files
authored
Merge pull request #474 from UdashFramework/transform-updates
Supress non-forced updates on transformed properties
2 parents af38505 + 00cc332 commit a367f17

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed

core/src/main/scala/io/udash/properties/single/TransformedProperty.scala

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package io.udash.properties
22
package single
33

4-
import com.avsystem.commons.misc.Opt
4+
import com.avsystem.commons._
55
import io.udash.utils.Registration
66

7-
import scala.concurrent.Future
8-
97
/** Represents ReadableProperty[A] transformed to ReadableProperty[B]. */
108
private[properties] class TransformedReadableProperty[A, B](
119
override protected val origin: ReadableProperty[A],
@@ -16,15 +14,21 @@ private[properties] class TransformedReadableProperty[A, B](
1614
protected var originListenerRegistration: Registration = _
1715

1816
protected def originListener(originValue: A) : Unit = {
19-
lastValue = Opt(originValue)
20-
transformedValue = transformer(originValue)
21-
fireValueListeners()
17+
val forced = lastValue.contains(originValue) //if the listener was triggered despite equal value, the update was forced
18+
val newValue = transformer(originValue)
19+
val transformedValueChanged = newValue != transformedValue
20+
lastValue = originValue.opt
21+
transformedValue = newValue
22+
if (forced || transformedValueChanged) fireValueListeners()
2223
}
2324

2425
private def initOriginListener(): Unit = {
2526
if (originListenerRegistration == null || !originListenerRegistration.isActive) {
2627
listeners.clear()
2728
originListenerRegistration = origin.listen(originListener)
29+
val originValue = origin.get
30+
lastValue = originValue.opt
31+
lastValue.foreach(v => transformedValue = transformer(v))
2832
}
2933
}
3034

@@ -63,7 +67,7 @@ private[properties] class TransformedReadableProperty[A, B](
6367

6468
override def get: B = {
6569
val originValue = origin.get
66-
if (lastValue.isEmpty || lastValue.get != originValue) {
70+
if (originListenerRegistration == null && (lastValue.isEmpty || lastValue.get != originValue)) {
6771
lastValue = Opt(originValue)
6872
transformedValue = transformer(originValue)
6973
}

core/src/test/scala/io/udash/properties/PropertyTest.scala

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,58 @@ class PropertyTest extends UdashCoreTest {
316316
counter2 should be(1)
317317
}
318318

319+
"fire on transformed value changed or when forced" in {
320+
val origin: Property[Option[Int]] = Property(Some(0))
321+
val transformed: ReadableProperty[Boolean] = origin.transform((q: Option[Int]) => q.isDefined)
322+
var counter = 0
323+
324+
transformed.listen(_ => counter += 1)
325+
326+
origin.set(Some(0))
327+
counter shouldBe 0 //suppressed at origin
328+
329+
origin.set(Some(1))
330+
counter shouldBe 0 //suppressed at transformed
331+
332+
origin.set(None)
333+
counter shouldBe 1
334+
335+
origin.set(None)
336+
counter shouldBe 1
337+
338+
origin.set(None, force = true)
339+
counter shouldBe 2
340+
341+
origin.touch()
342+
counter shouldBe 3
343+
}
344+
345+
"fire on streamed value changed or when forced" in {
346+
val origin: Property[Option[Int]] = Property(Some(0))
347+
val target = Property.blank[Boolean]
348+
349+
origin.streamTo(target)((q: Option[Int]) => q.isDefined)
350+
var counter = 0
351+
352+
target.listen(_ => counter += 1)
353+
354+
origin.set(Some(0))
355+
counter shouldBe 0 //suppressed at origin
356+
357+
origin.set(Some(1))
358+
counter shouldBe 0 //suppressed at target
359+
360+
origin.set(None)
361+
counter shouldBe 1
362+
363+
origin.set(None)
364+
counter shouldBe 1
365+
366+
//todo detect forced / touched?
367+
//origin.set(None, force = true)
368+
//counter shouldBe 2
369+
}
370+
319371
"combine with other properties (single properties)" in {
320372
val p1 = Property(1)
321373
val p2 = Property(2)
@@ -518,7 +570,7 @@ class PropertyTest extends UdashCoreTest {
518570

519571
val p = Property("1,2,3,4,5")
520572
val s: ReadableSeqProperty[Int, ReadableProperty[Int]] =
521-
p.transformToSeq((v: String) => Try(v.split(",").map(_.toInt).toSeq).getOrElse(Seq[Int]()))
573+
p.transformToSeq((v: String) => Try(v.split(",").map(_.trim.toInt).toSeq).getOrElse(Seq[Int]()))
522574

523575
p.listenersCount() should be(0)
524576

@@ -549,6 +601,14 @@ class PropertyTest extends UdashCoreTest {
549601
lastPatch.removed.size should be(2)
550602
elementsUpdated should be(2)
551603

604+
//suppressed at s
605+
p.set(" 5 ,4 ,3")
606+
s.get should be(Seq(5, 4, 3))
607+
lastValue should be(s.get)
608+
lastPatch.added.size should be(0)
609+
lastPatch.removed.size should be(2)
610+
elementsUpdated should be(2)
611+
552612
lastValue = null
553613
lastPatch = null
554614
elementsUpdated = 0

0 commit comments

Comments
 (0)