Skip to content

Commit

Permalink
API: Shorten default displayName-s, use pretty default names for var …
Browse files Browse the repository at this point in the history
…signals and eventbus streams
  • Loading branch information
raquo committed Nov 25, 2023
1 parent 43a2da7 commit 089be16
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/com/raquo/airstream/core/Named.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ trait Named {
protected[this] var maybeDisplayName: js.UndefOr[String] = js.undefined

/** This is the method that subclasses override to preserve the user's ability to set custom display names. */
protected def defaultDisplayName: String = super.toString
protected def defaultDisplayName: String = s"${getClass.getSimpleName}@${hashCode()}"

/** Override [[defaultDisplayName]] instead of this, if you need to. */
final override def toString: String = displayName
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com/raquo/airstream/eventbus/EventBus.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import scala.util.Try
*/
class EventBus[A] extends EventSource[A] with Sink[A] with Named {

val writer: WriteBus[A] = new WriteBus[A]
val writer: WriteBus[A] = new WriteBus[A](parentDisplayName = displayName)

val events: EventStream[A] = writer.stream

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import com.raquo.airstream.common.InternalNextErrorObserver
import com.raquo.airstream.core.{EventStream, Protected, Transaction, WritableStream}
import com.raquo.ew.JsArray

class EventBusStream[A] private[eventbus] () extends WritableStream[A] with InternalNextErrorObserver[A] {
class EventBusStream[A] private[eventbus] (
parentDisplayName: => String
) extends WritableStream[A] with InternalNextErrorObserver[A] {

private val sourceStreams: JsArray[EventStream[A]] = JsArray()

Expand Down Expand Up @@ -72,4 +74,6 @@ class EventBusStream[A] private[eventbus] () extends WritableStream[A] with Inte
sourceStreams.forEach(_.removeInternalObserver(observer = this))
super.onStop()
}

override protected def defaultDisplayName: String = parentDisplayName + ".events"
}
17 changes: 12 additions & 5 deletions src/main/scala/com/raquo/airstream/eventbus/WriteBus.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import com.raquo.airstream.util.hasDuplicateTupleKeys

import scala.util.Try

class WriteBus[A] extends Observer[A] {
class WriteBus[A](
parentDisplayName: => String,
displayNameSuffix: String = ".writer"
) extends Observer[A] {

/** Hidden here because the public interface of WriteBus is all about writing
* rather than reading, but exposed in [[EventBus]]
*/
private[eventbus] val stream: EventBusStream[A] = new EventBusStream()
private[eventbus] val stream: EventBusStream[A] = new EventBusStream(displayName)

/** Note: this source will be removed when the `owner` you provide says so.
* To remove this source manually, call .kill() on the resulting Subscription.
Expand All @@ -24,19 +27,21 @@ class WriteBus[A] extends Observer[A] {
}

def contracomposeWriter[B](operator: EventStream[B] => EventStream[A])(implicit owner: Owner): WriteBus[B] = {
val mapBus = new WriteBus[B]
val mapBus = new WriteBus[B](displayName, ".contracomposeWriter")
addSource(mapBus.stream.compose(operator))(owner)
mapBus
}

/** Behaves similar to `contramap`, but gives you a WriteBus, not just an Observer */
def contramapWriter[B](project: B => A)(implicit owner: Owner): WriteBus[B] = {
contracomposeWriter[B](_.map(project))(owner)
val mapBus = new WriteBus[B](displayName, ".contramapWriter")
addSource(mapBus.stream.map(project))(owner)
mapBus
}

/** Behaves similar to `filter`, but gives you a WriteBus, not just an Observer */
def filterWriter(passes: A => Boolean)(implicit owner: Owner): WriteBus[A] = {
val filterBus = new WriteBus[A]
val filterBus = new WriteBus[A](displayName, ".filterWriter")
addSource(filterBus.stream.filter(passes))(owner)
filterBus
}
Expand Down Expand Up @@ -80,6 +85,8 @@ class WriteBus[A] extends Observer[A] {
onNextWithSharedTransaction(_, sharedTransaction)
)
}

override protected def defaultDisplayName: String = parentDisplayName + displayNameSuffix
}

object WriteBus {
Expand Down
7 changes: 5 additions & 2 deletions src/main/scala/com/raquo/airstream/state/DerivedVar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ class DerivedVar[A, B](
parent: Var[A],
zoomIn: A => B,
zoomOut: (A, B) => A,
owner: Owner
owner: Owner,
displayNameSuffix: String
) extends Var[B] {

override private[state] def underlyingVar: SourceVar[_] = parent.underlyingVar

private[this] val _varSignal = new DerivedVarSignal(parent, zoomIn, owner)
private[this] val _varSignal = new DerivedVarSignal(parent, zoomIn, owner, displayName)

// #Note this getCurrentValue implementation is different from SourceVar
// - SourceVar's getCurrentValue looks at an internal currentValue variable
Expand Down Expand Up @@ -54,4 +55,6 @@ class DerivedVar[A, B](
}

override val signal: StrictSignal[B] = _varSignal

override protected def defaultDisplayName: String = parent.displayName + displayNameSuffix
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import com.raquo.airstream.ownership.{Owner, Subscription}
class DerivedVarSignal[A, B](
parent: Var[A],
zoomIn: A => B,
owner: Owner
owner: Owner,
parentDisplayName: => String
) extends MapSignal[A, B](
parent.signal,
project = zoomIn,
Expand All @@ -18,4 +19,6 @@ class DerivedVarSignal[A, B](
override protected[state] def isStarted: Boolean = super.isStarted

override protected[this] val subscription: Subscription = this.addObserver(Observer.empty)(owner)

override protected def defaultDisplayName: String = parentDisplayName + ".signal"
}
5 changes: 4 additions & 1 deletion src/main/scala/com/raquo/airstream/state/SourceVar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ class SourceVar[A] private[state](initial: Try[A]) extends Var[A] {
private[this] var currentValue: Try[A] = initial

/** VarSignal is a private type, do not expose it */
private[this] val _varSignal = new VarSignal[A](initial = currentValue)
private[this] val _varSignal = new VarSignal[A](
initial = currentValue,
parentDisplayName = displayName
)

override private[state] def underlyingVar: SourceVar[_] = this

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com/raquo/airstream/state/Var.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ trait Var[A] extends SignalSource[A] with Sink[A] with Named {
}

def zoom[B](in: A => B)(out: (A, B) => A)(implicit owner: Owner): Var[B] = {
new DerivedVar[A, B](this, in, out, owner)
new DerivedVar[A, B](this, in, out, owner, displayNameSuffix = ".zoom")
}

def setTry(tryValue: Try[A]): Unit = writer.onTry(tryValue)
Expand Down
5 changes: 4 additions & 1 deletion src/main/scala/com/raquo/airstream/state/VarSignal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import scala.util.Try
* (see StrictSignal).
*/
private[state] class VarSignal[A] private[state](
initial: Try[A]
initial: Try[A],
parentDisplayName: => String
) extends WritableSignal[A] with StrictSignal[A] {

/** SourceVar does not directly depend on other observables, so it breaks the graph. */
Expand All @@ -31,4 +32,6 @@ private[state] class VarSignal[A] private[state](
override protected def currentValueFromParent(): Try[A] = tryNow() // noop

override protected def onWillStart(): Unit = () // noop

override protected def defaultDisplayName: String = parentDisplayName + ".signal"
}
42 changes: 42 additions & 0 deletions src/test/scala/com/raquo/airstream/DebugSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -833,4 +833,46 @@ class DebugSpec extends UnitSpec with BeforeAndAfter {

calculations.clear()
}

it("EventBus.events and Var.signal display names") {

val bus = new EventBus[Int]

assert(bus.displayName.startsWith("EventBus@"))
assertEquals(bus.events.displayName, bus.displayName + ".writer.events")

// --

bus.setDisplayName("bus")

assertEquals(bus.writer.displayName, "bus.writer")
assertEquals(bus.events.displayName, "bus.writer.events")
assertEquals(bus.writer.contramapWriter(identity[Int]).displayName, "bus.writer.contramapWriter")

// --

val _var = Var(1)
val _derived = _var.zoom(x => x)((acc, x) => x)

assert(_var.displayName.startsWith("SourceVar@"))
assertEquals(_var.signal.displayName, _var.displayName + ".signal")
assertEquals(_derived.displayName, _var.displayName + ".zoom")
assertEquals(_derived.signal.displayName, _derived.displayName + ".signal")

// --

_var.setDisplayName("var")

assertEquals(_var.displayName, "var")
assertEquals(_var.signal.displayName, "var.signal")
assertEquals(_derived.displayName, _var.displayName + ".zoom")
assertEquals(_derived.signal.displayName, _derived.displayName + ".signal")

// --

_derived.setDisplayName("zoomed")

assertEquals(_derived.displayName, "zoomed")
assertEquals(_derived.signal.displayName, _derived.displayName + ".signal")
}
}

0 comments on commit 089be16

Please sign in to comment.