From 119376911af0728b3e3e82b426bc481e28a49c71 Mon Sep 17 00:00:00 2001 From: Philipp Haller Date: Wed, 21 Dec 2016 11:55:49 +0100 Subject: [PATCH] Add update method for updating box fields in Actor --- core/src/main/scala/lacasa/Actor.scala | 9 +++++++++ core/src/main/scala/lacasa/Box.scala | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/lacasa/Actor.scala b/core/src/main/scala/lacasa/Actor.scala index ac9f45c..a1f01c3 100644 --- a/core/src/main/scala/lacasa/Actor.scala +++ b/core/src/main/scala/lacasa/Actor.scala @@ -66,6 +66,15 @@ abstract class Actor[T] { throw new NoReturnControl } + /* Variant of `open` for more convenient access to box fields. + * + * `fun` must satisfy the same safety constraints as closures passed to `open` + */ + def update[S](select: => Box[S])(fun: Spore[S, S])(implicit noCapture: Safe[fun.Captured]): Unit = { + val theBox = select + theBox.updateInstance(fun) + } + // swap for accessing fields of type Box[S] def swap[S](select: => Box[S])(assign: Box[S] => Unit, newBox: Box[S])( fun: Spore[Packed[S], Unit] { type Excluded = newBox.C })( diff --git a/core/src/main/scala/lacasa/Box.scala b/core/src/main/scala/lacasa/Box.scala index 803f292..0e1b165 100644 --- a/core/src/main/scala/lacasa/Box.scala +++ b/core/src/main/scala/lacasa/Box.scala @@ -8,7 +8,7 @@ import scala.reflect.{ClassTag, classTag} import scala.spores._ import scala.util.control.ControlThrowable - +import scala.annotation.unchecked.uncheckedVariance private class NoReturnControl extends ControlThrowable { // do not fill in stack trace for efficiency @@ -63,7 +63,7 @@ object Safe { implicit def tuple2IsSafe[T, S](implicit one: Safe[T], two: Safe[S]): Safe[(T, S)] = new Safe[(T, S)] {} } -sealed class Box[+T] private (private val instance: T) { +sealed class Box[+T] private (private var instance: T @uncheckedVariance) { self => type C @@ -77,6 +77,11 @@ sealed class Box[+T] private (private val instance: T) { } } + // trusted operation + private[lacasa] def updateInstance(fun: T => T @uncheckedVariance): Unit = { + instance = fun(instance) + } + def open(fun: Spore[T, Unit])(implicit access: CanAccess { type C = self.C }, noCapture: Safe[fun.Captured]): Box[T] = { fun(instance) self