summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Zenger <mzenger@gmail.com>2003-06-25 10:50:11 +0000
committerMatthias Zenger <mzenger@gmail.com>2003-06-25 10:50:11 +0000
commita8722061eee0cb300a32ea30484a267ec6004368 (patch)
treeeec8001d387c75d75b2047e996fbc2a5fbe4b79f
parentefd426fe236731b51308c0a68a4dba9abad9a87c (diff)
downloadscala-a8722061eee0cb300a32ea30484a267ec6004368.tar.gz
scala-a8722061eee0cb300a32ea30484a267ec6004368.tar.bz2
scala-a8722061eee0cb300a32ea30484a267ec6004368.zip
Support files for the Publish/Subscriber mechan...
Support files for the Publish/Subscriber mechanism; this set of files implements, in particular, a rollback mechanism for any collection type. The mechanism is designed that it can consistently reset a whole set of containers to a consistent state.
-rw-r--r--sources/scala/History.scala36
-rw-r--r--sources/scala/Inclusion.scala13
-rw-r--r--sources/scala/Modification.scala13
-rw-r--r--sources/scala/ObservableMap.scala40
-rw-r--r--sources/scala/ObservableUpdate.scala13
-rw-r--r--sources/scala/Removal.scala13
-rw-r--r--sources/scala/Reset.scala13
-rw-r--r--sources/scala/RevertableHistory.scala25
-rw-r--r--sources/scala/Undo.scala15
9 files changed, 181 insertions, 0 deletions
diff --git a/sources/scala/History.scala b/sources/scala/History.scala
new file mode 100644
index 0000000000..115fb850dc
--- /dev/null
+++ b/sources/scala/History.scala
@@ -0,0 +1,36 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+/** <tt>History[A, B]</tt> objects may subscribe to events of
+ * type <tt>A</tt> published by an object of type <tt>B</tt>.
+ * The history subscriber object records all published events
+ * up to maximum number of <tt>maxHistory</tt> events.
+ */
+class History[A, B] with Subscriber[A, B] {
+
+ protected val log: Queue[Pair[B, A]] = new Queue[Pair[B, A]];
+
+ val maxHistory: Int = 32000;
+
+ def update(pub: B, event: A): Unit = {
+ if (log.length >= maxHistory) {
+ val old = log.dequeue;
+ }
+ log.enqueue(Pair(pub, event));
+ }
+
+ def getHistory: Iterator[Pair[B, A]] = log.toList.elements;
+
+ def historySize: Int = log.length;
+
+ def clear: Unit = log.clear;
+}
diff --git a/sources/scala/Inclusion.scala b/sources/scala/Inclusion.scala
new file mode 100644
index 0000000000..52ee525d08
--- /dev/null
+++ b/sources/scala/Inclusion.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+case class Inclusion[A](elem: A) extends ObservableUpdate[A];
diff --git a/sources/scala/Modification.scala b/sources/scala/Modification.scala
new file mode 100644
index 0000000000..4da13bd61a
--- /dev/null
+++ b/sources/scala/Modification.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+case class Modification[A](old: A, nu: A) extends ObservableUpdate[A];
diff --git a/sources/scala/ObservableMap.scala b/sources/scala/ObservableMap.scala
new file mode 100644
index 0000000000..420a0feeaa
--- /dev/null
+++ b/sources/scala/ObservableMap.scala
@@ -0,0 +1,40 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+abstract class ObservableMap[A, B, This <: ObservableMap[A, B, This]]: This
+ extends MutableMap[A, B]
+ with Publisher[ObservableUpdate[Pair[A, B]] with Undo, This] {
+
+ override def update(key: A, value: B): Unit = get(key) match {
+ case None => super.update(key, value);
+ publish(new Inclusion(Pair(key, value)) with Undo {
+ def undo = remove(key);
+ });
+ case Some(old) => super.update(key, value);
+ publish(new Modification(Pair(key, old), Pair(key, value)) with Undo {
+ def undo = update(key, old._2);
+ });
+ }
+
+ override def remove(key: A): Unit = get(key) match {
+ case None =>
+ case Some(old) => super.remove(key);
+ publish(new Removal(Pair(key, old)) with Undo {
+ def undo = update(key, old);
+ });
+ }
+
+ override def clear: Unit = {
+ super.clear;
+ publish(new Reset() with Undo { def undo = error("cannot undo"); });
+ }
+}
diff --git a/sources/scala/ObservableUpdate.scala b/sources/scala/ObservableUpdate.scala
new file mode 100644
index 0000000000..fabe049f40
--- /dev/null
+++ b/sources/scala/ObservableUpdate.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait ObservableUpdate[+A];
diff --git a/sources/scala/Removal.scala b/sources/scala/Removal.scala
new file mode 100644
index 0000000000..37b062709e
--- /dev/null
+++ b/sources/scala/Removal.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+case class Removal[A](elem: A) extends ObservableUpdate[A];
diff --git a/sources/scala/Reset.scala b/sources/scala/Reset.scala
new file mode 100644
index 0000000000..b458560251
--- /dev/null
+++ b/sources/scala/Reset.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+case class Reset[A]() extends ObservableUpdate[A];
diff --git a/sources/scala/RevertableHistory.scala b/sources/scala/RevertableHistory.scala
new file mode 100644
index 0000000000..760f5dcea6
--- /dev/null
+++ b/sources/scala/RevertableHistory.scala
@@ -0,0 +1,25 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+/** <tt>Subscriber[-A, -B]</tt> objects may subscribe to events of
+ * type <tt>A</tt> published by an object of type <tt>B</tt>.
+ */
+class RevertableHistory[A <: Undo, B] extends History[A, B] with Undo {
+
+ def undo: Unit = {
+ val old = log.toList.reverse;
+ clear;
+ old.foreach {
+ case Pair(sub, event) => event.undo;
+ }
+ }
+}
diff --git a/sources/scala/Undo.scala b/sources/scala/Undo.scala
new file mode 100644
index 0000000000..4349851e5a
--- /dev/null
+++ b/sources/scala/Undo.scala
@@ -0,0 +1,15 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait Undo {
+ def undo: Unit;
+}