From bde85b97d0542ee5def509f0bb435cdf23d1abba Mon Sep 17 00:00:00 2001 From: ragnar Date: Sun, 3 Mar 2024 00:47:38 +0100 Subject: [PATCH] scalafmt --- .../fullmv/mirrors/ReactiveMirror.scala | 4 +- .../github/ckuessner/aead/AeadHelper.scala | 6 +- .../com/github/ckuessner/aead/AeadTest.scala | 6 +- .../main/scala/channel/JsMessageBuffer.scala | 9 +- .../communicator/webrtc/ConnectionArea.scala | 2 +- .../main/scala/channel/tcp/TCPHandler.scala | 4 - .../DeltaAddWinsLastWriterWinsMap.scala | 11 +- .../main/scala/examples/demo/ui/Shapes.scala | 1 - .../src/main/scala/extra2023/ML.scala | 2 +- .../scala/reswing/millgame/types/Shapes.scala | 8 +- .../src/main/scala/reswing/reader/Main.scala | 2 +- .../reswing/reader/network/Fetcher.scala | 2 +- .../src/main/scala/universe/Inhabitants.scala | 1 - .../main/scala/replication/webapp/HTML.scala | 2 - .../scala/replication/calendar/Bindings.scala | 4 +- .../scala/replication/fbdc/Fortunes.scala | 1 - .../scala/replication/fbdc/Northwind.scala | 1 - .../replication/papoctokens/Tokens.scala | 6 +- .../deltaAntiEntropy/tests/AWSetTest.scala | 2 +- .../deltaAntiEntropy/tests/ORMapTest.scala | 6 +- .../main/scala/replication/fbdc/FBDC.scala | 3 +- .../reactives/todo/DeltaStateReactive.scala | 6 +- .../src/main/scala/todo/TaskData.scala | 14 +- .../src/main/scala/api2/TupleUtils.scala | 1 - .../scala/benchmarks/basic/SingleVar.scala | 8 +- .../incremental/MapBenchmarkWithInsert.scala | 2 +- .../incremental/MapBenchmarkWithRemove.scala | 3 +- .../MinBenchmarkWithInsertOfMin.scala | 2 +- .../MinBenchmarkWithInsertOfNotMin.scala | 2 +- .../MinBenchmarkWithRemoveBestCase.scala | 3 +- .../MinBenchmarkWithRemoveWorstCase.scala | 2 +- .../incremental/SizeBenchmarkWithInsert.scala | 2 +- .../incremental/SizeBenchmarkWithRemove.scala | 2 +- .../lattices/delta/crdt/MVRegisterBench.scala | 2 +- .../lattices/delta/crdt/PNCounterBench.scala | 2 +- .../benchmarks/measureSizes/ObjectSizes.scala | 1 - .../philosophers/PaperPhilosophers.scala | 1 - .../rga/DeltaLatticeSequence.scala | 2 +- .../contextual/MultiVersionRegister.scala | 2 +- .../datatypes/contextual/ReplicatedSet.scala | 6 +- .../scala/rdts/syntax/DeltaContextOps.scala | 6 +- .../RDTs/src/main/scala/rdts/time/Dots.scala | 5 +- .../test/rdts/corestructs/DotSetTest.scala | 2 +- .../scheduler/PlatformCandidates.scala | 2 +- .../src/main/scala/reactives/extra/Tags.scala | 10 +- .../scala/tests/rescala/RescalatagsTest.scala | 117 ++-- .../scala/reactives/fullmv/FullMVBundle.scala | 8 +- .../reactives/fullmv/TurnImplBundle.scala | 6 +- .../reactives/fullmv/mirrors/Mirror.scala | 100 ++-- .../reactives/fullmv/tasks/TaskBundle.scala | 433 ++++++++------- .../main/scala/reactives/locking/Key.scala | 2 +- .../scheduler/PlatformCandidates.scala | 5 +- .../core/reactor/ReactorWithoutAPITest.scala | 2 +- .../rescala/jvm/fullmv/DeframeTest.scala | 9 +- ...FullMVTurnTransitiveReachabilityTest.scala | 1 - .../jvm/fullmv/LockUnionFindTest.scala | 19 +- .../jvm/fullmv/NodeVersionHistoryTest.scala | 4 +- .../reactives/core/AdmissionTicket.scala | 7 +- .../src/main/scala/reactives/core/Core.scala | 2 - .../scala/reactives/core/ScopeSearches.scala | 2 +- .../extra/incremental/IncrementalBundle.scala | 1 - .../extra/reactor/ReactorBundle.scala | 520 +++++++++--------- .../main/scala/reactives/operator/Fold.scala | 1 - .../scala/reactives/operator/Interface.scala | 3 +- .../reactives/scheduler/CalculusLike.scala | 6 +- .../reactives/scheduler/TopoBundle.scala | 3 +- .../reactives/scheduler/Twoversion.scala | 4 +- .../reactives/structure/DerivedImpl.scala | 1 - .../main/scala/reactives/structure/Diff.scala | 3 +- .../reactives/core/tests/WithoutAPITest.scala | 6 +- .../extra/invariant/InvariantBundle.scala | 6 +- .../rescala/dynamic/TrueDynamicSignals.scala | 483 ++++++++-------- .../ExceptionPropagationTestSuite.scala | 28 +- .../misc/LightImplicitSyntaxTest.scala | 1 - .../misc/ReactiveCreationInTurnsTest.scala | 6 +- .../rescala/static/conversions/Change.scala | 307 ++++++----- .../rescala/static/events/EventTest.scala | 120 ++-- .../rescala/static/signals/SignalMacro.scala | 1 - .../tests/rescala/testtools/RETests.scala | 8 +- .../testtools/ReevaluationTracker.scala | 1 - .../SetAndExtractTransactionHandle.scala | 1 - .../rescala/testtools/TestIgnoreTags.scala | 4 +- .../src/main/scala/reswing/ReSwingValue.scala | 10 +- project/Settings.scala | 6 +- 84 files changed, 1217 insertions(+), 1201 deletions(-) diff --git a/Historical/Multiversion Distributed/multiversion/src/main/scala/rescala/fullmv/mirrors/ReactiveMirror.scala b/Historical/Multiversion Distributed/multiversion/src/main/scala/rescala/fullmv/mirrors/ReactiveMirror.scala index 382871e0d..c24b796f5 100644 --- a/Historical/Multiversion Distributed/multiversion/src/main/scala/rescala/fullmv/mirrors/ReactiveMirror.scala +++ b/Historical/Multiversion Distributed/multiversion/src/main/scala/rescala/fullmv/mirrors/ReactiveMirror.scala @@ -47,8 +47,8 @@ trait ReactiveMirrorBundle extends FullMVTurnReflectionBundle { type State[V] = self.State[V] override type Value = Nothing override protected[reactives] val state = this - override def toString: String = s"Mirror${info.description}" - override val host: FullMVEngine = null + override def toString: String = s"Mirror${info.description}" + override val host: FullMVEngine = null override def incrementFrame(txn: FullMVTurn): FramingBranchResult[FullMVTurn, Derived.of[State]] = { FullMVUtil.myAwait(txn.addRemoteBranch(TurnPhase.Framing), timeout) reflectionProxy.asyncIncrementFrame(txn) diff --git a/Modules/Aead/js/src/main/scala/com/github/ckuessner/aead/AeadHelper.scala b/Modules/Aead/js/src/main/scala/com/github/ckuessner/aead/AeadHelper.scala index e78252280..9022f78de 100644 --- a/Modules/Aead/js/src/main/scala/com/github/ckuessner/aead/AeadHelper.scala +++ b/Modules/Aead/js/src/main/scala/com/github/ckuessner/aead/AeadHelper.scala @@ -90,7 +90,8 @@ object AeadHelper { */ def encrypt(message: String, associatedData: String, key: Uint8Array): Try[Uint8Array] = Try { val nonce: Uint8Array = generateRandomNonce() - val cipherText = sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(message, associatedData, null, nonce, key, undefined) + val cipherText = + sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(message, associatedData, null, nonce, key, undefined) concatenateArrays(nonce, cipherText) } @@ -109,7 +110,8 @@ object AeadHelper { */ def encrypt(message: Uint8Array, associatedData: Uint8Array, key: Uint8Array): Try[Uint8Array] = Try { val nonce: Uint8Array = generateRandomNonce() - val cipherText = sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(message, associatedData, null, nonce, key, undefined) + val cipherText = + sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(message, associatedData, null, nonce, key, undefined) concatenateArrays(nonce, cipherText) } diff --git a/Modules/Aead/shared/src/test/scala/com/github/ckuessner/aead/AeadTest.scala b/Modules/Aead/shared/src/test/scala/com/github/ckuessner/aead/AeadTest.scala index bd8bec206..ccda2665f 100644 --- a/Modules/Aead/shared/src/test/scala/com/github/ckuessner/aead/AeadTest.scala +++ b/Modules/Aead/shared/src/test/scala/com/github/ckuessner/aead/AeadTest.scala @@ -13,11 +13,11 @@ class AeadTest extends munit.ScalaCheckSuite { implicit def executionContext: ExecutionContext = TestExecutionContext.executionContext - test("AeadHelper.ready should work"){ + test("AeadHelper.ready should work") { AeadHelper.ready().map(_ => ())(executionContext) } - test("decrypt should successfully decrypt generated byte array and empty associated data"){ + test("decrypt should successfully decrypt generated byte array and empty associated data") { val aead = AeadKey.generateKey.aeadPrimitive forAll(byteArrayGen) { (message: ByteArray) => val ciphertext = aead.encrypt(message, Generators.emptyByteArray).get @@ -35,7 +35,7 @@ class AeadTest extends munit.ScalaCheckSuite { } } - test( "should work for empty message") { + test("should work for empty message") { val aead = AeadKey.generateKey.aeadPrimitive assertEquals("", aead.decrypt(aead.encrypt("", "").get, "").get) diff --git a/Modules/Channels/js/src/main/scala/channel/JsMessageBuffer.scala b/Modules/Channels/js/src/main/scala/channel/JsMessageBuffer.scala index dcbbd10c8..e40156560 100644 --- a/Modules/Channels/js/src/main/scala/channel/JsMessageBuffer.scala +++ b/Modules/Channels/js/src/main/scala/channel/JsMessageBuffer.scala @@ -7,8 +7,9 @@ class JsArrayBufferMessageBuffer(val inner: ArrayBuffer) extends MessageBuffer { } object MesageBufferExtensions { - extension (mb: MessageBuffer) def asArrayBuffer: ArrayBuffer = - mb match - case buf: JsArrayBufferMessageBuffer => buf.inner - case other => other.asArray.toTypedArray.buffer + extension (mb: MessageBuffer) + def asArrayBuffer: ArrayBuffer = + mb match + case buf: JsArrayBufferMessageBuffer => buf.inner + case other => other.asArray.toTypedArray.buffer } diff --git a/Modules/Channels/js/src/main/scala/loci/communicator/webrtc/ConnectionArea.scala b/Modules/Channels/js/src/main/scala/loci/communicator/webrtc/ConnectionArea.scala index 8af766be2..71b8872b5 100644 --- a/Modules/Channels/js/src/main/scala/loci/communicator/webrtc/ConnectionArea.scala +++ b/Modules/Channels/js/src/main/scala/loci/communicator/webrtc/ConnectionArea.scala @@ -91,7 +91,7 @@ object Example { val selfId = Random.nextLong() Async[Ctx] { - val msg = broadcast.receive.bind + val msg = broadcast.receive.bind val communication: BroadcastCommunication = msg.convert Async[Ctx].bind: Async[Ctx].fromCallback: diff --git a/Modules/Channels/jvm/src/main/scala/channel/tcp/TCPHandler.scala b/Modules/Channels/jvm/src/main/scala/channel/tcp/TCPHandler.scala index 9406cf42a..28eeeeda9 100644 --- a/Modules/Channels/jvm/src/main/scala/channel/tcp/TCPHandler.scala +++ b/Modules/Channels/jvm/src/main/scala/channel/tcp/TCPHandler.scala @@ -21,7 +21,6 @@ def connect(host: String, port: Int): Async[Any, TCPConnection] = Async.fromCall Async.handler.fail(exception) } - class TCPConnection(socket: Socket) extends InChan with OutChan { // socket streams @@ -87,6 +86,3 @@ class TCPConnection(socket: Socket) extends InChan with OutChan { } } - - - diff --git a/Modules/Example EncryptedTodoFx/src/main/scala/encrdtlib/container/DeltaAddWinsLastWriterWinsMap.scala b/Modules/Example EncryptedTodoFx/src/main/scala/encrdtlib/container/DeltaAddWinsLastWriterWinsMap.scala index 2dbc082ab..97727fffb 100644 --- a/Modules/Example EncryptedTodoFx/src/main/scala/encrdtlib/container/DeltaAddWinsLastWriterWinsMap.scala +++ b/Modules/Example EncryptedTodoFx/src/main/scala/encrdtlib/container/DeltaAddWinsLastWriterWinsMap.scala @@ -33,10 +33,13 @@ class DeltaAddWinsLastWriterWinsMap[K, V]( def put(key: K, value: V): Unit = mutate( - DeltaAddWinsMap.deltaMutate[K, Map[Dot, ( - V, - LastWriterWins[Uid] - )]]( + DeltaAddWinsMap.deltaMutate[K, Map[ + Dot, + ( + V, + LastWriterWins[Uid] + ) + ]]( key, Map.empty, delta => diff --git a/Modules/Example Misc 2015/src/main/scala/examples/demo/ui/Shapes.scala b/Modules/Example Misc 2015/src/main/scala/examples/demo/ui/Shapes.scala index b7174d81e..e7d4e37dc 100644 --- a/Modules/Example Misc 2015/src/main/scala/examples/demo/ui/Shapes.scala +++ b/Modules/Example Misc 2015/src/main/scala/examples/demo/ui/Shapes.scala @@ -6,7 +6,6 @@ import reactives.core.AdmissionTicket import reactives.default.* import reactives.default.global.State as BundleState - trait Shape extends Serializable { val changed: Event[Any] val centerX: Signal[Int] diff --git a/Modules/Example Misc 2015/src/main/scala/extra2023/ML.scala b/Modules/Example Misc 2015/src/main/scala/extra2023/ML.scala index 4593dd558..1db62812f 100644 --- a/Modules/Example Misc 2015/src/main/scala/extra2023/ML.scala +++ b/Modules/Example Misc 2015/src/main/scala/extra2023/ML.scala @@ -81,7 +81,7 @@ object MLTest { val backwardsPropagate = Signal(true) val groundTruth = Signal { math.pow(2 * input.value - 3.0, 2) } val learn_rate = Signal { 0.4 } - val res = diff_app(input, backwardsPropagate, groundTruth, learn_rate) + val res = diff_app(input, backwardsPropagate, groundTruth, learn_rate) println(res.now) } } diff --git a/Modules/Example Misc 2015/src/main/scala/reswing/millgame/types/Shapes.scala b/Modules/Example Misc 2015/src/main/scala/reswing/millgame/types/Shapes.scala index 0f067f388..0b3ee90ff 100644 --- a/Modules/Example Misc 2015/src/main/scala/reswing/millgame/types/Shapes.scala +++ b/Modules/Example Misc 2015/src/main/scala/reswing/millgame/types/Shapes.scala @@ -42,10 +42,10 @@ case class Point[@specialized(Int, Double) T: Numeric](x: T, y: T) extends Shape def *(d: T) = Point(x * d, y * d) def /(d: Double) = Point(x.toDouble / d, y.toDouble / d) - def euclidian = math.sqrt((x * x + y * y).toDouble) - def normalize = if (x == 0 && y == 0) this else this / euclidian - infix def distance(p: Point[T]) = (p - this).euclidian - def directionTo(p: Point[T]) = (p - this).normalize + def euclidian = math.sqrt((x * x + y * y).toDouble) + def normalize = if (x == 0 && y == 0) this else this / euclidian + infix def distance(p: Point[T]) = (p - this).euclidian + def directionTo(p: Point[T]) = (p - this).normalize } // diff --git a/Modules/Example Misc 2015/src/main/scala/reswing/reader/Main.scala b/Modules/Example Misc 2015/src/main/scala/reswing/reader/Main.scala index b5c9ce638..f95e51d95 100644 --- a/Modules/Example Misc 2015/src/main/scala/reswing/reader/Main.scala +++ b/Modules/Example Misc 2015/src/main/scala/reswing/reader/Main.scala @@ -28,7 +28,7 @@ object Main extends App { store, (store.itemAdded map { (x: RSSItem) => // #EF (x.srcChannel map (_.title) getOrElse "") + ": " + x.title - }) `hold` "", // #IF + }) `hold` "", // #IF Signal.dynamic { // #SIG val itemCount = (store.channels.value map { case (_, items) => items.value.size }).sum "Channels: " + store.channels.value.size + " Items: " + itemCount diff --git a/Modules/Example Misc 2015/src/main/scala/reswing/reader/network/Fetcher.scala b/Modules/Example Misc 2015/src/main/scala/reswing/reader/network/Fetcher.scala index ea096169a..bfa94ec3c 100644 --- a/Modules/Example Misc 2015/src/main/scala/reswing/reader/network/Fetcher.scala +++ b/Modules/Example Misc 2015/src/main/scala/reswing/reader/network/Fetcher.scala @@ -17,7 +17,7 @@ import reactives.default._ class Fetcher(val urls: Signal[Set[URL]]) { lazy val rssFetched: Event[(NodeSeq, URL)] = fetch.after map { (_: (URL, NodeSeq)).swap } // #EVT //#EF lazy val state: Signal[String] = // #SIG - ((fetch.before map { (_: Any) => "Started fetching" }) || // #EF //#EF + ((fetch.before map { (_: Any) => "Started fetching" }) || // #EF //#EF (fetch.after map { (_: Any) => "Finished fetching" })) `hold` "" // #EF //#IF val firstFetchInitiated = collection.mutable.Set.empty[URL] diff --git a/Modules/Example Misc 2015/src/main/scala/universe/Inhabitants.scala b/Modules/Example Misc 2015/src/main/scala/universe/Inhabitants.scala index 993777cca..861e4dbd9 100644 --- a/Modules/Example Misc 2015/src/main/scala/universe/Inhabitants.scala +++ b/Modules/Example Misc 2015/src/main/scala/universe/Inhabitants.scala @@ -4,7 +4,6 @@ import universe.Animal._ import reactives.default.* - class Carnivore(implicit world: World) extends Animal { private val sleepy = energy map { _ < Animal.SleepThreshold } diff --git a/Modules/Example Replication/js/src/main/scala/replication/webapp/HTML.scala b/Modules/Example Replication/js/src/main/scala/replication/webapp/HTML.scala index 581c80385..0c52f3400 100644 --- a/Modules/Example Replication/js/src/main/scala/replication/webapp/HTML.scala +++ b/Modules/Example Replication/js/src/main/scala/replication/webapp/HTML.scala @@ -88,7 +88,6 @@ object HTML { def providers(exdat: FbdcExampleData) = { div( h1("make a request"), - ).render.reattach( exdat.providers.map { prov => prov.observeRemoveMap.entries.map { (id, provided) => @@ -114,7 +113,6 @@ object HTML { } } ), - ).render.reattach(exdat.latestFortune.map(f => p(f.map(_.result).getOrElse("")).render)) def northwindBox(exdat: FbdcExampleData, id: Uid) = diff --git a/Modules/Example Replication/jvm/src/main/scala/replication/calendar/Bindings.scala b/Modules/Example Replication/jvm/src/main/scala/replication/calendar/Bindings.scala index 9081d845a..43fbe4c3b 100644 --- a/Modules/Example Replication/jvm/src/main/scala/replication/calendar/Bindings.scala +++ b/Modules/Example Replication/jvm/src/main/scala/replication/calendar/Bindings.scala @@ -18,8 +18,8 @@ object SyncMessage { case class AppointmentMessage(state: CalendarState, target: String) extends SyncMessage case class RaftMessage(state: RaftState[Token]) extends SyncMessage - case class WantMessage(state: Dotted[ReplicatedSet[Token]]) extends SyncMessage - case class FreeMessage(state: Dotted[ReplicatedSet[Token]]) extends SyncMessage + case class WantMessage(state: Dotted[ReplicatedSet[Token]]) extends SyncMessage + case class FreeMessage(state: Dotted[ReplicatedSet[Token]]) extends SyncMessage } diff --git a/Modules/Example Replication/jvm/src/main/scala/replication/fbdc/Fortunes.scala b/Modules/Example Replication/jvm/src/main/scala/replication/fbdc/Fortunes.scala index ad15bb8c5..9189abd9d 100644 --- a/Modules/Example Replication/jvm/src/main/scala/replication/fbdc/Fortunes.scala +++ b/Modules/Example Replication/jvm/src/main/scala/replication/fbdc/Fortunes.scala @@ -3,7 +3,6 @@ package replication.fbdc import de.rmgk.script.{process, runOutput} import rdts.datatypes.LastWriterWins - object Fortunes { def enableConditional(exampleData: FbdcExampleData) = { diff --git a/Modules/Example Replication/jvm/src/main/scala/replication/fbdc/Northwind.scala b/Modules/Example Replication/jvm/src/main/scala/replication/fbdc/Northwind.scala index b6cc1a1e3..988e88ba4 100644 --- a/Modules/Example Replication/jvm/src/main/scala/replication/fbdc/Northwind.scala +++ b/Modules/Example Replication/jvm/src/main/scala/replication/fbdc/Northwind.scala @@ -9,7 +9,6 @@ import java.util.Properties import scala.collection.mutable.ListBuffer import scala.util.chaining.scalaUtilChainingOps - object Northwind { val dbProperties = new Properties().tap(_.setProperty("immutable", "1")) diff --git a/Modules/Example Replication/jvm/src/main/scala/replication/papoctokens/Tokens.scala b/Modules/Example Replication/jvm/src/main/scala/replication/papoctokens/Tokens.scala index 65e8bdeaf..baeccd79e 100644 --- a/Modules/Example Replication/jvm/src/main/scala/replication/papoctokens/Tokens.scala +++ b/Modules/Example Replication/jvm/src/main/scala/replication/papoctokens/Tokens.scala @@ -110,16 +110,16 @@ object Voting { } - case class Exclusive[T: Lattice: Bottom](token: Token, value: T) { def transform(f: T => T)(using ReplicaId) = if token.isOwner then f(value) else Bottom.empty } - /** totally not incredibly inefficient */ case class Causal[T: Lattice: HasDots: Bottom](deltas: Set[Dotted[T]]) { def value: T = val causalPrefix = deltas.map(_.context).reduceOption(_ union _).map(_.causalPrefix).getOrElse(Dots.empty) - deltas.filter(delta => delta.context <= causalPrefix).reduceOption(Dotted.lattice.merge).map(_.data).getOrElse(Bottom.empty) + deltas.filter(delta => delta.context <= causalPrefix).reduceOption(Dotted.lattice.merge).map(_.data).getOrElse( + Bottom.empty + ) } diff --git a/Modules/Example Replication/jvm/src/test/scala/deltaAntiEntropy/tests/AWSetTest.scala b/Modules/Example Replication/jvm/src/test/scala/deltaAntiEntropy/tests/AWSetTest.scala index 203dccca3..caa0ab1ab 100644 --- a/Modules/Example Replication/jvm/src/test/scala/deltaAntiEntropy/tests/AWSetTest.scala +++ b/Modules/Example Replication/jvm/src/test/scala/deltaAntiEntropy/tests/AWSetTest.scala @@ -46,7 +46,7 @@ class AWSetTest extends munit.ScalaCheckSuite { implicit val IntCodec: JsonValueCodec[Int] = JsonCodecMaker.make property("add") { forAll { (set: AntiEntropyContainer[ReplicatedSet[Int]], e: Int) => - given ReplicaId = set.replicaID + given ReplicaId = set.replicaID val added: AntiEntropyContainer[ReplicatedSet[Int]] = set.add(e) val elems = added.elements diff --git a/Modules/Example Replication/jvm/src/test/scala/deltaAntiEntropy/tests/ORMapTest.scala b/Modules/Example Replication/jvm/src/test/scala/deltaAntiEntropy/tests/ORMapTest.scala index ce5f87722..82b142729 100644 --- a/Modules/Example Replication/jvm/src/test/scala/deltaAntiEntropy/tests/ORMapTest.scala +++ b/Modules/Example Replication/jvm/src/test/scala/deltaAntiEntropy/tests/ORMapTest.scala @@ -18,9 +18,9 @@ class ORMapTest extends munit.ScalaCheckSuite { given rdts.syntax.ReplicaId = rdts.syntax.ReplicaId.predefined("test") given Bottom[Int] with def empty = Int.MinValue - forAll{ (entries: List[Int]) => - val orMap = entries.foldLeft(Dotted(ObserveRemoveMap.empty[Int, Int])) {(curr, elem) => curr.update(elem, elem)} - orMap.entries.foreach{(k, v) => + forAll { (entries: List[Int]) => + val orMap = entries.foldLeft(Dotted(ObserveRemoveMap.empty[Int, Int])) { (curr, elem) => curr.update(elem, elem) } + orMap.entries.foreach { (k, v) => assert(orMap.contains(k)) } } diff --git a/Modules/Example Replication/shared/src/main/scala/replication/fbdc/FBDC.scala b/Modules/Example Replication/shared/src/main/scala/replication/fbdc/FBDC.scala index 126647354..dc11e5cae 100644 --- a/Modules/Example Replication/shared/src/main/scala/replication/fbdc/FBDC.scala +++ b/Modules/Example Replication/shared/src/main/scala/replication/fbdc/FBDC.scala @@ -44,10 +44,9 @@ class Focus[Inner: DottedLattice, Outer](dm: DataManager[Outer])(extract: Outer type RespValue = Option[LastWriterWins[Res]] given Ordering[VectorClock] = VectorClock.vectorClockTotalOrdering -given HasDots[RespValue] = HasDots.noDots +given HasDots[RespValue] = HasDots.noDots given DottedLattice[RespValue] = Dotted.lattice - case class State( requests: CausalQueue[Req], responses: ObserveRemoveMap[String, RespValue], diff --git a/Modules/Example Todolist/src/main/scala/reactives/todo/DeltaStateReactive.scala b/Modules/Example Todolist/src/main/scala/reactives/todo/DeltaStateReactive.scala index bcf43c308..e8c258b77 100644 --- a/Modules/Example Todolist/src/main/scala/reactives/todo/DeltaStateReactive.scala +++ b/Modules/Example Todolist/src/main/scala/reactives/todo/DeltaStateReactive.scala @@ -4,7 +4,6 @@ import reactives.core.{CreationTicket, Derived, DynamicTicket, ReInfo, ReadAs} import reactives.default.* import reactives.default.global.State as BundleState - case class DeltaWithState[Delta, DState](delta: Seq[Delta], state: DState) class DeltaStateReactive[Delta, Combined]( @@ -42,7 +41,8 @@ object DeltaStateReactive { applyDelta: (DState, Delta) => DState, handlers: Seq[(DynamicTicket[BundleState], DState) => Delta] )(implicit name: ReInfo, creationTicket: CreationTicket[BundleState]): DeltaStateReactive[Delta, DState] = - creationTicket.scope.create(Set(deltaInput), DeltaWithState(List.empty[Delta], init), needsReevaluation = false)(state => - new DeltaStateReactive(state, deltaInput, applyDelta, handlers, name) + creationTicket.scope.create(Set(deltaInput), DeltaWithState(List.empty[Delta], init), needsReevaluation = false)( + state => + new DeltaStateReactive(state, deltaInput, applyDelta, handlers, name) ) } diff --git a/Modules/Example Todolist/src/main/scala/todo/TaskData.scala b/Modules/Example Todolist/src/main/scala/todo/TaskData.scala index 3ea8d0454..efb277e06 100644 --- a/Modules/Example Todolist/src/main/scala/todo/TaskData.scala +++ b/Modules/Example Todolist/src/main/scala/todo/TaskData.scala @@ -35,7 +35,7 @@ case class TaskRef(id: String) { lazy val cached: TaskRefData = TaskReferences.lookupOrCreateTaskRef(id, None) def task: Signal[DeltaBuffer[Dotted[LastWriterWins[Option[TaskData]]]]] = cached.task - def tag: LI = cached.tag + def tag: LI = cached.tag def removed: Event[String] = cached.removed } @@ -88,7 +88,12 @@ class TaskReferences(toggleAll: Event[dom.Event], storePrefix: String) { else DeltaBuffer(Dotted(LastWriterWins.now(task))) val edittext: Event.CBR[dom.Event, dom.html.Input] = Event.fromCallback { - input(`class` := "edit", `type` := "text", onchange := Event.handle[dom.Event], onblur := Event.handle[dom.Event]).render + input( + `class` := "edit", + `type` := "text", + onchange := Event.handle[dom.Event], + onblur := Event.handle[dom.Event] + ).render } val edittextStr = edittext.event.map { (e: dom.Event) => @@ -125,7 +130,7 @@ class TaskReferences(toggleAll: Event[dom.Event], storePrefix: String) { val removeButton = Event.fromCallback(button(`class` := "destroy", onclick := Event.handle)) - val editInput = edittext.data.reattach(Signal{ value := taskData.value.desc}) + val editInput = edittext.data.reattach(Signal { value := taskData.value.desc }) editDiv.event.observe { _ => setTimeout(0) { editInput.focus() }; () } @@ -143,7 +148,7 @@ class TaskReferences(toggleAll: Event[dom.Event], storePrefix: String) { removeButton.data ), editInput - ).render.reattach(Signal{ + ).render.reattach(Signal { `class` := (if editingV.value then "editing" else "no-editing") }) @@ -158,7 +163,6 @@ given RangeSplice[Modifier] with { case elem: dom.Element => value.applyTo(elem) } - implicit def optionAttrValue[T](implicit ev: AttrValue[T]): AttrValue[Option[T]] = new AttrValue[Option[T]] { override def apply(t: Element, a: Attr, v: Option[T]): Unit = { diff --git a/Modules/Graph-Compiler/src/main/scala/api2/TupleUtils.scala b/Modules/Graph-Compiler/src/main/scala/api2/TupleUtils.scala index e041c1e8c..d04ee08a0 100644 --- a/Modules/Graph-Compiler/src/main/scala/api2/TupleUtils.scala +++ b/Modules/Graph-Compiler/src/main/scala/api2/TupleUtils.scala @@ -4,7 +4,6 @@ import reactives.core.StaticTicket import reactives.default.* import reactives.default.global.State as BundleState - type CEventsFromEvents[T <: Tuple] <: Tuple = T match case EmptyTuple => EmptyTuple case Event[t] *: ts => CEvent[t] *: CEventsFromEvents[ts] diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/basic/SingleVar.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/basic/SingleVar.scala index df8e82443..3dcc1595f 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/basic/SingleVar.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/basic/SingleVar.scala @@ -9,7 +9,6 @@ import java.util.concurrent.TimeUnit import java.util.concurrent.locks.{ReadWriteLock, ReentrantReadWriteLock} import reactives.default.global.State as BundleState - @BenchmarkMode(Array(Mode.Throughput)) @OutputTimeUnit(TimeUnit.MILLISECONDS) @Warmup(iterations = 3, time = 1000, timeUnit = TimeUnit.MILLISECONDS) @@ -19,8 +18,8 @@ import reactives.default.global.State as BundleState @State(Scope.Benchmark) class SingleVar { - var engine: Interface = scala.compiletime.uninitialized - final lazy val engineT = engine + var engine: Interface = scala.compiletime.uninitialized + final lazy val engineT = engine implicit def scheduler: Scheduler[engineT.global.State] = engineT.global.scheduler var source: engineT.Var[Boolean] = scala.compiletime.uninitialized @@ -32,7 +31,8 @@ class SingleVar { engine = engineParam.engine current = false source = engineT.Var(current) - if (engineParam.engine.global.scheduler == reactives.scheduler.LevelbasedVariants.unmanaged) lock = new ReentrantReadWriteLock() + if (engineParam.engine.global.scheduler == reactives.scheduler.LevelbasedVariants.unmanaged) + lock = new ReentrantReadWriteLock() } @Benchmark diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MapBenchmarkWithInsert.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MapBenchmarkWithInsert.scala index 458a4fc00..ec5f766c9 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MapBenchmarkWithInsert.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MapBenchmarkWithInsert.scala @@ -24,7 +24,7 @@ class MapBenchmarkWithInsert { var addEvent: Evt[Int] = scala.compiletime.uninitialized var mappedSeq: Signal[Seq[Int]] = scala.compiletime.uninitialized - var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized + var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized var reactMappedSeq: ReactiveDeltaSeq[Int] = scala.compiletime.uninitialized @Setup(Level.Invocation) diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MapBenchmarkWithRemove.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MapBenchmarkWithRemove.scala index a609ca646..025ef4226 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MapBenchmarkWithRemove.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MapBenchmarkWithRemove.scala @@ -2,7 +2,6 @@ package benchmarks.incremental import org.openjdk.jmh.annotations._ import org.openjdk.jmh.infra.Blackhole - import reactives.default.* import reactives.extra.incremental.* @@ -26,7 +25,7 @@ class MapBenchmarkWithRemove { var removeEvent: Evt[Int] = scala.compiletime.uninitialized var mappedSeq: Signal[Seq[Int]] = scala.compiletime.uninitialized - var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized + var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized var reactMappedSeq: ReactiveDeltaSeq[Int] = scala.compiletime.uninitialized @Setup(Level.Invocation) diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithInsertOfMin.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithInsertOfMin.scala index cabae39de..035cc6ffd 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithInsertOfMin.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithInsertOfMin.scala @@ -25,7 +25,7 @@ class MinBenchmarkWithInsertOfMin { var addEvent: Evt[Int] = scala.compiletime.uninitialized var minOfSeq: Signal[Int] = scala.compiletime.uninitialized - var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized + var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized var reactMinOfSeq: Signal[Option[Int]] = scala.compiletime.uninitialized @Setup(Level.Invocation) diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithInsertOfNotMin.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithInsertOfNotMin.scala index def205df9..d7faf960b 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithInsertOfNotMin.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithInsertOfNotMin.scala @@ -24,7 +24,7 @@ class MinBenchmarkWithInsertOfNotMin { var addEvent: Evt[Int] = scala.compiletime.uninitialized var minOfSeq: Signal[Int] = scala.compiletime.uninitialized - var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized + var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized var reactMinOfSeq: Signal[Option[Int]] = scala.compiletime.uninitialized @Setup(Level.Invocation) diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithRemoveBestCase.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithRemoveBestCase.scala index e20f34265..e9f2161cc 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithRemoveBestCase.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithRemoveBestCase.scala @@ -2,7 +2,6 @@ package benchmarks.incremental import org.openjdk.jmh.annotations._ import org.openjdk.jmh.infra.Blackhole - import reactives.default.* import reactives.extra.incremental.* @@ -26,7 +25,7 @@ class MinBenchmarkWithRemoveBestCase { var removeEvent: Evt[Int] = scala.compiletime.uninitialized var minOfSeq: Signal[Int] = scala.compiletime.uninitialized - var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized + var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized var reactMinOfSeq: Signal[Option[Int]] = scala.compiletime.uninitialized @Setup(Level.Invocation) diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithRemoveWorstCase.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithRemoveWorstCase.scala index 9a0042f9d..d1198831b 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithRemoveWorstCase.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/MinBenchmarkWithRemoveWorstCase.scala @@ -24,7 +24,7 @@ class MinBenchmarkWithRemoveWorstCase { var removeEvent: Evt[Int] = scala.compiletime.uninitialized var minOfSeq: Signal[Int] = scala.compiletime.uninitialized - var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized + var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized var reactMinOfSeq: Signal[Option[Int]] = scala.compiletime.uninitialized @Setup(Level.Invocation) diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/SizeBenchmarkWithInsert.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/SizeBenchmarkWithInsert.scala index 87f5a56a2..a900e35c8 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/SizeBenchmarkWithInsert.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/SizeBenchmarkWithInsert.scala @@ -24,7 +24,7 @@ class SizeBenchmarkWithInsert { var addEvent: Evt[Int] = scala.compiletime.uninitialized var sizeOfSeq: Signal[Int] = scala.compiletime.uninitialized - var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized + var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized var sizeOfReactSeq: Signal[Int] = scala.compiletime.uninitialized @Setup(Level.Invocation) diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/SizeBenchmarkWithRemove.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/SizeBenchmarkWithRemove.scala index cf117c130..ce7b834f3 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/SizeBenchmarkWithRemove.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/incremental/SizeBenchmarkWithRemove.scala @@ -24,7 +24,7 @@ class SizeBenchmarkWithRemove { var removeEvent: Evt[Int] = scala.compiletime.uninitialized var sizeOfSeq: Signal[Int] = scala.compiletime.uninitialized - var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized + var reactSeq: IncSeq[Int] = scala.compiletime.uninitialized var sizeOfReactSeq: Signal[Int] = scala.compiletime.uninitialized @Setup(Level.Invocation) diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/lattices/delta/crdt/MVRegisterBench.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/lattices/delta/crdt/MVRegisterBench.scala index 1edb4469d..773bffbba 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/lattices/delta/crdt/MVRegisterBench.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/lattices/delta/crdt/MVRegisterBench.scala @@ -28,7 +28,7 @@ class MVRegisterBench { reg = (0 until numWrites).foldLeft(NamedDeltaBuffer.dotted("-1", MultiVersionRegister.empty[Int])) { case (r, i) => given rid: rdts.syntax.ReplicaId = i.toString.asId - val delta = Dotted(MultiVersionRegister.empty[Int]).write(i) + val delta = Dotted(MultiVersionRegister.empty[Int]).write(i) r.applyDelta(rid.uid, delta) } } diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/lattices/delta/crdt/PNCounterBench.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/lattices/delta/crdt/PNCounterBench.scala index 4934bf531..a60c303a3 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/lattices/delta/crdt/PNCounterBench.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/lattices/delta/crdt/PNCounterBench.scala @@ -25,7 +25,7 @@ class PNCounterBench { counter = (1 until numReplicas).foldLeft(NamedDeltaBuffer("0", PosNegCounter.zero).inc()(using "0".asId)) { case (c, n) => given rid: rdts.syntax.ReplicaId = rdts.base.Uid.predefined(n.toString) - val delta = PosNegCounter.zero.inc() + val delta = PosNegCounter.zero.inc() c.applyDelta(rid.uid, delta) } } diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/measureSizes/ObjectSizes.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/measureSizes/ObjectSizes.scala index af60a2b4e..7a17ff4c6 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/measureSizes/ObjectSizes.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/measureSizes/ObjectSizes.scala @@ -22,7 +22,6 @@ object ObjectSizes { measure("default empty signal", reactives.default.Signal {}) measure("default empty signal x 10", List.fill(100)(reactives.default.Signal {})) - def ptx = new ParRPDefault.ParRPTransaction(new reactives.parrp.Backoff(), None) measure("transaction", List.fill(100)(ptx)) measure( diff --git a/Modules/Microbenchmarks/src/main/scala/benchmarks/philosophers/PaperPhilosophers.scala b/Modules/Microbenchmarks/src/main/scala/benchmarks/philosophers/PaperPhilosophers.scala index 79c3a92fa..d7bb78b75 100644 --- a/Modules/Microbenchmarks/src/main/scala/benchmarks/philosophers/PaperPhilosophers.scala +++ b/Modules/Microbenchmarks/src/main/scala/benchmarks/philosophers/PaperPhilosophers.scala @@ -5,7 +5,6 @@ import reactives.operator.Interface import reactives.parrp.Backoff import reactives.default.global.State as BundleState - import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.{Executors, ThreadLocalRandom} import scala.annotation.tailrec diff --git a/Modules/RDTs/src/main/scala/rdts/datatypes/alternatives/rga/DeltaLatticeSequence.scala b/Modules/RDTs/src/main/scala/rdts/datatypes/alternatives/rga/DeltaLatticeSequence.scala index c202ae530..3d16b176d 100644 --- a/Modules/RDTs/src/main/scala/rdts/datatypes/alternatives/rga/DeltaLatticeSequence.scala +++ b/Modules/RDTs/src/main/scala/rdts/datatypes/alternatives/rga/DeltaLatticeSequence.scala @@ -136,7 +136,7 @@ object DeltaSequence { else merged.addRightEdge(oldPositions(v), v) } val vertices = left.vertices merge right.vertices - val values = Lattice.merge(left.values, right.values)(using Lattice.mapLattice(using Lattice.assertNoConflicts)) + val values = Lattice.merge(left.values, right.values)(using Lattice.mapLattice(using Lattice.assertNoConflicts)) DeltaSequence( vertices = vertices, diff --git a/Modules/RDTs/src/main/scala/rdts/datatypes/contextual/MultiVersionRegister.scala b/Modules/RDTs/src/main/scala/rdts/datatypes/contextual/MultiVersionRegister.scala index dbb67c46c..70bc201ab 100644 --- a/Modules/RDTs/src/main/scala/rdts/datatypes/contextual/MultiVersionRegister.scala +++ b/Modules/RDTs/src/main/scala/rdts/datatypes/contextual/MultiVersionRegister.scala @@ -22,7 +22,7 @@ object MultiVersionRegister { else throw IllegalStateException(s"assumed equality does not hold for »$l« and »$r« ") // we could replace this by casting … def assertEqualsOrdering[A]: Ordering[A] = _assertEqualsOrdering.on(identity) - def assertEqualsLattice[A]: Lattice[A] = Lattice.fromOrdering(using assertEqualsOrdering) + def assertEqualsLattice[A]: Lattice[A] = Lattice.fromOrdering(using assertEqualsOrdering) given dottedLattice[A]: Lattice[MultiVersionRegister[A]] = given Lattice[A] = Lattice.fromOrdering(using assertEqualsOrdering) diff --git a/Modules/RDTs/src/main/scala/rdts/datatypes/contextual/ReplicatedSet.scala b/Modules/RDTs/src/main/scala/rdts/datatypes/contextual/ReplicatedSet.scala index 5f4da7ed9..486005091 100644 --- a/Modules/RDTs/src/main/scala/rdts/datatypes/contextual/ReplicatedSet.scala +++ b/Modules/RDTs/src/main/scala/rdts/datatypes/contextual/ReplicatedSet.scala @@ -34,11 +34,11 @@ object ReplicatedSet { Dotted(current, dots).add(using rid)(e)(using Dotted.syntaxPermissions) def removeElem(using rid: ReplicaId, dots: Dots, isQuery: IsQuery)(e: E): Dotted[ReplicatedSet[E]] = - Dotted(current, dots).remove(using Dotted.syntaxPermissions, Dotted.syntaxPermissions)(e) + Dotted(current, dots).remove(using Dotted.syntaxPermissions, Dotted.syntaxPermissions)(e) def add(using ReplicaId)(e: E): CausalMutator = { - val dm = current.inner - val nextDot = context.nextDot(replicaId) + val dm = current.inner + val nextDot = context.nextDot(replicaId) val v: Dots = dm.getOrElse(e, Dots.empty) deltaState( diff --git a/Modules/RDTs/src/main/scala/rdts/syntax/DeltaContextOps.scala b/Modules/RDTs/src/main/scala/rdts/syntax/DeltaContextOps.scala index 95af06aa0..6d785b8cc 100644 --- a/Modules/RDTs/src/main/scala/rdts/syntax/DeltaContextOps.scala +++ b/Modules/RDTs/src/main/scala/rdts/syntax/DeltaContextOps.scala @@ -63,9 +63,9 @@ trait OpsTypes[DeltaContainer, Value] { final type IdMutator = ReplicaId ?=> Mutator } class OpsSyntaxHelper[C, L](container: C) extends OpsTypes[C, L] { - final protected[rdts] def current(using perm: IsQuery): L = perm.query(container) - final protected[rdts] def replicaId(using perm: ReplicaId): Uid = perm.uid - final protected[rdts] def context(using perm: IsCausalMutator): Dots = perm.context(container) + final protected[rdts] def current(using perm: IsQuery): L = perm.query(container) + final protected[rdts] def replicaId(using perm: ReplicaId): Uid = perm.uid + final protected[rdts] def context(using perm: IsCausalMutator): Dots = perm.context(container) extension (l: L) def mutator: Mutator = summon[IsMutator].mutate(container, l) extension (l: Dotted[L])(using perm: IsCausalMutator) def mutator: C = perm.mutateContext(container, l) extension [A](a: A) def inheritContext(using IsCausalMutator): Dotted[A] = Dotted(a, context) diff --git a/Modules/RDTs/src/main/scala/rdts/time/Dots.scala b/Modules/RDTs/src/main/scala/rdts/time/Dots.scala index c06c12b7d..2dd25fc21 100644 --- a/Modules/RDTs/src/main/scala/rdts/time/Dots.scala +++ b/Modules/RDTs/src/main/scala/rdts/time/Dots.scala @@ -127,14 +127,13 @@ object Dots { override def lteq(x: Dots, y: Dots): Boolean = x <= y } - given HasDots[Dots] with { extension (dotted: Dots) def dots: Dots = dotted /** Removes dots and anything associated to them from the value. - * In case the value becomes fully “empty” returns None - */ + * In case the value becomes fully “empty” returns None + */ def removeDots(dots: Dots): Option[Dots] = val res = dotted.diff(dots) if res.isEmpty then None else Some(res) diff --git a/Modules/RDTs/src/test/scala/test/rdts/corestructs/DotSetTest.scala b/Modules/RDTs/src/test/scala/test/rdts/corestructs/DotSetTest.scala index 92e46496d..98b58b5bf 100644 --- a/Modules/RDTs/src/test/scala/test/rdts/corestructs/DotSetTest.scala +++ b/Modules/RDTs/src/test/scala/test/rdts/corestructs/DotSetTest.scala @@ -131,7 +131,7 @@ class DotSetTest extends munit.ScalaCheckSuite { forAll { (ds: Dots, deleted: Dots) => val cc = ds union deleted - val decomposed = Dotted(ds, cc).decomposed + val decomposed = Dotted(ds, cc).decomposed val Dotted(dsMerged, ccMerged) = decomposed.foldLeft(Dotted.empty[Dots]) { _ merge _ } assertEquals( diff --git a/Modules/Reactives/js-native/src/main/scala/reactives/scheduler/PlatformCandidates.scala b/Modules/Reactives/js-native/src/main/scala/reactives/scheduler/PlatformCandidates.scala index 9ca834881..49e67ccf9 100644 --- a/Modules/Reactives/js-native/src/main/scala/reactives/scheduler/PlatformCandidates.scala +++ b/Modules/Reactives/js-native/src/main/scala/reactives/scheduler/PlatformCandidates.scala @@ -1,6 +1,6 @@ package reactives.scheduler object PlatformCandidates { - val parrp = GlobalCandidate.levelled + val parrp = GlobalCandidate.levelled val fullmv = GlobalCandidate.levelled } diff --git a/Modules/Reactives/js/src/main/scala/reactives/extra/Tags.scala b/Modules/Reactives/js/src/main/scala/reactives/extra/Tags.scala index 059678355..20c105e36 100644 --- a/Modules/Reactives/js/src/main/scala/reactives/extra/Tags.scala +++ b/Modules/Reactives/js/src/main/scala/reactives/extra/Tags.scala @@ -33,7 +33,10 @@ class Tags(val addDebuggingIds: Boolean) { } extension (outer: dom.Element) - def reattach[T](signal: Signal[T])(using splicer: RangeSplice[T], creationTicket: CreationTicket[Interface.State]): outer.type = { + def reattach[T](signal: Signal[T])(using + splicer: RangeSplice[T], + creationTicket: CreationTicket[Interface.State] + ): outer.type = { val range = document.createRange() range.selectNodeContents(outer) range.collapse(toStart = false) @@ -47,7 +50,10 @@ class Tags(val addDebuggingIds: Boolean) { } extension (input: Input) - def inputEntered(using creationTicket: CreationTicket[Interface.State], scheduler: PlanTransactionScope[Interface.State]): Event[String] = { + def inputEntered(using + creationTicket: CreationTicket[Interface.State], + scheduler: PlanTransactionScope[Interface.State] + ): Event[String] = { val handler: Event.CBR[KeyboardEvent, Unit] = Event.fromCallback(input.onkeyup = Event.handle(_)) handler.event diff --git a/Modules/Reactives/js/src/test/scala/tests/rescala/RescalatagsTest.scala b/Modules/Reactives/js/src/test/scala/tests/rescala/RescalatagsTest.scala index 90c3fe156..8a7944a68 100644 --- a/Modules/Reactives/js/src/test/scala/tests/rescala/RescalatagsTest.scala +++ b/Modules/Reactives/js/src/test/scala/tests/rescala/RescalatagsTest.scala @@ -16,85 +16,88 @@ import scala.util.chaining.scalaUtilChainingOps class RescalatagsTest extends RETests { - test("put var into dom") { + test("put var into dom") { - val v = Var.empty[Element] - val rendered = div().render.reattach(v) - assertEquals(rendered.textContent, "", "empty var gives empty frag") + val v = Var.empty[Element] + val rendered = div().render.reattach(v) + assertEquals(rendered.textContent, "", "empty var gives empty frag") - assertEquals(rendered.innerHTML, "", "empty var into dom is empty") + assertEquals(rendered.innerHTML, "", "empty var into dom is empty") - v.set(span("hallo welt").render) - assertEquals(rendered.innerHTML, "hallo welt", "setting var changes rendered outer tag") + v.set(span("hallo welt").render) + assertEquals(rendered.innerHTML, "hallo welt", "setting var changes rendered outer tag") - v.set(div("hallo div").render) - assertEquals(rendered.innerHTML, "
hallo div
", "resetting var changes rendered outer tag") + v.set(div("hallo div").render) + assertEquals(rendered.innerHTML, "
hallo div
", "resetting var changes rendered outer tag") - } + } - given RangeSplice[Modifier] with { - override def splice(range: dom.Range, value: Modifier): Unit = - val parent = range.commonAncestorContainer - parent match - case elem: dom.Element => value.applyTo(elem) - } + given RangeSplice[Modifier] with { + override def splice(range: dom.Range, value: Modifier): Unit = + val parent = range.commonAncestorContainer + parent match + case elem: dom.Element => value.applyTo(elem) + } - test("put style into dom") { - val v: Var[String] = Var.empty[String] + test("put style into dom") { + val v: Var[String] = Var.empty[String] - val ourTag: Span = span.render.reattach(v.map(backgroundColor := _)) + val ourTag: Span = span.render.reattach(v.map(backgroundColor := _)) - assertEquals(ourTag.style.getPropertyValue(backgroundColor.cssName), "", "empty color does not render") + assertEquals(ourTag.style.getPropertyValue(backgroundColor.cssName), "", "empty color does not render") - v.set("red") - assertEquals(ourTag.style.getPropertyValue(backgroundColor.cssName), "red", "changing var changes color") + v.set("red") + assertEquals(ourTag.style.getPropertyValue(backgroundColor.cssName), "red", "changing var changes color") - v.set("blue") - assertEquals(ourTag.style.getPropertyValue(backgroundColor.cssName), "blue", "changing var changes color again") - } + v.set("blue") + assertEquals(ourTag.style.getPropertyValue(backgroundColor.cssName), "blue", "changing var changes color again") + } - test("put attribute into dom") { - val v = Var.empty[String] + test("put attribute into dom") { + val v = Var.empty[String] - val ourTag = a().render.reattach(v.map(href := _)) + val ourTag = a().render.reattach(v.map(href := _)) - assertEquals(ourTag.outerHTML, a.render.outerHTML, "empty href does not render") + assertEquals(ourTag.outerHTML, a.render.outerHTML, "empty href does not render") - v.set("www.rescala-lang.com") - assertEquals(ourTag.outerHTML, a(href := "www.rescala-lang.com").render.outerHTML, "changing var changes href") + v.set("www.rescala-lang.com") + assertEquals(ourTag.outerHTML, a(href := "www.rescala-lang.com").render.outerHTML, "changing var changes href") - v.set("index.html") - assertEquals(ourTag.outerHTML, a(href := "index.html").render.outerHTML, "changing var changes href again") + v.set("index.html") + assertEquals(ourTag.outerHTML, a(href := "index.html").render.outerHTML, "changing var changes href again") - } + } - test("work with multiple childern") { + test("work with multiple childern") { - val v = Var(Seq(span("hey"), span("ho"))) - def vrend = v.map(_.map(_.render)) + val v = Var(Seq(span("hey"), span("ho"))) + def vrend = v.map(_.map(_.render)) - val outerR = div().render.reattach(vrend) - val outerWithOtherChildren = div(span("before")).render.reattach(vrend).tap(_.append(span("after").render)) + val outerR = div().render.reattach(vrend) + val outerWithOtherChildren = div(span("before")).render.reattach(vrend).tap(_.append(span("after").render)) - assertEquals(outerR.innerHTML, "heyho", "render fragments") - assertEquals( - "beforeheyhoafter", outerWithOtherChildren.innerHTML, - "render fragments2" - ) + assertEquals(outerR.innerHTML, "heyho", "render fragments") + assertEquals( + "beforeheyhoafter", + outerWithOtherChildren.innerHTML, + "render fragments2" + ) - v.set(Seq(span("hallo welt"))) - assertEquals(outerR.innerHTML, "hallo welt", "setting to less elements works") - assertEquals( - "beforehallo weltafter", outerWithOtherChildren.innerHTML, - "setting to less elements works2" - ) + v.set(Seq(span("hallo welt"))) + assertEquals(outerR.innerHTML, "hallo welt", "setting to less elements works") + assertEquals( + "beforehallo weltafter", + outerWithOtherChildren.innerHTML, + "setting to less elements works2" + ) - v.set(Seq(span("hey2"), span("ho2"))) - assertEquals(outerR.innerHTML, "hey2ho2", "increasing works") - assertEquals( - "beforehey2ho2after", outerWithOtherChildren.innerHTML, - "increasing works2" - ) + v.set(Seq(span("hey2"), span("ho2"))) + assertEquals(outerR.innerHTML, "hey2ho2", "increasing works") + assertEquals( + "beforehey2ho2after", + outerWithOtherChildren.innerHTML, + "increasing works2" + ) - } + } } diff --git a/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/FullMVBundle.scala b/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/FullMVBundle.scala index 823da2fa3..1e0ffaa05 100644 --- a/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/FullMVBundle.scala +++ b/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/FullMVBundle.scala @@ -1,11 +1,15 @@ package reactives.fullmv import reactives.core -import reactives.core.{AdmissionTicket, Derived, Initializer, Observation, ReSource, ReadAs, SchedulerWithDynamicScope, Transaction} +import reactives.core.{ + AdmissionTicket, Derived, Initializer, Observation, ReSource, ReadAs, SchedulerWithDynamicScope, Transaction +} import reactives.fullmv.NotificationBranchResult.ReevOutBranchResult.* import reactives.fullmv.NotificationBranchResult.* import reactives.fullmv.mirrors.* -import reactives.fullmv.sgt.synchronization.{SubsumableLock, SubsumableLockEntryPoint, SubsumableLockHostImpl, SubsumableLockImpl} +import reactives.fullmv.sgt.synchronization.{ + SubsumableLock, SubsumableLockEntryPoint, SubsumableLockHostImpl, SubsumableLockImpl +} import reactives.fullmv.tasks.{Framing, Notification, Reevaluation, SourceNotification} import java.util.concurrent.atomic.AtomicReference diff --git a/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/TurnImplBundle.scala b/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/TurnImplBundle.scala index 162837fde..6d6eeeaa2 100644 --- a/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/TurnImplBundle.scala +++ b/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/TurnImplBundle.scala @@ -452,7 +452,8 @@ class FullMVTurnImpl( } } override def tryLock(): Future[TryLockResult] = { - if (SubsumableLockImpl.DEBUG) println(s"[${Thread.currentThread().getName}] $this dispatching local tryLock request") + if (SubsumableLockImpl.DEBUG) + println(s"[${Thread.currentThread().getName}] $this dispatching local tryLock request") tryLock0(0) } @@ -521,7 +522,8 @@ class FullMVTurnImpl( } override def remoteTryLock(): Future[TryLockResult] = { - if (SubsumableLockImpl.DEBUG) println(s"[${Thread.currentThread().getName}] $this dispatching remote tryLock request") + if (SubsumableLockImpl.DEBUG) + println(s"[${Thread.currentThread().getName}] $this dispatching remote tryLock request") tryLock0(0).map { res => if (SubsumableLockImpl.DEBUG) println( diff --git a/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/mirrors/Mirror.scala b/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/mirrors/Mirror.scala index f7007c4f6..a06f50461 100644 --- a/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/mirrors/Mirror.scala +++ b/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/mirrors/Mirror.scala @@ -3,54 +3,52 @@ package reactives.fullmv.mirrors import reactives.fullmv.sgt.synchronization.{LockStateResult, SubsumableLock, TryLockResult, TrySubsumeResult} import reactives.fullmv.{FullMVTurn, TransactionSpanningTreeNode, TurnPhase} - - trait FullMVTurnHost extends Host[FullMVTurn] { - val lockHost: SubsumableLockHost - } - - import scala.concurrent.Future - - trait FullMVTurnPhaseReflectionProxy { - def asyncNewPhase(phase: TurnPhase.Type): Unit - } - - trait FullMVTurnPredecessorReflectionProxy { - def newPredecessors(predecessors: TransactionSpanningTreeNode[FullMVTurn], clock: Int): Future[Unit] - } - - trait FullMVTurnProxy { - def addRemoteBranch(forPhase: TurnPhase.Type): Future[Unit] - def asyncRemoteBranchComplete(forPhase: TurnPhase.Type): Unit - - def acquireRemoteBranchIfPhaseAtMost(maxPhase: TurnPhase.Type): Future[TurnPhase.Type] - def addPredecessor(tree: TransactionSpanningTreeNode[FullMVTurn]): Future[Boolean] - - def maybeNewReachableSubtree( - attachBelow: FullMVTurn, - spanningSubTreeRoot: TransactionSpanningTreeNode[FullMVTurn] - ): Future[Unit] - def newSuccessor(successor: FullMVTurn): Future[Unit] - - def getLockedRoot: Future[LockStateResult] - // result has one thread reference counted - def remoteTryLock(): Future[TryLockResult] - // parameter has one thread reference counted, result has one thread reference counted - def remoteTrySubsume(lockedNewParent: SubsumableLock): Future[TrySubsumeResult] - - def asyncAddPhaseReplicator(replicator: FullMVTurnPhaseReflectionProxy, knownPhase: TurnPhase.Type): Unit - def asyncAddPredecessorReplicator( - replicator: FullMVTurnPredecessorReflectionProxy, - startAt: TransactionSpanningTreeNode[FullMVTurn], - clock: Int - ): Unit - } - - trait ReactiveReflectionProxy[-P] { - def asyncIncrementFrame(turn: FullMVTurn): Unit - def asyncIncrementSupersedeFrame(turn: FullMVTurn, supersede: FullMVTurn): Unit - def asyncResolvedUnchanged(turn: FullMVTurn): Unit - def asyncResolvedUnchangedFollowFrame(turn: FullMVTurn, followFrame: FullMVTurn): Unit - def asyncNewValue(turn: FullMVTurn, value: P): Unit - def asyncNewValueFollowFrame(turn: FullMVTurn, value: P, followFrame: FullMVTurn): Unit - } - +trait FullMVTurnHost extends Host[FullMVTurn] { + val lockHost: SubsumableLockHost +} + +import scala.concurrent.Future + +trait FullMVTurnPhaseReflectionProxy { + def asyncNewPhase(phase: TurnPhase.Type): Unit +} + +trait FullMVTurnPredecessorReflectionProxy { + def newPredecessors(predecessors: TransactionSpanningTreeNode[FullMVTurn], clock: Int): Future[Unit] +} + +trait FullMVTurnProxy { + def addRemoteBranch(forPhase: TurnPhase.Type): Future[Unit] + def asyncRemoteBranchComplete(forPhase: TurnPhase.Type): Unit + + def acquireRemoteBranchIfPhaseAtMost(maxPhase: TurnPhase.Type): Future[TurnPhase.Type] + def addPredecessor(tree: TransactionSpanningTreeNode[FullMVTurn]): Future[Boolean] + + def maybeNewReachableSubtree( + attachBelow: FullMVTurn, + spanningSubTreeRoot: TransactionSpanningTreeNode[FullMVTurn] + ): Future[Unit] + def newSuccessor(successor: FullMVTurn): Future[Unit] + + def getLockedRoot: Future[LockStateResult] + // result has one thread reference counted + def remoteTryLock(): Future[TryLockResult] + // parameter has one thread reference counted, result has one thread reference counted + def remoteTrySubsume(lockedNewParent: SubsumableLock): Future[TrySubsumeResult] + + def asyncAddPhaseReplicator(replicator: FullMVTurnPhaseReflectionProxy, knownPhase: TurnPhase.Type): Unit + def asyncAddPredecessorReplicator( + replicator: FullMVTurnPredecessorReflectionProxy, + startAt: TransactionSpanningTreeNode[FullMVTurn], + clock: Int + ): Unit +} + +trait ReactiveReflectionProxy[-P] { + def asyncIncrementFrame(turn: FullMVTurn): Unit + def asyncIncrementSupersedeFrame(turn: FullMVTurn, supersede: FullMVTurn): Unit + def asyncResolvedUnchanged(turn: FullMVTurn): Unit + def asyncResolvedUnchangedFollowFrame(turn: FullMVTurn, followFrame: FullMVTurn): Unit + def asyncNewValue(turn: FullMVTurn, value: P): Unit + def asyncNewValueFollowFrame(turn: FullMVTurn, value: P, followFrame: FullMVTurn): Unit +} diff --git a/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/tasks/TaskBundle.scala b/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/tasks/TaskBundle.scala index b63e20a3c..286f634d4 100644 --- a/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/tasks/TaskBundle.scala +++ b/Modules/Reactives/jvm/src/main/scala/reactives/fullmv/tasks/TaskBundle.scala @@ -11,259 +11,256 @@ import reactives.structure.Pulse import java.util.concurrent.RecursiveAction - - trait FramingTask extends FullMVAction { - override def doCompute(): Unit = { - val branchResult = doFraming() - if (FullMVUtil.DEBUG) println(s"[${Thread.currentThread().getName}] $this => $branchResult") - branchResult match { - case FramingBranchEnd => - turn.activeBranchDifferential(TurnPhase.Framing, -1) - case Frame(out: Set[ReSource.of[State]], maybeOtherTurn) => - branchCountDiffOnBranchOut(out, maybeOtherTurn) - for (dep <- out) new Framing(maybeOtherTurn, dep).fork - case FrameSupersede(out: Set[ReSource.of[State]], maybeOtherTurn, supersede) => - branchCountDiffOnBranchOut(out, maybeOtherTurn) - for (dep <- out) new SupersedeFraming(maybeOtherTurn, dep, supersede).fork - } - } - - private def branchCountDiffOnBranchOut(out: Set[ReSource.of[State]], maybeOtherTurn: FullMVTurn): Unit = { - if (turn == maybeOtherTurn) { - val branchDiff = out.size - 1 - if (branchDiff != 0) turn.activeBranchDifferential(TurnPhase.Framing, branchDiff) - } else { - if (out.nonEmpty) maybeOtherTurn.activeBranchDifferential(TurnPhase.Framing, out.size) +trait FramingTask extends FullMVAction { + override def doCompute(): Unit = { + val branchResult = doFraming() + if (FullMVUtil.DEBUG) println(s"[${Thread.currentThread().getName}] $this => $branchResult") + branchResult match { + case FramingBranchEnd => turn.activeBranchDifferential(TurnPhase.Framing, -1) - } + case Frame(out: Set[ReSource.of[State]], maybeOtherTurn) => + branchCountDiffOnBranchOut(out, maybeOtherTurn) + for (dep <- out) new Framing(maybeOtherTurn, dep).fork + case FrameSupersede(out: Set[ReSource.of[State]], maybeOtherTurn, supersede) => + branchCountDiffOnBranchOut(out, maybeOtherTurn) + for (dep <- out) new SupersedeFraming(maybeOtherTurn, dep, supersede).fork } - - def doFraming(): FramingBranchResult[FullMVTurn, ReSource.of[State]] } - class Framing(override val turn: FullMVTurn, override val node: ReSource.of[State]) extends FramingTask { - override def doFraming(): FramingBranchResult[FullMVTurn, ReSource.of[State]] = { - assert(turn.phase == TurnPhase.Framing, s"$this cannot increment frame (requires framing phase)") - node.state.incrementFrame(turn) + private def branchCountDiffOnBranchOut(out: Set[ReSource.of[State]], maybeOtherTurn: FullMVTurn): Unit = { + if (turn == maybeOtherTurn) { + val branchDiff = out.size - 1 + if (branchDiff != 0) turn.activeBranchDifferential(TurnPhase.Framing, branchDiff) + } else { + if (out.nonEmpty) maybeOtherTurn.activeBranchDifferential(TurnPhase.Framing, out.size) + turn.activeBranchDifferential(TurnPhase.Framing, -1) } - override def toString = s"Framing($turn, $node)" } - class SupersedeFraming(override val turn: FullMVTurn, override val node: ReSource.of[State], supersede: FullMVTurn) - extends FramingTask { - override def doFraming(): FramingBranchResult[FullMVTurn, ReSource.of[State]] = { - assert(turn.phase == TurnPhase.Framing, s"$this cannot increment frame (requires framing phase)") - assert(supersede.phase == TurnPhase.Framing, s"$supersede cannot have frame superseded (requires framing phase)") - node.state.incrementSupersedeFrame(turn, supersede) - } - override def toString = s"Framing($turn, $node)" - } + def doFraming(): FramingBranchResult[FullMVTurn, ReSource.of[State]] +} - trait FullMVAction extends RecursiveAction { - val turn: FullMVTurn - val node: ReSource.of[State] - override def compute(): Unit = { - try { doCompute() } - catch { - case t: Throwable => - new Exception(this.toString + " failed on " + Thread.currentThread().getName, t).printStackTrace() - } - } - def doCompute(): Unit +class Framing(override val turn: FullMVTurn, override val node: ReSource.of[State]) extends FramingTask { + override def doFraming(): FramingBranchResult[FullMVTurn, ReSource.of[State]] = { + assert(turn.phase == TurnPhase.Framing, s"$this cannot increment frame (requires framing phase)") + node.state.incrementFrame(turn) } + override def toString = s"Framing($turn, $node)" +} - trait NotificationAction[N <: ReSource.of[State]] extends ReevaluationHandling[N] { - val changed: Boolean - override def doCompute(): Unit = { - val (retainBranch, notificationResultAction) = deliverNotification() - if (FullMVUtil.DEBUG) - println(s"[${Thread.currentThread().getName}] $this => $retainBranch, $notificationResultAction") - processNotificationResult(retainBranch, notificationResultAction) - } - - def processNotificationResult( - retainBranch: Boolean, - notificationResultAction: NotificationBranchResult[FullMVTurn, Derived.of[State]] - ): Unit = { - notificationResultAction match { - case DoNothing => - if (!retainBranch) turn.activeBranchDifferential(TurnPhase.Executing, -1) - case ReevaluationReady => - doReevaluation(retainBranch) - case outAndSucc: ReevOutBranchResult[FullMVTurn @unchecked, Derived.of[State] @unchecked] => - processReevOutResult(retainBranch, outAndSucc, changed = false) - } - } - - def deliverNotification(): (Boolean, NotificationBranchResult[FullMVTurn, Derived.of[State]]) +class SupersedeFraming(override val turn: FullMVTurn, override val node: ReSource.of[State], supersede: FullMVTurn) + extends FramingTask { + override def doFraming(): FramingBranchResult[FullMVTurn, ReSource.of[State]] = { + assert(turn.phase == TurnPhase.Framing, s"$this cannot increment frame (requires framing phase)") + assert(supersede.phase == TurnPhase.Framing, s"$supersede cannot have frame superseded (requires framing phase)") + node.state.incrementSupersedeFrame(turn, supersede) } + override def toString = s"Framing($turn, $node)" +} - class SourceNotification( - override val turn: FullMVTurn, - override val node: ReSource.of[State], - override val changed: Boolean - ) extends NotificationAction[ReSource.of[State]] - with SourceReevaluationHandling { - override def deliverNotification(): (Boolean, NotificationBranchResult[FullMVTurn, Derived.of[State]]) = - node.state.notify(turn, changed) - override def createReevaluation(succTxn: FullMVTurn) = new SourceReevaluation(succTxn, node) - override def toString = s"SourceNotification($turn, $node)" +trait FullMVAction extends RecursiveAction { + val turn: FullMVTurn + val node: ReSource.of[State] + override def compute(): Unit = { + try { doCompute() } + catch { + case t: Throwable => + new Exception(this.toString + " failed on " + Thread.currentThread().getName, t).printStackTrace() + } } + def doCompute(): Unit +} - class Notification( - override val turn: FullMVTurn, - override val node: Derived.of[State], - override val changed: Boolean - ) extends NotificationAction[Derived.of[State]] - with RegularReevaluationHandling { - override def deliverNotification(): (Boolean, NotificationBranchResult[FullMVTurn, Derived.of[State]]) = - node.state.notify(turn, changed) - override def createReevaluation(succTxn: FullMVTurn) = new Reevaluation(succTxn, node) - override def toString = s"Notification($turn, $node)" - } - class NotificationWithFollowFrame( - override val turn: FullMVTurn, - override val node: Derived.of[State], - override val changed: Boolean, - followFrame: FullMVTurn - ) extends NotificationAction[Derived.of[State]] - with RegularReevaluationHandling { - override def deliverNotification(): (Boolean, NotificationBranchResult[FullMVTurn, Derived.of[State]]) = - node.state.notifyFollowFrame(turn, changed, followFrame) - override def createReevaluation(succTxn: FullMVTurn) = new Reevaluation(succTxn, node) - override def toString = s"NotificationWithFollowFrame($turn, $node, $followFrame)" +trait NotificationAction[N <: ReSource.of[State]] extends ReevaluationHandling[N] { + val changed: Boolean + override def doCompute(): Unit = { + val (retainBranch, notificationResultAction) = deliverNotification() + if (FullMVUtil.DEBUG) + println(s"[${Thread.currentThread().getName}] $this => $retainBranch, $notificationResultAction") + processNotificationResult(retainBranch, notificationResultAction) } - class Reevaluation(override val turn: FullMVTurn, override val node: Derived.of[State]) - extends RegularReevaluationHandling { - override def doCompute(): Unit = doReevaluation(retainBranch = true) - override def toString = s"Reevaluation($turn, $node)" + def processNotificationResult( + retainBranch: Boolean, + notificationResultAction: NotificationBranchResult[FullMVTurn, Derived.of[State]] + ): Unit = { + notificationResultAction match { + case DoNothing => + if (!retainBranch) turn.activeBranchDifferential(TurnPhase.Executing, -1) + case ReevaluationReady => + doReevaluation(retainBranch) + case outAndSucc: ReevOutBranchResult[FullMVTurn @unchecked, Derived.of[State] @unchecked] => + processReevOutResult(retainBranch, outAndSucc, changed = false) + } } - trait RegularReevaluationHandling extends ReevaluationHandling[Derived.of[State]] { - override val node: Derived.of[State] + def deliverNotification(): (Boolean, NotificationBranchResult[FullMVTurn, Derived.of[State]]) +} - object FullAccessHandle extends AccessHandler[State] { - override def staticAccess(reactive: ReSource.of[State]): reactive.Value = turn.staticAfter(reactive) - override def dynamicAccess(reactive: ReSource.of[State]): reactive.Value = turn.dynamicAfter(reactive) - } +class SourceNotification( + override val turn: FullMVTurn, + override val node: ReSource.of[State], + override val changed: Boolean +) extends NotificationAction[ReSource.of[State]] + with SourceReevaluationHandling { + override def deliverNotification(): (Boolean, NotificationBranchResult[FullMVTurn, Derived.of[State]]) = + node.state.notify(turn, changed) + override def createReevaluation(succTxn: FullMVTurn) = new SourceReevaluation(succTxn, node) + override def toString = s"SourceNotification($turn, $node)" +} - def doReevaluation(retainBranch: Boolean): Unit = { -// assert(Thread.currentThread() == turn.userlandThread, s"$this on different thread ${Thread.currentThread().getName}") - assert(turn.phase == TurnPhase.Executing, s"$turn cannot reevaluate (requires executing phase") - var value = node.state.reevIn(turn) - val transactionHandle = TransactionHandle(turn) - val ticket: ReevTicket[State, node.Value] = - new ReevTicket[State, node.Value](transactionHandle, value, FullAccessHandle) - val res: Result[State, node.Value] = - try { - turn.host.dynamicScope.withDynamicInitializer(transactionHandle) { - node.reevaluate(ticket) - } - } catch { - case exception: Throwable => - System.err.println( - s"[FullMV Error] Reevaluation of $node failed with ${exception.getClass.getName}: ${exception.getMessage}; Completing reevaluation as NoChange." - ) - exception.printStackTrace() - ticket.withPropagate(false) - } - res.inputs().foreach(commitDependencyDiff(node, node.state.incomings)) - res.forValue(v => value = v) - res.forEffect(_.execute()) - val res2 = processReevaluationResult(if (res.activate) Some(value) else None) - processReevOutResult(retainBranch, res2, changed = res.activate) - } +class Notification( + override val turn: FullMVTurn, + override val node: Derived.of[State], + override val changed: Boolean +) extends NotificationAction[Derived.of[State]] + with RegularReevaluationHandling { + override def deliverNotification(): (Boolean, NotificationBranchResult[FullMVTurn, Derived.of[State]]) = + node.state.notify(turn, changed) + override def createReevaluation(succTxn: FullMVTurn) = new Reevaluation(succTxn, node) + override def toString = s"Notification($turn, $node)" +} +class NotificationWithFollowFrame( + override val turn: FullMVTurn, + override val node: Derived.of[State], + override val changed: Boolean, + followFrame: FullMVTurn +) extends NotificationAction[Derived.of[State]] + with RegularReevaluationHandling { + override def deliverNotification(): (Boolean, NotificationBranchResult[FullMVTurn, Derived.of[State]]) = + node.state.notifyFollowFrame(turn, changed, followFrame) + override def createReevaluation(succTxn: FullMVTurn) = new Reevaluation(succTxn, node) + override def toString = s"NotificationWithFollowFrame($turn, $node, $followFrame)" +} - final def commitDependencyDiff( - node: Derived.of[State], - current: Set[ReSource.of[State]] - )(updated: Set[ReSource.of[State]]): Unit = { - val indepsRemoved = current -- updated - val indepsAdded = updated -- current - indepsRemoved.foreach(turn.drop(_, node)) - indepsAdded.foreach(turn.discover(_, node)) - turn.writeIndeps(node, updated) - } +class Reevaluation(override val turn: FullMVTurn, override val node: Derived.of[State]) + extends RegularReevaluationHandling { + override def doCompute(): Unit = doReevaluation(retainBranch = true) + override def toString = s"Reevaluation($turn, $node)" +} - override def createReevaluation(succTxn: FullMVTurn) = new Reevaluation(succTxn, node) - } +trait RegularReevaluationHandling extends ReevaluationHandling[Derived.of[State]] { + override val node: Derived.of[State] - class SourceReevaluation(override val turn: FullMVTurn, override val node: ReSource.of[State]) - extends SourceReevaluationHandling { - override def doCompute(): Unit = doReevaluation(retainBranch = true) - override def toString = s"SourceReevaluation($turn, $node)" + object FullAccessHandle extends AccessHandler[State] { + override def staticAccess(reactive: ReSource.of[State]): reactive.Value = turn.staticAfter(reactive) + override def dynamicAccess(reactive: ReSource.of[State]): reactive.Value = turn.dynamicAfter(reactive) } - trait SourceReevaluationHandling extends ReevaluationHandling[ReSource.of[State]] { - def doReevaluation(retainBranch: Boolean): Unit = { + def doReevaluation(retainBranch: Boolean): Unit = { // assert(Thread.currentThread() == turn.userlandThread, s"$this on different thread ${Thread.currentThread().getName}") - assert(turn.phase == TurnPhase.Executing, s"$turn cannot source-reevaluate (requires executing phase") - val ic = turn.asInstanceOf[FullMVTurnImpl].initialChanges(node) - assert(ic.source eq node, s"$turn initial change map broken?") - if ( - !ic.writeValue( - ic.source.state.latestValue, - x => { - val res = processReevaluationResult(Some(x.asInstanceOf[node.Value])) - processReevOutResult(retainBranch, res, changed = true) - } - ) - ) { - val res = processReevaluationResult(None) - processReevOutResult(retainBranch, res, changed = false) + assert(turn.phase == TurnPhase.Executing, s"$turn cannot reevaluate (requires executing phase") + var value = node.state.reevIn(turn) + val transactionHandle = TransactionHandle(turn) + val ticket: ReevTicket[State, node.Value] = + new ReevTicket[State, node.Value](transactionHandle, value, FullAccessHandle) + val res: Result[State, node.Value] = + try { + turn.host.dynamicScope.withDynamicInitializer(transactionHandle) { + node.reevaluate(ticket) + } + } catch { + case exception: Throwable => + System.err.println( + s"[FullMV Error] Reevaluation of $node failed with ${exception.getClass.getName}: ${exception.getMessage}; Completing reevaluation as NoChange." + ) + exception.printStackTrace() + ticket.withPropagate(false) } - } + res.inputs().foreach(commitDependencyDiff(node, node.state.incomings)) + res.forValue(v => value = v) + res.forEffect(_.execute()) + val res2 = processReevaluationResult(if (res.activate) Some(value) else None) + processReevOutResult(retainBranch, res2, changed = res.activate) + } - override def createReevaluation(succTxn: FullMVTurn): FullMVAction = new SourceReevaluation(succTxn, node) + final def commitDependencyDiff( + node: Derived.of[State], + current: Set[ReSource.of[State]] + )(updated: Set[ReSource.of[State]]): Unit = { + val indepsRemoved = current -- updated + val indepsAdded = updated -- current + indepsRemoved.foreach(turn.drop(_, node)) + indepsAdded.foreach(turn.discover(_, node)) + turn.writeIndeps(node, updated) } - trait ReevaluationHandling[N <: ReSource.of[State]] extends FullMVAction { - def createReevaluation(succTxn: FullMVTurn): FullMVAction - def doReevaluation(retainBranch: Boolean): Unit + override def createReevaluation(succTxn: FullMVTurn) = new Reevaluation(succTxn, node) +} - def processReevaluationResult(maybeChange: Option[node.Value]) - : ReevOutBranchResult[FullMVTurn, Derived.of[State]] = { - val reevOutResult = node.state.reevOut(turn, maybeChange, node.commit) - if (FullMVUtil.DEBUG && maybeChange.isDefined && maybeChange.get.isInstanceOf[Pulse.Exceptional]) { - // could be a framework exception that is relevant to debugging, but was eaten by reactive's - // exception propagation and thus wouldn't be reported otherwise.. - println(s"[${Thread.currentThread().getName}] WARNING: $this glitch-free result is exceptional:") - maybeChange.get.asInstanceOf[Pulse.Exceptional].throwable.printStackTrace() - } - if (FullMVUtil.DEBUG) - println( - s"[${Thread.currentThread().getName}] Reevaluation($turn,$node) => ${ - if (maybeChange.isDefined) "changed" - else "unchanged" - } $reevOutResult" - ) - reevOutResult +class SourceReevaluation(override val turn: FullMVTurn, override val node: ReSource.of[State]) + extends SourceReevaluationHandling { + override def doCompute(): Unit = doReevaluation(retainBranch = true) + override def toString = s"SourceReevaluation($turn, $node)" +} + +trait SourceReevaluationHandling extends ReevaluationHandling[ReSource.of[State]] { + def doReevaluation(retainBranch: Boolean): Unit = { +// assert(Thread.currentThread() == turn.userlandThread, s"$this on different thread ${Thread.currentThread().getName}") + assert(turn.phase == TurnPhase.Executing, s"$turn cannot source-reevaluate (requires executing phase") + val ic = turn.asInstanceOf[FullMVTurnImpl].initialChanges(node) + assert(ic.source eq node, s"$turn initial change map broken?") + if ( + !ic.writeValue( + ic.source.state.latestValue, + x => { + val res = processReevaluationResult(Some(x.asInstanceOf[node.Value])) + processReevOutResult(retainBranch, res, changed = true) + } + ) + ) { + val res = processReevaluationResult(None) + processReevOutResult(retainBranch, res, changed = false) } + } - def processReevOutResult( - retainBranch: Boolean, - outAndSucc: ReevOutBranchResult[FullMVTurn, Derived.of[State]], - changed: Boolean - ): Unit = { - (outAndSucc: @unchecked) match { - case PureNotifyOnly(out) => - doBranchDiff(retainBranch, out) - for (dep <- out) new Notification(turn, dep, changed).fork() - case NotifyAndNonReadySuccessor(out, succTxn) => - doBranchDiff(retainBranch, out) - for (dep <- out) new NotificationWithFollowFrame(turn, dep, changed, succTxn).fork() - case NotifyAndReevaluationReadySuccessor(out, succTxn) => - doBranchDiff(retainBranch, out) - for (dep <- out) new NotificationWithFollowFrame(turn, dep, changed, succTxn).fork() - createReevaluation(succTxn).fork() - () - } + override def createReevaluation(succTxn: FullMVTurn): FullMVAction = new SourceReevaluation(succTxn, node) +} + +trait ReevaluationHandling[N <: ReSource.of[State]] extends FullMVAction { + def createReevaluation(succTxn: FullMVTurn): FullMVAction + def doReevaluation(retainBranch: Boolean): Unit + + def processReevaluationResult(maybeChange: Option[node.Value]): ReevOutBranchResult[FullMVTurn, Derived.of[State]] = { + val reevOutResult = node.state.reevOut(turn, maybeChange, node.commit) + if (FullMVUtil.DEBUG && maybeChange.isDefined && maybeChange.get.isInstanceOf[Pulse.Exceptional]) { + // could be a framework exception that is relevant to debugging, but was eaten by reactive's + // exception propagation and thus wouldn't be reported otherwise.. + println(s"[${Thread.currentThread().getName}] WARNING: $this glitch-free result is exceptional:") + maybeChange.get.asInstanceOf[Pulse.Exceptional].throwable.printStackTrace() } + if (FullMVUtil.DEBUG) + println( + s"[${Thread.currentThread().getName}] Reevaluation($turn,$node) => ${ + if (maybeChange.isDefined) "changed" + else "unchanged" + } $reevOutResult" + ) + reevOutResult + } - private def doBranchDiff(retainBranch: Boolean, out: Set[Derived.of[State]]) = { - val branchDiff = out.size - (if (retainBranch) 1 else 2) - if (branchDiff != 0) turn.activeBranchDifferential(TurnPhase.Executing, branchDiff) + def processReevOutResult( + retainBranch: Boolean, + outAndSucc: ReevOutBranchResult[FullMVTurn, Derived.of[State]], + changed: Boolean + ): Unit = { + (outAndSucc: @unchecked) match { + case PureNotifyOnly(out) => + doBranchDiff(retainBranch, out) + for (dep <- out) new Notification(turn, dep, changed).fork() + case NotifyAndNonReadySuccessor(out, succTxn) => + doBranchDiff(retainBranch, out) + for (dep <- out) new NotificationWithFollowFrame(turn, dep, changed, succTxn).fork() + case NotifyAndReevaluationReadySuccessor(out, succTxn) => + doBranchDiff(retainBranch, out) + for (dep <- out) new NotificationWithFollowFrame(turn, dep, changed, succTxn).fork() + createReevaluation(succTxn).fork() + () } } + private def doBranchDiff(retainBranch: Boolean, out: Set[Derived.of[State]]) = { + val branchDiff = out.size - (if (retainBranch) 1 else 2) + if (branchDiff != 0) turn.activeBranchDifferential(TurnPhase.Executing, branchDiff) + } +} diff --git a/Modules/Reactives/jvm/src/main/scala/reactives/locking/Key.scala b/Modules/Reactives/jvm/src/main/scala/reactives/locking/Key.scala index 8aeebf44d..7b397a94a 100644 --- a/Modules/Reactives/jvm/src/main/scala/reactives/locking/Key.scala +++ b/Modules/Reactives/jvm/src/main/scala/reactives/locking/Key.scala @@ -33,7 +33,7 @@ final class Key[InterTurn](val turn: InterTurn) { } /** contains a list of all locks owned by us. */ - private val heldLocks: ArrayBuffer[ReLock[InterTurn]] = ArrayBuffer[ReLock[InterTurn]]() + private val heldLocks: ArrayBuffer[ReLock[InterTurn]] = ArrayBuffer[ReLock[InterTurn]]() private[locking] def addLock(lock: ReLock[InterTurn]): Unit = heldLocks.synchronized { heldLocks += lock; () } private[locking] def grabLocks() = heldLocks.synchronized(heldLocks) diff --git a/Modules/Reactives/jvm/src/main/scala/reactives/scheduler/PlatformCandidates.scala b/Modules/Reactives/jvm/src/main/scala/reactives/scheduler/PlatformCandidates.scala index 6711daa9e..fa636b483 100644 --- a/Modules/Reactives/jvm/src/main/scala/reactives/scheduler/PlatformCandidates.scala +++ b/Modules/Reactives/jvm/src/main/scala/reactives/scheduler/PlatformCandidates.scala @@ -7,10 +7,9 @@ object PlatformCandidates { transparent inline def furtherSelect(inline selection: String) = inline selection match - case "parrp" => Some(parrp) + case "parrp" => Some(parrp) case "fullmv" => Some(fullmv) - case other => None - + case other => None object parrp extends GlobalCandidate[reactives.parrp.ParRPDefault.ParRPState] { override def scheduler: Scheduler[State] = reactives.parrp.ParRPDefault.scheduler diff --git a/Modules/Reactives/jvm/src/test/scala/reactives/core/reactor/ReactorWithoutAPITest.scala b/Modules/Reactives/jvm/src/test/scala/reactives/core/reactor/ReactorWithoutAPITest.scala index 4a10e88af..6453cdcc1 100644 --- a/Modules/Reactives/jvm/src/test/scala/reactives/core/reactor/ReactorWithoutAPITest.scala +++ b/Modules/Reactives/jvm/src/test/scala/reactives/core/reactor/ReactorWithoutAPITest.scala @@ -21,7 +21,7 @@ class ReactorWithoutAPITest extends RETests { override type State[V] = Interface.State[V] override protected[reactives] def state: State[ReactorStage[T]] = initState - override def info: ReInfo = ReInfo.create.derive("Custom Reactor") + override def info: ReInfo = ReInfo.create.derive("Custom Reactor") /** Interprets the internal type to the external type * diff --git a/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/DeframeTest.scala b/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/DeframeTest.scala index 8f079057a..f3aea3289 100644 --- a/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/DeframeTest.scala +++ b/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/DeframeTest.scala @@ -188,9 +188,12 @@ class DeframeTest extends munit.FunSuite { // assertEquals(DeframeReframing(turnRightTwo, top, turnLeftTwo).doFraming(), FramingBranchResult.FramingBranchEnd) val reevTop = new Reevaluation(turnLeftOne, top) - assertEquals(reevTop.processReevaluationResult( - Some(Pulse.Value(234).asInstanceOf[reevTop.node.Value]) - ), NotifyAndNonReadySuccessor(Set(), turnLeftTwo)) + assertEquals( + reevTop.processReevaluationResult( + Some(Pulse.Value(234).asInstanceOf[reevTop.node.Value]) + ), + NotifyAndNonReadySuccessor(Set(), turnLeftTwo) + ) } } } diff --git a/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/FullMVTurnTransitiveReachabilityTest.scala b/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/FullMVTurnTransitiveReachabilityTest.scala index a694f83d8..a230cb6f7 100644 --- a/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/FullMVTurnTransitiveReachabilityTest.scala +++ b/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/FullMVTurnTransitiveReachabilityTest.scala @@ -1,6 +1,5 @@ package tests.rescala.fullmv - import reactives.fullmv.{FullMVTurnImpl, FullMVUtil} import scala.concurrent.Await diff --git a/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/LockUnionFindTest.scala b/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/LockUnionFindTest.scala index e593b7a0e..48b94d1f2 100644 --- a/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/LockUnionFindTest.scala +++ b/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/LockUnionFindTest.scala @@ -117,7 +117,7 @@ class LockUnionFindTest extends munit.FunSuite { t2 } - assert(locks(0).refCount.get <= 0) // gc'd + assert(locks(0).refCount.get <= 0) // gc'd assertEquals(locks(1).refCount.get, 1) // turn 0 for (i <- 2 until maxIdx) { assertEquals(locks(i).refCount.get, 2) // lock(i-1), turn(i-1) @@ -128,7 +128,7 @@ class LockUnionFindTest extends munit.FunSuite { turns(2).completeExecuting() turns(4).completeExecuting() - assert(locks(0).refCount.get <= 0) // gc'd + assert(locks(0).refCount.get <= 0) // gc'd assertEquals(locks(1).refCount.get, 1) // turn 0 assertEquals(locks(2).refCount.get, 1) // lock 1 assertEquals(locks(3).refCount.get, 1) // lock 2 @@ -141,17 +141,18 @@ class LockUnionFindTest extends munit.FunSuite { Await.result(turns(0).tryLock(), Duration.Zero).asInstanceOf[Locked].lock.asyncUnlock() - assert(locks(0).refCount.get <= 0) // gc'd - assert(locks(1).refCount.get <= 0) // gc'd - assert(locks(2).refCount.get <= 0) // gc'd - assert(locks(3).refCount.get <= 0) // gc'd + assert(locks(0).refCount.get <= 0) // gc'd + assert(locks(1).refCount.get <= 0) // gc'd + assert(locks(2).refCount.get <= 0) // gc'd + assert(locks(3).refCount.get <= 0) // gc'd assertEquals(locks(4).refCount.get, 1) // turn 3 - assert(locks(5).refCount.get <= 0) // gc'd + assert(locks(5).refCount.get <= 0) // gc'd for (i <- 6 until maxIdx) { assertEquals(locks(i).refCount.get, 1) // turn(i-1) } assertEquals( - locks(maxIdx).refCount.get, maxIdx - 6 + 4 + locks(maxIdx).refCount.get, + maxIdx - 6 + 4 ) // lock(4), lock(6) to lock(maxIdx - 1), turn(0), turn(count-1), turn(count) } @@ -263,7 +264,7 @@ class LockUnionFindTest extends munit.FunSuite { assertEquals(Await.result(turn2.trySubsume(l1), Duration.Zero), Successful) assertEquals(lock1.refCount.get, 3) // turn2, turn1 and thread - assert(lock2.refCount.get <= 0) // none + assert(lock2.refCount.get <= 0) // none l1.asyncUnlock() diff --git a/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/NodeVersionHistoryTest.scala b/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/NodeVersionHistoryTest.scala index 412780659..1a95f7de1 100644 --- a/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/NodeVersionHistoryTest.scala +++ b/Modules/Reactives/jvm/src/test/scala/tests/rescala/jvm/fullmv/NodeVersionHistoryTest.scala @@ -2,7 +2,9 @@ package tests.rescala.fullmv import reactives.fullmv.FramingBranchResult.{Frame, FramingBranchEnd} import reactives.fullmv.NotificationBranchResult.{DoNothing, ReevaluationReady} -import reactives.fullmv.NotificationBranchResult.ReevOutBranchResult.{NotifyAndReevaluationReadySuccessor, PureNotifyOnly} +import reactives.fullmv.NotificationBranchResult.ReevOutBranchResult.{ + NotifyAndReevaluationReadySuccessor, PureNotifyOnly +} import reactives.fullmv._ import scala.concurrent.duration.Duration diff --git a/Modules/Reactives/shared/src/main/scala/reactives/core/AdmissionTicket.scala b/Modules/Reactives/shared/src/main/scala/reactives/core/AdmissionTicket.scala index 7e0e261f5..8dee16b5d 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/core/AdmissionTicket.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/core/AdmissionTicket.scala @@ -1,6 +1,5 @@ package reactives.core - /** Encapsulates an action changing a single source. */ trait InitialChange[State[_]] { @@ -8,9 +7,9 @@ trait InitialChange[State[_]] { val source: ReSource.of[State] /** @param base the current (old) value of the source. - * @param writeCallback callback to apply the new value, executed only if the action is approved by the source. - * @return the propagation status of the source (whether or not to reevaluate output reactives). - */ + * @param writeCallback callback to apply the new value, executed only if the action is approved by the source. + * @return the propagation status of the source (whether or not to reevaluate output reactives). + */ def writeValue(base: source.Value, writeCallback: source.Value => Unit): Boolean } diff --git a/Modules/Reactives/shared/src/main/scala/reactives/core/Core.scala b/Modules/Reactives/shared/src/main/scala/reactives/core/Core.scala index e0194e624..5cd333730 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/core/Core.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/core/Core.scala @@ -60,8 +60,6 @@ trait ReadAs[+A] extends ReSource { } object ReadAs { type of[S[_], A] = ReadAs[A] { type State[V] = S[V] } } - - /** User facing low level API to access values in a static context. */ sealed abstract class StaticTicket[State[_]](val tx: Transaction[State]) { private[reactives] def collectStatic(reactive: ReSource.of[State]): reactive.Value diff --git a/Modules/Reactives/shared/src/main/scala/reactives/core/ScopeSearches.scala b/Modules/Reactives/shared/src/main/scala/reactives/core/ScopeSearches.scala index 623ddb23f..fcec4136e 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/core/ScopeSearches.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/core/ScopeSearches.scala @@ -77,6 +77,6 @@ object PlanTransactionScope { inline given search(using ts: TransactionSearch[Interface.State]): PlanTransactionScope[Interface.State] = ts.static match - case None => DynamicTransactionLookup(reactives.default.global.scheduler, reactives.default.global.dynamicScope) + case None => DynamicTransactionLookup(reactives.default.global.scheduler, reactives.default.global.dynamicScope) case Some(tx) => StaticInTransaction(tx, reactives.default.global.scheduler) } diff --git a/Modules/Reactives/shared/src/main/scala/reactives/extra/incremental/IncrementalBundle.scala b/Modules/Reactives/shared/src/main/scala/reactives/extra/incremental/IncrementalBundle.scala index 725627624..1481e94cd 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/extra/incremental/IncrementalBundle.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/extra/incremental/IncrementalBundle.scala @@ -7,7 +7,6 @@ import reactives.operator.* import scala.collection.mutable import scala.util.control.Breaks.{break, breakable} - /** @tparam T Type of values inside Deltas * @tparam S Structure of Reactive Sequence source */ diff --git a/Modules/Reactives/shared/src/main/scala/reactives/extra/reactor/ReactorBundle.scala b/Modules/Reactives/shared/src/main/scala/reactives/extra/reactor/ReactorBundle.scala index 014817518..d60e8754b 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/extra/reactor/ReactorBundle.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/extra/reactor/ReactorBundle.scala @@ -5,323 +5,323 @@ import reactives.macros.MacroAccess import reactives.operator.* import reactives.operator.Interface.State - class Reactor[T]( - initState: State[ReactorState[T]] - ) extends Derived with MacroAccess[T] { +class Reactor[T]( + initState: State[ReactorState[T]] +) extends Derived with MacroAccess[T] { - override type Value = ReactorState[T] - override type State[V] = Interface.State[V] + override type Value = ReactorState[T] + override type State[V] = Interface.State[V] - override protected[reactives] def state: State[ReactorState[T]] = initState + override protected[reactives] def state: State[ReactorState[T]] = initState - def info: ReInfo = ReInfo.create.derive("Custom Reactor") + def info: ReInfo = ReInfo.create.derive("Custom Reactor") - override def read(v: ReactorState[T]): T = v.currentValue + override def read(v: ReactorState[T]): T = v.currentValue - /** called if any of the dependencies changed in the current update turn, - * after all (known) dependencies are updated - */ - override protected[reactives] def reevaluate(input: ReIn): Rout = { + /** called if any of the dependencies changed in the current update turn, + * after all (known) dependencies are updated + */ + override protected[reactives] def reevaluate(input: ReIn): Rout = { - input.trackDependencies(Set()) + input.trackDependencies(Set()) - var progressedNextAction = false + var progressedNextAction = false - def processActions[A](currentState: ReactorState[T]): ReactorState[T] = { - def setAction(value: T, remainingActions: List[ReactorAction[T]]): ReactorState[T] = { - processActions(currentState.copy(currentValue = value, currentStage = Stage(remainingActions))) - } + def processActions[A](currentState: ReactorState[T]): ReactorState[T] = { + def setAction(value: T, remainingActions: List[ReactorAction[T]]): ReactorState[T] = { + processActions(currentState.copy(currentValue = value, currentStage = Stage(remainingActions))) + } - def nextAction[E](event: Event[E], handler: E => Stage[T]): ReactorState[T] = { - if (progressedNextAction) { - return currentState - } - - val eventValue: Option[E] = input.depend(event) - eventValue match { - case None => currentState - case Some(value) => - progressedNextAction = true - val stages = handler(value) - processActions(currentState.copy(currentStage = stages)) - } + def nextAction[E](event: Event[E], handler: E => Stage[T]): ReactorState[T] = { + if (progressedNextAction) { + return currentState } - def loopAction(loopStage: Stage[T], initialStage: Stage[T]): ReactorState[T] = { - val resultState = processActions(currentState.copy(currentStage = loopStage)) - if (resultState.currentStage.actions.isEmpty) { - return processActions(resultState.copy(currentStage = initialStage)) - } - - resultState.copy(currentStage = Stage(List(ReactorAction.LoopAction(resultState.currentStage, initialStage)))) + val eventValue: Option[E] = input.depend(event) + eventValue match { + case None => currentState + case Some(value) => + progressedNextAction = true + val stages = handler(value) + processActions(currentState.copy(currentStage = stages)) } + } - def untilAction[E](event: Event[E], body: Stage[T], interrupt: E => Stage[T]): ReactorState[T] = { - val eventValue = input.depend(event) - eventValue match { - case None => - val resultState = processActions(currentState.copy(currentStage = body)) - resultState.copy(currentStage = - Stage(List(ReactorAction.UntilAction(event, resultState.currentStage, interrupt))) - ) - case Some(value) => - val stages = interrupt(value) - processActions(currentState.copy(currentStage = stages)) - } + def loopAction(loopStage: Stage[T], initialStage: Stage[T]): ReactorState[T] = { + val resultState = processActions(currentState.copy(currentStage = loopStage)) + if (resultState.currentStage.actions.isEmpty) { + return processActions(resultState.copy(currentStage = initialStage)) } - def modifyAction(modifier: T => T, currentValue: T, tail: List[ReactorAction[T]]): ReactorState[T] = { - val modifiedValue = modifier(currentValue) - setAction(modifiedValue, tail) - } + resultState.copy(currentStage = Stage(List(ReactorAction.LoopAction(resultState.currentStage, initialStage)))) + } - def readAction(builder: T => Stage[T], currentValue: T): ReactorState[T] = { - val nextStage = builder(currentValue) - processActions(currentState.copy(currentStage = nextStage)) + def untilAction[E](event: Event[E], body: Stage[T], interrupt: E => Stage[T]): ReactorState[T] = { + val eventValue = input.depend(event) + eventValue match { + case None => + val resultState = processActions(currentState.copy(currentStage = body)) + resultState.copy(currentStage = + Stage(List(ReactorAction.UntilAction(event, resultState.currentStage, interrupt))) + ) + case Some(value) => + val stages = interrupt(value) + processActions(currentState.copy(currentStage = stages)) } + } - currentState.currentStage.actions match { - case Nil => currentState - case ReactorAction.SetAction(v) :: tail => - setAction(v, tail) - case ReactorAction.ModifyAction(modifier) :: tail => - modifyAction(modifier, currentState.currentValue, tail) - case ReactorAction.NextAction(event, handler) :: _ => - nextAction(event, handler) - case ReactorAction.ReadAction(builder) :: _ => - readAction(builder, currentState.currentValue) - case ReactorAction.LoopAction(loopStage, initialStage) :: _ => - loopAction(loopStage, initialStage) - case ReactorAction.UntilAction(event, body, interrupt) :: _ => - untilAction(event, body, interrupt) - } + def modifyAction(modifier: T => T, currentValue: T, tail: List[ReactorAction[T]]): ReactorState[T] = { + val modifiedValue = modifier(currentValue) + setAction(modifiedValue, tail) } - val resState = processActions(input.before) + def readAction(builder: T => Stage[T], currentValue: T): ReactorState[T] = { + val nextStage = builder(currentValue) + processActions(currentState.copy(currentStage = nextStage)) + } - input.withValue(resState) + currentState.currentStage.actions match { + case Nil => currentState + case ReactorAction.SetAction(v) :: tail => + setAction(v, tail) + case ReactorAction.ModifyAction(modifier) :: tail => + modifyAction(modifier, currentState.currentValue, tail) + case ReactorAction.NextAction(event, handler) :: _ => + nextAction(event, handler) + case ReactorAction.ReadAction(builder) :: _ => + readAction(builder, currentState.currentValue) + case ReactorAction.LoopAction(loopStage, initialStage) :: _ => + loopAction(loopStage, initialStage) + case ReactorAction.UntilAction(event, body, interrupt) :: _ => + untilAction(event, body, interrupt) + } } - def now(implicit scheduler: Scheduler[State]): T = scheduler.singleReadValueOnce(this) + val resState = processActions(input.before) + + input.withValue(resState) } - object Reactor { - - /** Creates a new Reactor, which steps through the reactor stages ones. - * - * @param initialValue The initial value of the Reactor. - * @param initialStage The Stage defining the Reactors behaviour. - * @tparam T The type of the Reactor value. - * @return The created Reactor. - */ - def once[T]( - initialValue: T - )(initialStage: Stage[T])(using creationTicket: CreationTicket[State]) = { - createReactor(initialValue, initialStage) - } + def now(implicit scheduler: Scheduler[State]): T = scheduler.singleReadValueOnce(this) +} + +object Reactor { + + /** Creates a new Reactor, which steps through the reactor stages ones. + * + * @param initialValue The initial value of the Reactor. + * @param initialStage The Stage defining the Reactors behaviour. + * @tparam T The type of the Reactor value. + * @return The created Reactor. + */ + def once[T]( + initialValue: T + )(initialStage: Stage[T])(using creationTicket: CreationTicket[State]) = { + createReactor(initialValue, initialStage) + } - /** Creates a new Reactor, which starts from the beginning, once it's finished. - * - * @param initialValue The initial value of the Reactor. - * @param initialStage The Stage defining the Reactors behaviour. - * @tparam T The type of the Reactor value. - * @return The created Reactor. - */ - def loop[T]( - initialValue: T - )(initialStage: Stage[T])(using creationTicket: CreationTicket[State]) = { - val loopingStage = initialStage.copy(List(ReactorAction.LoopAction(initialStage, initialStage))) - createReactor(initialValue, loopingStage) - } + /** Creates a new Reactor, which starts from the beginning, once it's finished. + * + * @param initialValue The initial value of the Reactor. + * @param initialStage The Stage defining the Reactors behaviour. + * @tparam T The type of the Reactor value. + * @return The created Reactor. + */ + def loop[T]( + initialValue: T + )(initialStage: Stage[T])(using creationTicket: CreationTicket[State]) = { + val loopingStage = initialStage.copy(List(ReactorAction.LoopAction(initialStage, initialStage))) + createReactor(initialValue, loopingStage) + } - private def createReactor[T](initialValue: T, initialStage: Stage[T])(implicit - ct: CreationTicket[State] - ): Reactor[T] = { - ct.scope.create( - Set(), - new ReactorState[T](initialValue, initialStage), - needsReevaluation = true - ) { (createdState: State[ReactorState[T]]) => - new Reactor[T](createdState) - } + private def createReactor[T](initialValue: T, initialStage: Stage[T])(implicit + ct: CreationTicket[State] + ): Reactor[T] = { + ct.scope.create( + Set(), + new ReactorState[T](initialValue, initialStage), + needsReevaluation = true + ) { (createdState: State[ReactorState[T]]) => + new Reactor[T](createdState) } } +} - sealed trait ReactorAction[T] {} +sealed trait ReactorAction[T] {} - object ReactorAction { - case class SetAction[T](res: T) extends ReactorAction[T] +object ReactorAction { + case class SetAction[T](res: T) extends ReactorAction[T] - case class ModifyAction[T](modifier: T => T) extends ReactorAction[T] + case class ModifyAction[T](modifier: T => T) extends ReactorAction[T] - case class NextAction[T, E](event: Event[E], handler: E => Stage[T]) - extends ReactorAction[T] + case class NextAction[T, E](event: Event[E], handler: E => Stage[T]) + extends ReactorAction[T] - case class ReadAction[T](stageBuilder: T => Stage[T]) extends ReactorAction[T] + case class ReadAction[T](stageBuilder: T => Stage[T]) extends ReactorAction[T] - case class LoopAction[T](currentStage: Stage[T], initialStage: Stage[T]) extends ReactorAction[T] + case class LoopAction[T](currentStage: Stage[T], initialStage: Stage[T]) extends ReactorAction[T] - case class UntilAction[T, E](event: Event[E], body: Stage[T], interrupt: E => Stage[T]) - extends ReactorAction[T] - } + case class UntilAction[T, E](event: Event[E], body: Stage[T], interrupt: E => Stage[T]) + extends ReactorAction[T] +} - case class ReactorState[T](currentValue: T, currentStage: Stage[T]) {} +case class ReactorState[T](currentValue: T, currentStage: Stage[T]) {} - case class Stage[T](actions: List[ReactorAction[T]] = Nil) { +case class Stage[T](actions: List[ReactorAction[T]] = Nil) { - private def addAction(newValue: ReactorAction[T]): Stage[T] = { - copy(actions = actions :+ newValue) - } + private def addAction(newValue: ReactorAction[T]): Stage[T] = { + copy(actions = actions :+ newValue) + } - /** Sets the value of the Reactor. - * - * @param newValue The new value of the Reactor. - * @return A StageBuilder describing the Reactor behaviour. - */ - def set(newValue: T): Stage[T] = { - addAction(ReactorAction.SetAction(newValue)) - } + /** Sets the value of the Reactor. + * + * @param newValue The new value of the Reactor. + * @return A StageBuilder describing the Reactor behaviour. + */ + def set(newValue: T): Stage[T] = { + addAction(ReactorAction.SetAction(newValue)) + } - /** Modifies the value of the Reactor. - * - * @param modifier A function that has the old Reactor value as input and returns a new Reactor value. - * @return A StageBuilder describing the Reactor behaviour. - */ - def modify(modifier: T => T): Stage[T] = { - addAction(ReactorAction.ModifyAction(modifier)) - } + /** Modifies the value of the Reactor. + * + * @param modifier A function that has the old Reactor value as input and returns a new Reactor value. + * @return A StageBuilder describing the Reactor behaviour. + */ + def modify(modifier: T => T): Stage[T] = { + addAction(ReactorAction.ModifyAction(modifier)) + } - /** Waits until the event is triggered. - * - * When the event is triggered the given body is executed in the - * same transaction. - * - * @param event the event to wait for. - * @param body the code to execute when the event is triggered. - * @tparam E the event's type. - */ - def next[E](event: Event[E])(body: E => Stage[T]): Stage[T] = { - addAction(ReactorAction.NextAction(event, body)) - } + /** Waits until the event is triggered. + * + * When the event is triggered the given body is executed in the + * same transaction. + * + * @param event the event to wait for. + * @param body the code to execute when the event is triggered. + * @tparam E the event's type. + */ + def next[E](event: Event[E])(body: E => Stage[T]): Stage[T] = { + addAction(ReactorAction.NextAction(event, body)) + } - /** Waits until the event is triggered. - * - * When the event is triggered the given body is executed in the - * same transaction. - * - * @param event the event to wait for. - * @param body the code to execute when the event is triggered. - */ - def next(event: Event[Unit])(body: => Stage[T]): Stage[T] = { - addAction(ReactorAction.NextAction(event, (_: Unit) => body)) - } + /** Waits until the event is triggered. + * + * When the event is triggered the given body is executed in the + * same transaction. + * + * @param event the event to wait for. + * @param body the code to execute when the event is triggered. + */ + def next(event: Event[Unit])(body: => Stage[T]): Stage[T] = { + addAction(ReactorAction.NextAction(event, (_: Unit) => body)) + } - /** Reads the current reactor value. - * - * Executes the body with the current reactor value - * and expects another [[Stage]] as result. - * - * A usage example could be returning different [[Stage]]s - * depending on the event value. - * - * @param body The function building the resulting [[Stage]] - */ - def read(body: T => Stage[T]): Stage[T] = { - addAction(ReactorAction.ReadAction(body)) - } + /** Reads the current reactor value. + * + * Executes the body with the current reactor value + * and expects another [[Stage]] as result. + * + * A usage example could be returning different [[Stage]]s + * depending on the event value. + * + * @param body The function building the resulting [[Stage]] + */ + def read(body: T => Stage[T]): Stage[T] = { + addAction(ReactorAction.ReadAction(body)) + } - /** Executes the body in a loop. - * - * @param body The [[Stage]] to be executes repeatedly - */ - def loop(body: => Stage[T]): Stage[T] = { - addAction(ReactorAction.LoopAction(body, body)) - } + /** Executes the body in a loop. + * + * @param body The [[Stage]] to be executes repeatedly + */ + def loop(body: => Stage[T]): Stage[T] = { + addAction(ReactorAction.LoopAction(body, body)) + } - /** Executes it's body until an event is fired. - * - * Until executes the body until the given event is fired. - * When the event is fired, until executes the interruptHandler. - * - * @param event The event indicating the interrupt. - * @param body The [[Stage]] to be executes by default. - * @param interruptHandler A function taking the interrupt event's value - * and returning a [[Stage]]. - * It is executed when the interrupt is fired. - * @tparam E The type of the event value. - */ - def until[E](event: Event[E], body: => Stage[T], interruptHandler: E => Stage[T]): Stage[T] = { - addAction(ReactorAction.UntilAction(event, body, interruptHandler)) - } + /** Executes it's body until an event is fired. + * + * Until executes the body until the given event is fired. + * When the event is fired, until executes the interruptHandler. + * + * @param event The event indicating the interrupt. + * @param body The [[Stage]] to be executes by default. + * @param interruptHandler A function taking the interrupt event's value + * and returning a [[Stage]]. + * It is executed when the interrupt is fired. + * @tparam E The type of the event value. + */ + def until[E](event: Event[E], body: => Stage[T], interruptHandler: E => Stage[T]): Stage[T] = { + addAction(ReactorAction.UntilAction(event, body, interruptHandler)) + } - /** Executes it's body until an event is fired. - * - * Until executes the body until the given event is fired. - * When the event is fired, until executes the interruptHandler. - * - * @param event The event indicating the interrupt. - * @param body The [[Stage]] to be executes by default. - * @param interruptHandler A function taking the interrupt event's value - * and returning a [[Stage]]. - * It is executed when the interrupt is fired. - */ - def until(event: Event[Unit], body: => Stage[T], interruptHandler: Stage[T]): Stage[T] = { - val handler = { (_: Unit) => interruptHandler } - addAction(ReactorAction.UntilAction(event, body, handler)) - } + /** Executes it's body until an event is fired. + * + * Until executes the body until the given event is fired. + * When the event is fired, until executes the interruptHandler. + * + * @param event The event indicating the interrupt. + * @param body The [[Stage]] to be executes by default. + * @param interruptHandler A function taking the interrupt event's value + * and returning a [[Stage]]. + * It is executed when the interrupt is fired. + */ + def until(event: Event[Unit], body: => Stage[T], interruptHandler: Stage[T]): Stage[T] = { + val handler = { (_: Unit) => interruptHandler } + addAction(ReactorAction.UntilAction(event, body, handler)) + } - /** Executes it's body until an event is fired. - * - * Until executes the body until the given event is fired. - * - * @param event The event indicating the interrupt. - * @param body The [[Stage]] to be executes by default. - * @tparam E The type of the event value. - */ - def until(event: Event[Any], body: => Stage[T]): Stage[T] = { - val interrupHandler = { (_: Any) => Stage[T]() } - addAction(ReactorAction.UntilAction(event, body, interrupHandler)) - } + /** Executes it's body until an event is fired. + * + * Until executes the body until the given event is fired. + * + * @param event The event indicating the interrupt. + * @param body The [[Stage]] to be executes by default. + * @tparam E The type of the event value. + */ + def until(event: Event[Any], body: => Stage[T]): Stage[T] = { + val interrupHandler = { (_: Any) => Stage[T]() } + addAction(ReactorAction.UntilAction(event, body, interrupHandler)) } +} - object S { - def set[T](newValue: T): Stage[T] = { - Stage().set(newValue) - } +object S { + def set[T](newValue: T): Stage[T] = { + Stage().set(newValue) + } - def modify[T](modifier: T => T): Stage[T] = { - Stage().modify(modifier) - } + def modify[T](modifier: T => T): Stage[T] = { + Stage().modify(modifier) + } - def next[T, E](event: Event[E])(body: E => Stage[T]): Stage[T] = { - Stage().next(event)(body) - } + def next[T, E](event: Event[E])(body: E => Stage[T]): Stage[T] = { + Stage().next(event)(body) + } - def next[T](event: Event[Unit])(body: => Stage[T]): Stage[T] = { - Stage().next(event)(body) - } + def next[T](event: Event[Unit])(body: => Stage[T]): Stage[T] = { + Stage().next(event)(body) + } - def read[T](body: T => Stage[T]): Stage[T] = { - Stage().read(body) - } + def read[T](body: T => Stage[T]): Stage[T] = { + Stage().read(body) + } - def loop[T](body: => Stage[T]): Stage[T] = { - Stage().loop(body) - } + def loop[T](body: => Stage[T]): Stage[T] = { + Stage().loop(body) + } - def until[T, E](event: Event[E], body: => Stage[T], interruptHandler: E => Stage[T]): Stage[T] = { - Stage().until(event, body, interruptHandler) - } + def until[T, E](event: Event[E], body: => Stage[T], interruptHandler: E => Stage[T]): Stage[T] = { + Stage().until(event, body, interruptHandler) + } - def until[T](event: Event[Unit], body: => Stage[T], interruptHandler: Stage[T]): Stage[T] = { - Stage().until(event, body, interruptHandler) - } + def until[T](event: Event[Unit], body: => Stage[T], interruptHandler: Stage[T]): Stage[T] = { + Stage().until(event, body, interruptHandler) + } - def until[T](event: Event[Any], body: => Stage[T]): Stage[T] = { - Stage().until(event, body) - } + def until[T](event: Event[Any], body: => Stage[T]): Stage[T] = { + Stage().until(event, body) + } - def end[T]: Stage[T] = { - Stage() - } + def end[T]: Stage[T] = { + Stage() } +} diff --git a/Modules/Reactives/shared/src/main/scala/reactives/operator/Fold.scala b/Modules/Reactives/shared/src/main/scala/reactives/operator/Fold.scala index e7bed2aac..78c6ce952 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/operator/Fold.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/operator/Fold.scala @@ -55,7 +55,6 @@ object Fold { inline def current[S](using fs: FoldState[S]): S = FoldState.unwrap(fs) - } opaque type FoldState[T] = () => T diff --git a/Modules/Reactives/shared/src/main/scala/reactives/operator/Interface.scala b/Modules/Reactives/shared/src/main/scala/reactives/operator/Interface.scala index cdf8fd4e4..4dcb09526 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/operator/Interface.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/operator/Interface.scala @@ -18,7 +18,8 @@ trait Interface { export Fold.current extension [T](e: Event[T]) { - inline infix def act[S](inline f: FoldState[S] ?=> T => S): Fold.Branch[S] = Fold.branch { e.value.fold(current)(f) } + inline infix def act[S](inline f: FoldState[S] ?=> T => S): Fold.Branch[S] = + Fold.branch { e.value.fold(current)(f) } } val global: GlobalCandidate[GlobalCandidate.selected.State] = GlobalCandidate.selected diff --git a/Modules/Reactives/shared/src/main/scala/reactives/scheduler/CalculusLike.scala b/Modules/Reactives/shared/src/main/scala/reactives/scheduler/CalculusLike.scala index 2526f702e..ae8dfd303 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/scheduler/CalculusLike.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/scheduler/CalculusLike.scala @@ -4,8 +4,8 @@ package reactives.scheduler import reactives.core.{ - AccessHandler, AdmissionTicket, Derived, Initializer, Observation, ReSource, ReadAs, ReevTicket, SchedulerWithDynamicScope, - Transaction + AccessHandler, AdmissionTicket, Derived, Initializer, Observation, ReSource, ReadAs, ReevTicket, + SchedulerWithDynamicScope, Transaction } object CalculusLike { @@ -70,7 +70,7 @@ object CalculusLike { case class FTransaction(override val initializer: Initializer[CalculusLike.this.State]) extends Transaction[State] { override private[reactives] def access(reactive: ReSource.of[State]): reactive.Value = reactive.state.value - override def observe(obs: Observation): Unit = obs.execute() + override def observe(obs: Observation): Unit = obs.execute() } object FScheduler diff --git a/Modules/Reactives/shared/src/main/scala/reactives/scheduler/TopoBundle.scala b/Modules/Reactives/shared/src/main/scala/reactives/scheduler/TopoBundle.scala index 40417797f..aa22db1a4 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/scheduler/TopoBundle.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/scheduler/TopoBundle.scala @@ -1,7 +1,8 @@ package reactives.scheduler import reactives.core.{ - AccessHandler, AdmissionTicket, Initializer, Observation, ReSource, ReadAs, ReevTicket, SchedulerWithDynamicScope, Transaction + AccessHandler, AdmissionTicket, Initializer, Observation, ReSource, ReadAs, ReevTicket, SchedulerWithDynamicScope, + Transaction } import scala.collection.mutable.{ArrayBuffer, ListBuffer} diff --git a/Modules/Reactives/shared/src/main/scala/reactives/scheduler/Twoversion.scala b/Modules/Reactives/shared/src/main/scala/reactives/scheduler/Twoversion.scala index 1f0db4f71..9dcdb132c 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/scheduler/Twoversion.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/scheduler/Twoversion.scala @@ -2,8 +2,8 @@ package reactives.scheduler import reactives.core import reactives.core.{ - AccessHandler, AdmissionTicket, InitialChange, Observation, ReSource, ReadAs, ReevTicket, SchedulerWithDynamicScope, Tracing, - Transaction + AccessHandler, AdmissionTicket, InitialChange, Observation, ReSource, ReadAs, ReevTicket, SchedulerWithDynamicScope, + Tracing, Transaction } import scala.collection.mutable.ListBuffer diff --git a/Modules/Reactives/shared/src/main/scala/reactives/structure/DerivedImpl.scala b/Modules/Reactives/shared/src/main/scala/reactives/structure/DerivedImpl.scala index 2b61cc35c..8989733a1 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/structure/DerivedImpl.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/structure/DerivedImpl.scala @@ -5,7 +5,6 @@ import reactives.operator.Interface import reactives.structure.Pulse.NoChange import reactives.operator.Interface.State - abstract class DerivedImpl[T]( initial: State[Pulse[T]], name: ReInfo, diff --git a/Modules/Reactives/shared/src/main/scala/reactives/structure/Diff.scala b/Modules/Reactives/shared/src/main/scala/reactives/structure/Diff.scala index f5f0e3ca0..10d5175dd 100644 --- a/Modules/Reactives/shared/src/main/scala/reactives/structure/Diff.scala +++ b/Modules/Reactives/shared/src/main/scala/reactives/structure/Diff.scala @@ -12,7 +12,8 @@ final class Diff[+A](val from: Pulse[A], val to: Pulse[A]) { val left = from.get left -> right } catch { - case EmptySignalControlThrowable(info) => throw new NoSuchElementException(s"Can not convert $this to pair (empty propagated from $info)") + case EmptySignalControlThrowable(info) => + throw new NoSuchElementException(s"Can not convert $this to pair (empty propagated from $info)") } } diff --git a/Modules/Reactives/shared/src/test/scala/reactives/core/tests/WithoutAPITest.scala b/Modules/Reactives/shared/src/test/scala/reactives/core/tests/WithoutAPITest.scala index 1d57aacf7..bfb3bd678 100644 --- a/Modules/Reactives/shared/src/test/scala/reactives/core/tests/WithoutAPITest.scala +++ b/Modules/Reactives/shared/src/test/scala/reactives/core/tests/WithoutAPITest.scala @@ -16,8 +16,8 @@ class WithoutAPITest extends RETests { override type Value = T override protected[reactives] def state: State[T] = initState - override val info: ReInfo = ReInfo.create - override def read(v: Value): T = v + override val info: ReInfo = ReInfo.create + override def read(v: Value): T = v override protected[reactives] def commit(base: Value): Value = base def makeChange(newValue: T) = @@ -40,7 +40,7 @@ class WithoutAPITest extends RETests { override type Value = String override type State[V] = Interface.State[V] override protected[reactives] def state: State[Value] = initState - override val info: ReInfo = ReInfo.create + override val info: ReInfo = ReInfo.create override protected[reactives] def commit(base: Value): Value = base override protected[reactives] def reevaluate(input: ReIn): Rout = { diff --git a/Modules/Reactives/shared/src/test/scala/reactives/extra/invariant/InvariantBundle.scala b/Modules/Reactives/shared/src/test/scala/reactives/extra/invariant/InvariantBundle.scala index f18c1df4c..75180fdb0 100644 --- a/Modules/Reactives/shared/src/test/scala/reactives/extra/invariant/InvariantBundle.scala +++ b/Modules/Reactives/shared/src/test/scala/reactives/extra/invariant/InvariantBundle.scala @@ -22,7 +22,7 @@ class Invariant[T](val description: String, val inv: T => Boolean) { trait InvariantBundle extends TopoBundle { - override type State[V] = InvariantState[V] + override type State[V] = InvariantState[V] sealed trait InvariantException extends RuntimeException @@ -67,7 +67,9 @@ trait InvariantBundle extends TopoBundle { override def beforeCleanupHook(all: Seq[ReSource], initialWrites: Set[ReSource]): Unit = InvariantUtil.evaluateInvariants(all, initialWrites) - implicit class SignalWithInvariants[T](val signal: ReSource{type State[V] = InvariantState[V]; type Value = Pulse[T]}) { + implicit class SignalWithInvariants[T](val signal: ReSource { + type State[V] = InvariantState[V]; type Value = Pulse[T] + }) { def specify(inv: Invariant[T]*): Unit = { signal.state.invariants = diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/dynamic/TrueDynamicSignals.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/dynamic/TrueDynamicSignals.scala index 572e708d7..99ff13865 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/dynamic/TrueDynamicSignals.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/dynamic/TrueDynamicSignals.scala @@ -7,290 +7,289 @@ import reactives.operator.Interface import reactives.scheduler.Levelbased import reactives.default.global.State as BundleState - class TrueDynamicSignals extends RETests { - val ie = new Infiltrator(reactives.default) - import ie.assertLevel - import ie.api._ - - test("signals Nested In Vars") { + val ie = new Infiltrator(reactives.default) + import ie.assertLevel + import ie.api._ - val a = Var(3) - val b = Var(Signal(a.value)) - val c = Signal.dynamic(b.value.value) + test("signals Nested In Vars") { - assertEquals(c.readValueOnce, 3) - a set 4 - assertEquals(c.readValueOnce, 4) - b set Signal(5) - assertEquals(c.readValueOnce, 5) + val a = Var(3) + val b = Var(Signal(a.value)) + val c = Signal.dynamic(b.value.value) - } + assertEquals(c.readValueOnce, 3) + a set 4 + assertEquals(c.readValueOnce, 4) + b set Signal(5) + assertEquals(c.readValueOnce, 5) - test("nested Defined Signals") { - val a = Var(3) - val b = Signal.dynamic { - val c = Signal { a.value } - c.value - } + } - assertEquals(b.readValueOnce, 3) - a set 4 - assertEquals(b.readValueOnce, 4) - a set 5 - assertEquals(b.readValueOnce, 5) + test("nested Defined Signals") { + val a = Var(3) + val b = Signal.dynamic { + val c = Signal { a.value } + c.value } - test("use Of Inside Signal") { - val outside = Var(1) - val inside = Var(10) + assertEquals(b.readValueOnce, 3) + a set 4 + assertEquals(b.readValueOnce, 4) + a set 5 + assertEquals(b.readValueOnce, 5) + } - def sig = Signal { outside.value } + test("use Of Inside Signal") { + val outside = Var(1) + val inside = Var(10) - val testsig = Signal.dynamic { - def sig = Signal { inside.value } - sig.value - } + def sig = Signal { outside.value } - assertEquals(testsig.readValueOnce, 10) - outside set 2 - inside set 11 - assertEquals(testsig.readValueOnce, 11) - assertEquals(sig.readValueOnce, 2) + val testsig = Signal.dynamic { + def sig = Signal { inside.value } + sig.value } - test("use Of Outside Signal") { - val outside = Var(1) - val inside = Var(10) - - def sig()(implicit turnSource: CreationTicket[global.State]) = Signal { outside.value } + assertEquals(testsig.readValueOnce, 10) + outside set 2 + inside set 11 + assertEquals(testsig.readValueOnce, 11) + assertEquals(sig.readValueOnce, 2) + } - val testsig = Signal.dynamic { - { - def insideSig = Signal { inside.value } - insideSig.value - } - sig().value - } + test("use Of Outside Signal") { + val outside = Var(1) + val inside = Var(10) - assertEquals(testsig.readValueOnce, 1) - outside set 2 - inside set 11 - assertEquals(testsig.readValueOnce, 2) - } + def sig()(implicit turnSource: CreationTicket[global.State]) = Signal { outside.value } - test("outer And Inner Values") { - val v = Var(0) - object obj { - def sig(implicit ct: CreationTicket[BundleState]) = Signal { v.value } + val testsig = Signal.dynamic { + { + def insideSig = Signal { inside.value } + insideSig.value } + sig().value + } - val evt = Evt[Int]() - val testsig = Signal.dynamic { - obj.sig.value + (evt `hold` -1).value - } + assertEquals(testsig.readValueOnce, 1) + outside set 2 + inside set 11 + assertEquals(testsig.readValueOnce, 2) + } - assertEquals(testsig.readValueOnce, -1) - evt.fire(100) - assertEquals(testsig.readValueOnce, 100) - v set 10 - assertEquals(testsig.readValueOnce, 110) - evt.fire(10) - assertEquals(testsig.readValueOnce, 20) - evt.fire(5) - assertEquals(testsig.readValueOnce, 15) - v set 50 - assertEquals(testsig.readValueOnce, 55) + test("outer And Inner Values") { + val v = Var(0) + object obj { + def sig(implicit ct: CreationTicket[BundleState]) = Signal { v.value } } - // test("chained Signals2") { - // - // import scala.language.reflectiveCalls - // - // val v1 = Var { 20 } - // val v2 = Var { new { def signal(implicit ct: CreationTicket[REState]) = Signal { v1() } } } - // val v3 = Var { new { val signal = Signal { v2() } } } - // - // val s = Signal { v3() } - // - // val sig = Signal.dynamic { s().signal().signal.value } - // - // assertEquals(sig.readValueOnce, 20) - // v1 set 30 - // assertEquals(sig.readValueOnce, 30) - // v2 set new { def signal(implicit ct: CreationTicket[REState]) = Signal { 7 + v1() } } - // assertEquals(sig.readValueOnce, 37) - // v1 set 10 - // assertEquals(sig.readValueOnce, 17) - // v3 set new { val signal = Signal { new { def signal(implicit ct: CreationTicket[REState]) = Signal { v1() } } } } - // assertEquals(sig.readValueOnce, 10) - // v2 set new { def signal(implicit ct: CreationTicket[REState]) = Signal { 10 + v1() } } - // assertEquals(sig.readValueOnce, 10) - // v1 set 80 - // assertEquals(sig.readValueOnce, 80) - // } - - test("extracting Signal Side Effects") { - val e1 = Evt[Int]() - def newSignal()(implicit ct: CreationTicket[BundleState]): Signal[Int] = e1.count() - - val macroRes = Signal { - newSignal().value - } - val normalRes = Signal.dynamic() { implicit t: DynamicTicket[BundleState] => - t.depend(newSignal()) - } - assertEquals(macroRes.readValueOnce, 0, "before, macro") - assertEquals(normalRes.readValueOnce, 0, "before, normal") - e1.fire(1) - assertEquals(macroRes.readValueOnce, 1, "after, macro") - assertEquals(normalRes.readValueOnce, 1, "after, normal") - e1.fire(1) - assertEquals(macroRes.readValueOnce, 2, "end, macro") - assertEquals(normalRes.readValueOnce, 1, "end, normal") + val evt = Evt[Int]() + val testsig = Signal.dynamic { + obj.sig.value + (evt `hold` -1).value } - // test("chained Signals1") { - // - // import scala.language.reflectiveCalls - // - // val v1 = Var { 1 } - // val v2 = Var { 2 } - // val v = Var { List(new { val s = v1 }, new { val s = v2 }) } - // - // val sig = Signal.dynamic { v() map (_.s()) } - // - // assertEquals(sig.readValueOnce, List(1, 2)) - // v1 set 5 - // assertEquals(sig.readValueOnce, List(5, 2)) - // v2 set 7 - // assertEquals(sig.readValueOnce, List(5, 7)) - // v set v.readValueOnce.reverse - // assertEquals(sig.readValueOnce, List(7, 5)) - // } - - test("signal Does Not Reevaluate The Expression If Depends On IsUpdated That Is Not In Current Dependencies") { - val condition = Var(true) - val ifTrue = Var(0) - val ifFalse = Var(10) - var reevaluations = 0 - val s = Signal.dynamic(condition) { (dt: DynamicTicket[BundleState]) => - reevaluations += 1 - if (dt.depend(condition)) dt.depend(ifTrue) else dt.depend(ifFalse) - } - - assert(reevaluations == 1) - assert(s.readValueOnce == 0) - ifTrue.set(1) - assert(reevaluations == 2) - assert(s.readValueOnce == 1) - ifFalse.set(11) // No effect - assert(reevaluations == 2) - assert(s.readValueOnce == 1) - - condition.set(false) - assert(s.readValueOnce == 11) - assert(reevaluations == 3) - ifFalse.set(12) - assert(s.readValueOnce == 12) - assert(reevaluations == 4) - ifTrue.set(2) // No effect - assert(s.readValueOnce == 12) - assert(reevaluations == 4) + assertEquals(testsig.readValueOnce, -1) + evt.fire(100) + assertEquals(testsig.readValueOnce, 100) + v set 10 + assertEquals(testsig.readValueOnce, 110) + evt.fire(10) + assertEquals(testsig.readValueOnce, 20) + evt.fire(5) + assertEquals(testsig.readValueOnce, 15) + v set 50 + assertEquals(testsig.readValueOnce, 55) + } + + // test("chained Signals2") { + // + // import scala.language.reflectiveCalls + // + // val v1 = Var { 20 } + // val v2 = Var { new { def signal(implicit ct: CreationTicket[REState]) = Signal { v1() } } } + // val v3 = Var { new { val signal = Signal { v2() } } } + // + // val s = Signal { v3() } + // + // val sig = Signal.dynamic { s().signal().signal.value } + // + // assertEquals(sig.readValueOnce, 20) + // v1 set 30 + // assertEquals(sig.readValueOnce, 30) + // v2 set new { def signal(implicit ct: CreationTicket[REState]) = Signal { 7 + v1() } } + // assertEquals(sig.readValueOnce, 37) + // v1 set 10 + // assertEquals(sig.readValueOnce, 17) + // v3 set new { val signal = Signal { new { def signal(implicit ct: CreationTicket[REState]) = Signal { v1() } } } } + // assertEquals(sig.readValueOnce, 10) + // v2 set new { def signal(implicit ct: CreationTicket[REState]) = Signal { 10 + v1() } } + // assertEquals(sig.readValueOnce, 10) + // v1 set 80 + // assertEquals(sig.readValueOnce, 80) + // } + + test("extracting Signal Side Effects") { + val e1 = Evt[Int]() + def newSignal()(implicit ct: CreationTicket[BundleState]): Signal[Int] = e1.count() + + val macroRes = Signal { + newSignal().value } - - test("basic Higher Order Signal can Be Accessed") { - val v = Var(42) - val s1: Signal[Int] = v.map(identity) - val s2: Signal[Signal[Int]] = Signal.dynamic() { _ => s1 } - - assert(s2.readValueOnce.readValueOnce == 42) - - v.set(0) - assert(s2.readValueOnce.readValueOnce == 0) + val normalRes = Signal.dynamic() { implicit t: DynamicTicket[BundleState] => + t.depend(newSignal()) + } + assertEquals(macroRes.readValueOnce, 0, "before, macro") + assertEquals(normalRes.readValueOnce, 0, "before, normal") + e1.fire(1) + assertEquals(macroRes.readValueOnce, 1, "after, macro") + assertEquals(normalRes.readValueOnce, 1, "after, normal") + e1.fire(1) + assertEquals(macroRes.readValueOnce, 2, "end, macro") + assertEquals(normalRes.readValueOnce, 1, "end, normal") + } + + // test("chained Signals1") { + // + // import scala.language.reflectiveCalls + // + // val v1 = Var { 1 } + // val v2 = Var { 2 } + // val v = Var { List(new { val s = v1 }, new { val s = v2 }) } + // + // val sig = Signal.dynamic { v() map (_.s()) } + // + // assertEquals(sig.readValueOnce, List(1, 2)) + // v1 set 5 + // assertEquals(sig.readValueOnce, List(5, 2)) + // v2 set 7 + // assertEquals(sig.readValueOnce, List(5, 7)) + // v set v.readValueOnce.reverse + // assertEquals(sig.readValueOnce, List(7, 5)) + // } + + test("signal Does Not Reevaluate The Expression If Depends On IsUpdated That Is Not In Current Dependencies") { + val condition = Var(true) + val ifTrue = Var(0) + val ifFalse = Var(10) + var reevaluations = 0 + val s = Signal.dynamic(condition) { (dt: DynamicTicket[BundleState]) => + reevaluations += 1 + if (dt.depend(condition)) dt.depend(ifTrue) else dt.depend(ifFalse) } - test("creating Signals Inside Signals") { - val outside = Var(1) - - val testsig = Signal.dynamic() { implicit to => - // remark 01.10.2014: without the bound the inner signal will be enqueued (it is level 0 same as its dependency) - // this will cause testsig to reevaluate again, after the inner signal is fully updated. - // leading to an infinite loop - to.depend(Signal.dynamic(outside) { ti => ti.depend(outside) }) - } - - assertEquals(testsig.readValueOnce, 1) - outside set 2 - assertEquals(testsig.readValueOnce, 2) + assert(reevaluations == 1) + assert(s.readValueOnce == 0) + ifTrue.set(1) + assert(reevaluations == 2) + assert(s.readValueOnce == 1) + ifFalse.set(11) // No effect + assert(reevaluations == 2) + assert(s.readValueOnce == 1) + + condition.set(false) + assert(s.readValueOnce == 11) + assert(reevaluations == 3) + ifFalse.set(12) + assert(s.readValueOnce == 12) + assert(reevaluations == 4) + ifTrue.set(2) // No effect + assert(s.readValueOnce == 12) + assert(reevaluations == 4) + } + + test("basic Higher Order Signal can Be Accessed") { + val v = Var(42) + val s1: Signal[Int] = v.map(identity) + val s2: Signal[Signal[Int]] = Signal.dynamic() { _ => s1 } + + assert(s2.readValueOnce.readValueOnce == 42) + + v.set(0) + assert(s2.readValueOnce.readValueOnce == 0) + } + + test("creating Signals Inside Signals") { + val outside = Var(1) + + val testsig = Signal.dynamic() { implicit to => + // remark 01.10.2014: without the bound the inner signal will be enqueued (it is level 0 same as its dependency) + // this will cause testsig to reevaluate again, after the inner signal is fully updated. + // leading to an infinite loop + to.depend(Signal.dynamic(outside) { ti => ti.depend(outside) }) } - test("dynamic dependency changes on top of stuff that is not changing") { - val v0 = Var("level 0") - val v3 = v0.map(_ => "level 1").map(_ => "level 2").map(_ => "level 3") + assertEquals(testsig.readValueOnce, 1) + outside set 2 + assertEquals(testsig.readValueOnce, 2) + } - val condition = Var(false) - val `dynamic signal changing from level 1 to level 4` = Signal.dynamic(condition) { t => - if (t.depend(condition)) t.depend(v3) else t.depend(v0) - } - assert(`dynamic signal changing from level 1 to level 4`.readValueOnce == "level 0") - assertLevel(`dynamic signal changing from level 1 to level 4`, 1) + test("dynamic dependency changes on top of stuff that is not changing") { + val v0 = Var("level 0") + val v3 = v0.map(_ => "level 1").map(_ => "level 2").map(_ => "level 3") - condition.set(true) - assert(`dynamic signal changing from level 1 to level 4`.readValueOnce == "level 3") - assertLevel(`dynamic signal changing from level 1 to level 4`, 4) + val condition = Var(false) + val `dynamic signal changing from level 1 to level 4` = Signal.dynamic(condition) { t => + if (t.depend(condition)) t.depend(v3) else t.depend(v0) } - - test("creating signals in signals based on changing signals dynamic") { - val v0 = Var("level 0") - val v3 = v0.map(_ + "level 1").map(_ + "level 2").map(_ + "level 3") - - val `dynamic signal changing from level 1 to level 4` = Signal.dynamic() { implicit ticket => - if (ticket.depend(v0) == "level 0") ticket.depend(v0) - else { - // the static bound is necessary here, otherwise we get infinite loops - ticket.depend(Signal.dynamic(v3) { t => t.depend(v3) + "level 4 inner" }) - } + assert(`dynamic signal changing from level 1 to level 4`.readValueOnce == "level 0") + assertLevel(`dynamic signal changing from level 1 to level 4`, 1) + + condition.set(true) + assert(`dynamic signal changing from level 1 to level 4`.readValueOnce == "level 3") + assertLevel(`dynamic signal changing from level 1 to level 4`, 4) + } + + test("creating signals in signals based on changing signals dynamic") { + val v0 = Var("level 0") + val v3 = v0.map(_ + "level 1").map(_ + "level 2").map(_ + "level 3") + + val `dynamic signal changing from level 1 to level 4` = Signal.dynamic() { implicit ticket => + if (ticket.depend(v0) == "level 0") ticket.depend(v0) + else { + // the static bound is necessary here, otherwise we get infinite loops + ticket.depend(Signal.dynamic(v3) { t => t.depend(v3) + "level 4 inner" }) } - assert(`dynamic signal changing from level 1 to level 4`.readValueOnce == "level 0") - assertLevel(`dynamic signal changing from level 1 to level 4`, 1) - - v0.set("level0+") - assert( - `dynamic signal changing from level 1 to level 4`.readValueOnce == "level0+level 1level 2level 3level 4 inner" - ) - assertLevel(`dynamic signal changing from level 1 to level 4`, 5) } + assert(`dynamic signal changing from level 1 to level 4`.readValueOnce == "level 0") + assertLevel(`dynamic signal changing from level 1 to level 4`, 1) + + v0.set("level0+") + assert( + `dynamic signal changing from level 1 to level 4`.readValueOnce == "level0+level 1level 2level 3level 4 inner" + ) + assertLevel(`dynamic signal changing from level 1 to level 4`, 5) + } + + test("graph cost example") { + + def mini(x: Var[Map[Signal[Int], Int]]): Signal[Int] = + Signal.dynamic { + val (node, value) = x.value.minBy { case (n, v) => n.value + v } + node.value + value + } - test("graph cost example") { - - def mini(x: Var[Map[Signal[Int], Int]]): Signal[Int] = - Signal.dynamic { - val (node, value) = x.value.minBy { case (n, v) => n.value + v } - node.value + value - } - - val root = Signal { 0 } + val root = Signal { 0 } - val parentA = Var(Map(root -> 2)) - val WeightA = mini(parentA) + val parentA = Var(Map(root -> 2)) + val WeightA = mini(parentA) - assert(WeightA.readValueOnce == 2) + assert(WeightA.readValueOnce == 2) - val parentB = Var(Map(root -> 1)) - val WeightB = mini(parentB) + val parentB = Var(Map(root -> 1)) + val WeightB = mini(parentB) - assert(WeightB.readValueOnce == 1) + assert(WeightB.readValueOnce == 1) - val parentC = Var(Map(WeightA -> 3, WeightB -> 10)) - val WeightC = mini(parentC) + val parentC = Var(Map(WeightA -> 3, WeightB -> 10)) + val WeightC = mini(parentC) - assert(WeightC.readValueOnce == 5) + assert(WeightC.readValueOnce == 5) - parentC.transform(_ + (WeightB -> 1)) + parentC.transform(_ + (WeightB -> 1)) - assert(WeightC.readValueOnce == 2) + assert(WeightC.readValueOnce == 2) - } + } } diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/errors/ExceptionPropagationTestSuite.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/errors/ExceptionPropagationTestSuite.scala index 54073b83b..0bb856a85 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/errors/ExceptionPropagationTestSuite.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/errors/ExceptionPropagationTestSuite.scala @@ -139,9 +139,9 @@ class ExceptionPropagationTestSuite extends RETests { intercept[ObservedException] { v.set(0) } assertEquals(res, 100 / 42, "observers are not triggered on failure") - //if (engine != reactives.interfaces.toposort) { - assertEquals(v.readValueOnce, 42, "transaction is aborted on failure") - //} + // if (engine != reactives.interfaces.toposort) { + assertEquals(v.readValueOnce, 42, "transaction is aborted on failure") + // } } test("do not observe emptiness") { @@ -162,20 +162,20 @@ class ExceptionPropagationTestSuite extends RETests { } test("abort combinator") { - //if (engine != reactives.interfaces.toposort) { - val v = Var(0) - val ds = Signal { div(v.value) } + // if (engine != reactives.interfaces.toposort) { + val v = Var(0) + val ds = Signal { div(v.value) } - intercept[ObservedException] { ds.abortOnError("abort immediate") } + intercept[ObservedException] { ds.abortOnError("abort immediate") } - v.set(42) - ds.abortOnError("abort later") - assertEquals(ds.readValueOnce, 100 / 42, "can add observers if no longer failed") + v.set(42) + ds.abortOnError("abort later") + assertEquals(ds.readValueOnce, 100 / 42, "can add observers if no longer failed") - intercept[ObservedException] { v.set(0) } - assertEquals(ds.readValueOnce, 100 / 42, "observers are not triggered on failure") - assertEquals(v.readValueOnce, 42, "transaction is aborted on failure") - //} + intercept[ObservedException] { v.set(0) } + assertEquals(ds.readValueOnce, 100 / 42, "observers are not triggered on failure") + assertEquals(v.readValueOnce, 42, "transaction is aborted on failure") + // } } test("partial recovery") { diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/misc/LightImplicitSyntaxTest.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/misc/LightImplicitSyntaxTest.scala index 785f7256b..0b55eaec3 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/misc/LightImplicitSyntaxTest.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/misc/LightImplicitSyntaxTest.scala @@ -4,7 +4,6 @@ import reactives.core.{CreationTicket, DynamicTicket} import tests.rescala.testtools.RETests import reactives.default.global.State as BundleState - class LightImplicitSyntaxTest extends RETests { multiEngined { engine => import engine._ diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/misc/ReactiveCreationInTurnsTest.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/misc/ReactiveCreationInTurnsTest.scala index 4f6562a97..6dd412f75 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/misc/ReactiveCreationInTurnsTest.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/misc/ReactiveCreationInTurnsTest.scala @@ -36,14 +36,16 @@ class ReactiveCreationInTurnsTest extends RETests { } assertEquals( - 1, v2.readValueOnce , + 1, + v2.readValueOnce, "related signal is only be evaluated once on creation (this behaviour is actually undefined)" ) v1.set(100) assertEquals( - 1, v2.readValueOnce , + 1, + v2.readValueOnce, "related signal should be evaluated once on change (this behaviour is actually undefined)" ) diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/static/conversions/Change.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/static/conversions/Change.scala index ae5936b49..744433a56 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/static/conversions/Change.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/static/conversions/Change.scala @@ -8,169 +8,172 @@ import reactives.default.* class Change extends RETests { - /* changed */ - test("changed is Not Triggered On Creation") { - var test = 0 - val v1 = Var(1) - val s1 = v1.map { _ + 1 } - val e: Event[Int] = s1.changed - e observe ((_: Int) => { test += 1 }) - - assert(test == 0) - } - - test("changed is Triggered When The Signal Changes") { - var test = 0 - val v1 = Var(1) - val s1 = v1.map { _ + 1 } - val e: Event[Int] = s1.changed - e observe ((_: Int) => { test += 1 }) - - v1 set 2 - assert(test == 1) - v1 set 3 - assert(test == 2) - } - - test("changed the Value Of The Event Reflects The Change In The Signal") { - var test = 0 - val v1 = Var(1) - val s1 = v1.map { _ + 1 } - val e: Event[Int] = s1.changed - e observe ((x: Int) => { test = x }) - - v1 set 2 - assert(test == 3) - v1 set 3 - assert(test == 4) - } - - /* changedTo */ - test("changed To is Not Triggered On Creation") { - var test = 0 - val v1 = Var(1) - val s1 = v1.map { _ + 1 } - val e: Event[Any] = s1.changed.filter(_ == 1) - e observe ((_: Any) => { test += 1 }) - - assert(test == 0) - } + /* changed */ + test("changed is Not Triggered On Creation") { + var test = 0 + val v1 = Var(1) + val s1 = v1.map { _ + 1 } + val e: Event[Int] = s1.changed + e observe ((_: Int) => { test += 1 }) + + assert(test == 0) + } + + test("changed is Triggered When The Signal Changes") { + var test = 0 + val v1 = Var(1) + val s1 = v1.map { _ + 1 } + val e: Event[Int] = s1.changed + e observe ((_: Int) => { test += 1 }) + + v1 set 2 + assert(test == 1) + v1 set 3 + assert(test == 2) + } + + test("changed the Value Of The Event Reflects The Change In The Signal") { + var test = 0 + val v1 = Var(1) + val s1 = v1.map { _ + 1 } + val e: Event[Int] = s1.changed + e observe ((x: Int) => { test = x }) + + v1 set 2 + assert(test == 3) + v1 set 3 + assert(test == 4) + } + + /* changedTo */ + test("changed To is Not Triggered On Creation") { + var test = 0 + val v1 = Var(1) + val s1 = v1.map { _ + 1 } + val e: Event[Any] = s1.changed.filter(_ == 1) + e observe ((_: Any) => { test += 1 }) + + assert(test == 0) + } + + test("changed To is Triggered When The Signal Has The Given Value") { + var test = 0 + val v1 = Var(1) + val s1 = v1.map { _ + 1 } + val e = s1.changed.filter(_ == 3) + e observe ((_) => { test += 1 }) + + v1 set 2 + assert(test == 1) + v1 set 3 + assert(test == 1) + } + + /* change */ + test("change is Not Triggered On Creation") { + var test = 0 + val v1 = Var(1) + val s1 = v1.map { _ + 1 } + val e = s1.change + e observe { _ => test += 1 } + + assert(test == 0) + } + + test("change is Triggered When The Signal Changes") { + var test = 0 + val v1 = Var(1) + val s1 = v1.map { _ + 1 } + val e = s1.change + e observe { _ => test += 1 } + + assertEquals(test, 0) + assertEquals(s1.readValueOnce, 2) + v1 set 2 + assertEquals(s1.readValueOnce, 3) + assertEquals(test, 1) + v1 set 3 + assertEquals(s1.readValueOnce, 4) + assertEquals(test, 2) + } + + test("change the Value Of The Event Reflects The Change In The Signal") { + var test = (0, 0) + val v1 = Var(1) + val s1 = v1.map { _ + 1 } + val e = s1.change + e observe { x => test = x.pair } + + v1 set 2 + assertEquals(test, ((2, 3))) + v1 set 3 + assertEquals(test, ((3, 4))) + } + + /* with empty signals */ + + test("changing emptiness") { + val v2 = Var.empty[String] + + val e2 = v2.change.map(_.pair).recover { case t => Some("failed" -> t.toString) } + + val ored: Event[(String, String)] = e2 + + val log = ored.list() + + assertEquals(log.readValueOnce, Nil) + + v2.set("two") + assertEquals(log.readValueOnce, List()) + + v2.set("three") + assertEquals(log.readValueOnce, List("two" -> "three")) + } + + test("folding changing and emptiness") { + val v1 = Var.empty[String] + val v2 = Var.empty[String] + + val e1 = v1.changed.map(x => ("constant", x)) + val e2 = v2.change.map(_.pair).recover { case t => Some("failed" -> t.toString) } + + val ored: Event[(String, String)] = e1 || e2 + + val log = ored.list() + + assertEquals(log.readValueOnce, Nil) + + v1.set("one") + assertEquals(log.readValueOnce, List("constant" -> "one")) + + v2.set("two") + assertEquals(log.readValueOnce, List("constant" -> "one")) - test("changed To is Triggered When The Signal Has The Given Value") { - var test = 0 - val v1 = Var(1) - val s1 = v1.map { _ + 1 } - val e = s1.changed.filter(_ == 3) - e observe ((_) => { test += 1 }) - - v1 set 2 - assert(test == 1) - v1 set 3 - assert(test == 1) - } - - /* change */ - test("change is Not Triggered On Creation") { - var test = 0 - val v1 = Var(1) - val s1 = v1.map { _ + 1 } - val e = s1.change - e observe { _ => test += 1 } - - assert(test == 0) - } + v2.set("three") + assertEquals(log.readValueOnce, List("two" -> "three", "constant" -> "one")) - test("change is Triggered When The Signal Changes") { - var test = 0 - val v1 = Var(1) - val s1 = v1.map { _ + 1 } - val e = s1.change - e observe { _ => test += 1 } - - assertEquals(test, 0) - assertEquals(s1.readValueOnce, 2) - v1 set 2 - assertEquals(s1.readValueOnce, 3) - assertEquals(test, 1) - v1 set 3 - assertEquals(s1.readValueOnce, 4) - assertEquals(test, 2) + transaction(v1, v2) { at => + v1.admit("four a")(at) + v2.admit("four b")(at) } - test("change the Value Of The Event Reflects The Change In The Signal") { - var test = (0, 0) - val v1 = Var(1) - val s1 = v1.map { _ + 1 } - val e = s1.change - e observe { x => test = x.pair } - - v1 set 2 - assertEquals(test, ((2, 3))) - v1 set 3 - assertEquals(test, ((3, 4))) - } - - /* with empty signals */ - - test("changing emptiness") { - val v2 = Var.empty[String] - - val e2 = v2.change.map(_.pair).recover { case t => Some("failed" -> t.toString) } + assertEquals(log.readValueOnce, List("constant" -> "four a", "two" -> "three", "constant" -> "one")) - val ored: Event[(String, String)] = e2 - - val log = ored.list() - - assertEquals(log.readValueOnce, Nil) - - v2.set("two") - assertEquals(log.readValueOnce, List()) - - v2.set("three") - assertEquals(log.readValueOnce, List("two" -> "three")) + transaction(v1, v2) { turn => + v1.admitPulse(Pulse.Exceptional(EmptySignalControlThrowable(summon)))(turn) + v2.admit("five b")(turn) } - test("folding changing and emptiness") { - val v1 = Var.empty[String] - val v2 = Var.empty[String] - - val e1 = v1.changed.map(x => ("constant", x)) - val e2 = v2.change.map(_.pair).recover { case t => Some("failed" -> t.toString) } - - val ored: Event[(String, String)] = e1 || e2 - - val log = ored.list() - - assertEquals(log.readValueOnce, Nil) - - v1.set("one") - assertEquals(log.readValueOnce, List("constant" -> "one")) - - v2.set("two") - assertEquals(log.readValueOnce, List("constant" -> "one")) - - v2.set("three") - assertEquals(log.readValueOnce, List("two" -> "three", "constant" -> "one")) - - transaction(v1, v2) { at => - v1.admit("four a")(at) - v2.admit("four b")(at) - } - - assertEquals(log.readValueOnce, List("constant" -> "four a", "two" -> "three", "constant" -> "one")) - - transaction(v1, v2) { turn => - v1.admitPulse(Pulse.Exceptional(EmptySignalControlThrowable(summon)))(turn) - v2.admit("five b")(turn) - } - - assertEquals(log.readValueOnce, List( + assertEquals( + log.readValueOnce, + List( "four b" -> "five b", "constant" -> "four a", "two" -> "three", "constant" -> "one" - )) + ) + ) - } + } } diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/static/events/EventTest.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/static/events/EventTest.scala index edd351545..91ff950be 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/static/events/EventTest.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/static/events/EventTest.scala @@ -6,68 +6,68 @@ import reactives.default.* class EventTest extends RETests { - test("handlers Are Executed") { - var test = 0 - val e1 = Evt[Int]() - e1 observe ((_: Int) => { test += 1 }) - e1.fire(10) - e1.fire(10) - assert(test == 2) - } - - test("correct Value Is Received") { - var test = 0 - val e1 = Evt[Int]() - e1 observe ((x: Int) => { test += x }) - e1.fire(10) - assert(test == 10) - } - - test("events Without Params Is Called") { - var test = 0 - val e1 = Evt[Unit]() - e1 observe (_ => { test += 1 }) - e1.fire(()) - assert(test == 1) - } - - test("function Is Called") { - var test = 0 - - def f(): Unit = { test += 1 } - - val e1 = Evt[Int]() - e1 observe (_ => f()) - - e1.fire(10) - e1.fire(10) - assert(test == 2) - } - - test("events With Method Handlers With Parameter") { - - var test = 0 - val e = Evt[Int]() - def m1(): Unit = { test += 1 } - - e observe (_ => m1()) - e.fire(10) - e.fire(10) - assert(test == 2) - - } - - test("from callback in transaction test") { - - val res = transaction() { implicit at => - val res = Event.fromCallback { - Event.handle("some!") - } - res.event.hold("none") + test("handlers Are Executed") { + var test = 0 + val e1 = Evt[Int]() + e1 observe ((_: Int) => { test += 1 }) + e1.fire(10) + e1.fire(10) + assert(test == 2) + } + + test("correct Value Is Received") { + var test = 0 + val e1 = Evt[Int]() + e1 observe ((x: Int) => { test += x }) + e1.fire(10) + assert(test == 10) + } + + test("events Without Params Is Called") { + var test = 0 + val e1 = Evt[Unit]() + e1 observe (_ => { test += 1 }) + e1.fire(()) + assert(test == 1) + } + + test("function Is Called") { + var test = 0 + + def f(): Unit = { test += 1 } + + val e1 = Evt[Int]() + e1 observe (_ => f()) + + e1.fire(10) + e1.fire(10) + assert(test == 2) + } + + test("events With Method Handlers With Parameter") { + + var test = 0 + val e = Evt[Int]() + def m1(): Unit = { test += 1 } + + e observe (_ => m1()) + e.fire(10) + e.fire(10) + assert(test == 2) + + } + + test("from callback in transaction test") { + + val res = transaction() { implicit at => + val res = Event.fromCallback { + Event.handle("some!") } + res.event.hold("none") + } - assertEquals(res.readValueOnce, "some!") + assertEquals(res.readValueOnce, "some!") - } + } } diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/static/signals/SignalMacro.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/static/signals/SignalMacro.scala index 041b9ffbd..5f9fba56c 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/static/signals/SignalMacro.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/static/signals/SignalMacro.scala @@ -4,7 +4,6 @@ import reactives.core.{CreationScope, CreationTicket} import tests.rescala.testtools.RETests import reactives.default.global.State as BundleState - class SignalMacro extends RETests { multiEngined { engine => import engine._ diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/RETests.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/RETests.scala index 240026160..23564e8e8 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/RETests.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/RETests.scala @@ -13,7 +13,13 @@ abstract class RETests extends munit.FunSuite { new Compare[B, A] { override def isEqual(obtained: B, expected: A): Boolean = compare.isEqual(expected, obtained) - override def failEqualsComparison(obtained: B, expected: A, title: Any, loc: Location, assertions: Assertions): Nothing = compare.failEqualsComparison(expected, obtained, title, loc, assertions) + override def failEqualsComparison( + obtained: B, + expected: A, + title: Any, + loc: Location, + assertions: Assertions + ): Nothing = compare.failEqualsComparison(expected, obtained, title, loc, assertions) } ) diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/ReevaluationTracker.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/ReevaluationTracker.scala index faaa0b530..a16375f03 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/ReevaluationTracker.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/ReevaluationTracker.scala @@ -4,7 +4,6 @@ import reactives.core.CreationTicket import reactives.operator.Interface import reactives.default.global.State as BundleState - class ReevaluationBundle[T <: Interface](val api: T) { import api._ diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/SetAndExtractTransactionHandle.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/SetAndExtractTransactionHandle.scala index 4b9fd534c..d3ae191d0 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/SetAndExtractTransactionHandle.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/SetAndExtractTransactionHandle.scala @@ -5,7 +5,6 @@ import reactives.operator.Interface import reactives.operator.Source import reactives.default.global.State as BundleState - class SetAndExtractTransactionHandle[Api <: Interface](val api: Api) { import api._ def SetAndExtractTransactionHandle[A, N]( diff --git a/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/TestIgnoreTags.scala b/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/TestIgnoreTags.scala index e1b43d8a9..ae2806e27 100644 --- a/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/TestIgnoreTags.scala +++ b/Modules/Reactives/shared/src/test/scala/tests/rescala/testtools/TestIgnoreTags.scala @@ -3,10 +3,10 @@ package tests.rescala.testtools // workarounds for tests are fun. // note, this does not seem to work in JS because the environment variable can not be read case class IgnoreOnWindowsBecause(description: String) - //extends Tag(if (System.getProperty("os.name").contains("Windows")) "org.scalatest.Ignore" else "") +//extends Tag(if (System.getProperty("os.name").contains("Windows")) "org.scalatest.Ignore" else "") case class IgnoreOnGithubCiBecause(description: String) - //extends Tag(if (Option(System.getenv("GITHUB_WORKFLOW")).exists(_.nonEmpty)) "org.scalatest.Ignore" else "") +//extends Tag(if (Option(System.getenv("GITHUB_WORKFLOW")).exists(_.nonEmpty)) "org.scalatest.Ignore" else "") case class IgnoreOnGithubWindowsCiBecause(description: String) // extends Tag( diff --git a/Modules/Swing/src/main/scala/reswing/ReSwingValue.scala b/Modules/Swing/src/main/scala/reswing/ReSwingValue.scala index 2dbe58a46..79f28fbc2 100644 --- a/Modules/Swing/src/main/scala/reswing/ReSwingValue.scala +++ b/Modules/Swing/src/main/scala/reswing/ReSwingValue.scala @@ -51,10 +51,12 @@ final case class ReSwingEventValue[T](private val value: Lazy[Event[T]]) extends } final case class ReSwingSignalValue[T](private val value: Lazy[Signal[T]]) extends ReSwingValue[T] { - protected val signal = Lazy { (value().changed || event()) `hold` value().readValueOnce } - private[reswing] def fixed = true - private[reswing] def get = value().readValueOnce - private[reswing] def use(setter: T => Unit): Unit = { value().changed `observe` setter; setter(value().readValueOnce) } + protected val signal = Lazy { (value().changed || event()) `hold` value().readValueOnce } + private[reswing] def fixed = true + private[reswing] def get = value().readValueOnce + private[reswing] def use(setter: T => Unit): Unit = { + value().changed `observe` setter; setter(value().readValueOnce) + } } object ReSwingValue { diff --git a/project/Settings.scala b/project/Settings.scala index 10f557a70..80d01a966 100644 --- a/project/Settings.scala +++ b/project/Settings.scala @@ -29,8 +29,10 @@ object Settings { "-language:implicitConversions", "-language:existentials", "-deprecation", - "-source", "3.4", - "-java-output-version", "11" + "-source", + "3.4", + "-java-output-version", + "11" ) )