From 34ae4f9fba6d144aa9ced9ccfb81220bd78e7603 Mon Sep 17 00:00:00 2001 From: Matthias Zenger Date: Mon, 10 May 2004 13:08:50 +0000 Subject: New library files. --- sources/scala/collection/mutable/Location.scala | 27 ++++++ sources/scala/collection/mutable/Message.scala | 77 +++++++++++++++ .../collection/mutable/ObservableBuffer.scala | 74 ++++++++++++++ .../collection/mutable/PriorityQueueProxy.scala | 93 ++++++++++++++++++ sources/scala/collection/mutable/QueueProxy.scala | 95 ++++++++++++++++++ sources/scala/collection/mutable/Scriptable.scala | 24 +++++ sources/scala/collection/mutable/StackProxy.scala | 106 +++++++++++++++++++++ sources/scala/collection/mutable/Undoable.scala | 24 +++++ 8 files changed, 520 insertions(+) create mode 100644 sources/scala/collection/mutable/Location.scala create mode 100644 sources/scala/collection/mutable/Message.scala create mode 100644 sources/scala/collection/mutable/ObservableBuffer.scala create mode 100644 sources/scala/collection/mutable/PriorityQueueProxy.scala create mode 100644 sources/scala/collection/mutable/QueueProxy.scala create mode 100644 sources/scala/collection/mutable/Scriptable.scala create mode 100644 sources/scala/collection/mutable/StackProxy.scala create mode 100644 sources/scala/collection/mutable/Undoable.scala diff --git a/sources/scala/collection/mutable/Location.scala b/sources/scala/collection/mutable/Location.scala new file mode 100644 index 0000000000..30abd06781 --- /dev/null +++ b/sources/scala/collection/mutable/Location.scala @@ -0,0 +1,27 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.collection.mutable; + + +/** Class Location describes locations in messages implemented + * by class Message. + * + * @author Matthias Zenger + * @version 1.0, 10/05/2004 + */ +trait Location; + +case object NA extends Location; + +case object Start extends Location; + +case object End extends Location; + +case class Index(n: Int) extends Location; diff --git a/sources/scala/collection/mutable/Message.scala b/sources/scala/collection/mutable/Message.scala new file mode 100644 index 0000000000..da5610b29a --- /dev/null +++ b/sources/scala/collection/mutable/Message.scala @@ -0,0 +1,77 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.collection.mutable; + + +/** Class Message represents messages that are issued by observable + * collection classes whenever a data structure is changed. Class Message + * has several subclasses for the various kinds of events: Update + * Remove, Include, Reset, and + * Script. + * + * @author Matthias Zenger + * @version 1.0, 08/07/2003 + */ +trait Message[+A]; + +/** This observable update refers to inclusion operations that add new elements + * to collection classes. + * + * @author Matthias Zenger + * @version 1.0, 08/07/2003 + */ +case class Include[+A](elem: A) extends Message[A]; + +/** This observable update refers to destructive modification operations + * of elements from collection classes. + * + * @author Matthias Zenger + * @version 1.0, 08/07/2003 + */ +case class Update[+A](elem: A) extends Message[A]; + +/** This observable update refers to removal operations of elements + * from collection classes. + * + * @author Matthias Zenger + * @version 1.0, 08/07/2003 + */ +case class Remove[+A](elem: A) extends Message[A]; + +/** This command refers to reset operations. + * + * @author Matthias Zenger + * @version 1.0, 08/07/2003 + */ +case class Reset[+A] extends Message[A]; + +/** Objects of this class represent compound messages consisting + * of a sequence of other messages. + * + * @author Matthias Zenger + * @version 1.0, 10/05/2004 + */ +class Script[A] extends ArrayBuffer[Message[A]] with Message[A] { + + override def toString(): String = { + var res = "Script("; + var it = elements; + var i = 1; + while (it.hasNext) { + if (i > 1) + res = res + ", "; + res = res + "[" + i + "] " + it.next; + i = i + 1; + } + res + ")"; + } + + override def hashCode(): Int = error("scripts are not suitable as hash keys"); +} diff --git a/sources/scala/collection/mutable/ObservableBuffer.scala b/sources/scala/collection/mutable/ObservableBuffer.scala new file mode 100644 index 0000000000..70b94fe5ac --- /dev/null +++ b/sources/scala/collection/mutable/ObservableBuffer.scala @@ -0,0 +1,74 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.collection.mutable; + + +/** This class is typically used as a mixin. It adds a subscription + * mechanism to the Buffer class into which this abstract + * class is mixed in. Class ObservableBuffer publishes + * events of the type Message. + * + * @author Matthias Zenger + * @version 1.0, 08/07/2003 + */ +abstract class ObservableBuffer[A, This <: ObservableBuffer[A, This]]: This + extends Buffer[A] + with Publisher[Message[Pair[Location, A]] with Undoable, This] { + + abstract override def +(elem: A): Buffer[A] = { + super.+(elem); + publish(new Include(Pair(End, elem)) with Undoable { + def undo: Unit = trimEnd(1); + }); + this + } + + abstract override def +:(elem: A): Buffer[A] = { + super.+:(elem); + publish(new Include(Pair(Start, elem)) with Undoable { + def undo: Unit = trimStart(1); + }); + this + } + + abstract override def insertAll(n: Int, iter: Iterable[A]): Unit = { + super.insertAll(n, iter); + var i = n; + val it = iter.elements; + while (it.hasNext) { + publish(new Include(Pair(Index(i), it.next)) with Undoable { + def undo: Unit = remove(i); + }); + i = i + 1; + } + } + + abstract override def update(n: Int, newelem: A): Unit = { + val oldelem = apply(n); + super.update(n, newelem); + publish(new Update(Pair(Index(n), newelem)) with Undoable { + def undo: Unit = update(n, oldelem); + }); + } + + abstract override def remove(n: Int): A = { + val oldelem = apply(n); + super.remove(n); + publish(new Remove(Pair(Index(n), oldelem)) with Undoable { + def undo: Unit = insert(n, oldelem); + }); + oldelem + } + + abstract override def clear: Unit = { + super.clear; + publish(new Reset with Undoable { def undo: Unit = error("cannot undo"); }); + } +} diff --git a/sources/scala/collection/mutable/PriorityQueueProxy.scala b/sources/scala/collection/mutable/PriorityQueueProxy.scala new file mode 100644 index 0000000000..0a93803e3a --- /dev/null +++ b/sources/scala/collection/mutable/PriorityQueueProxy.scala @@ -0,0 +1,93 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.collection.mutable; + + +/** This class implements priority queues using a heap. The + * elements of the queue have to be ordered in terms of the + * Ordered[T] trait. + * + * @author Matthias Zenger + * @version 1.0, 03/05/2004 + */ +class PriorityQueueProxy[A <% Ordered[A]](p: PriorityQueue[A]) extends + PriorityQueue[A] with IterableProxy[A](p) { + + /** Creates a new iterator over all elements contained in this + * object. + * + * @return the new iterator + */ + override def elements: Iterator[A] = p.elements; + + /** Returns the length of this priority queue. + */ + override def length: Int = p.length; + + /** Checks if the queue is empty. + * + * @return true, iff there is no element in the queue. + */ + override def isEmpty: Boolean = p.isEmpty; + + /** Inserts a single element into the priority queue. + * + * @param elem the element to insert + */ + override def +=(elem: A): Unit = p += elem; + + /** Adds all elements provided by an Iterable object + * into the priority queue. + * + * @param iter an iterable object + */ + override def ++=(iter: Iterable[A]): Unit = p ++= iter; + + /** Adds all elements provided by an iterator into the priority queue. + * + * @param it an iterator + */ + override def ++=(it: Iterator[A]): Unit = p ++= it; + + /** Adds all elements to the queue. + * + * @param elems the elements to add. + */ + override def enqueue(elems: A*): Unit = p ++= elems; + + /** Returns the element with the highest priority in the queue, + * and removes this element from the queue. + * + * @return the element with the highest priority. + */ + override def dequeue: A = p.dequeue; + + /** Returns the element with the highest priority in the queue, + * or throws an error if there is no element contained in the queue. + * + * @return the element with the highest priority. + */ + override def max: A = p.max; + + /** Removes all elements from the queue. After this operation is completed, + * the queue will be empty. + */ + override def clear: Unit = p.clear; + + /** Returns a regular queue containing the same elements. + */ + override def toQueue: Queue[A] = p.toQueue; + + /** This method clones the priority queue. + * + * @return a priority queue with the same elements. + */ + override def clone(): PriorityQueue[A] = new PriorityQueueProxy(p.clone()); +} diff --git a/sources/scala/collection/mutable/QueueProxy.scala b/sources/scala/collection/mutable/QueueProxy.scala new file mode 100644 index 0000000000..d1cfcd10cf --- /dev/null +++ b/sources/scala/collection/mutable/QueueProxy.scala @@ -0,0 +1,95 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.collection.mutable; + + +/** Queue objects implement data structures that allow to + * insert and retrieve elements in a first-in-first-out (FIFO) manner. + * + * @author Matthias Zenger + * @version 1.1, 03/05/2004 + */ +class QueueProxy[A](q: Queue[A]) extends Queue[A] with SeqProxy[A](q) { + + /** Access element number n. + * + * @return the element at index n. + */ + override def apply(n: Int): A = q.apply(n); + + /** Returns the length of this queue. + */ + override def length: Int = q.length; + + /** Checks if the queue is empty. + * + * @return true, iff there is no element in the queue. + */ + override def isEmpty: Boolean = q.isEmpty; + + /** Inserts a single element at the end of the queue. + * + * @param elem the element to insert + */ + override def +=(elem: A): Unit = q += elem; + + /** Adds all elements provided by an Iterable object + * at the end of the queue. The elements are prepended in the order they + * are given out by the iterator. + * + * @param iter an iterable object + */ + override def ++=(iter: Iterable[A]): Unit = q ++= iter; + + /** Adds all elements provided by an iterator + * at the end of the queue. The elements are prepended in the order they + * are given out by the iterator. + * + * @param iter an iterator + */ + override def ++=(it: Iterator[A]): Unit = q ++= it; + + /** Adds all elements to the queue. + * + * @param elems the elements to add. + */ + override def enqueue(elems: A*): Unit = q ++= elems; + + /** Returns the first element in the queue, and removes this element + * from the queue. + * + * @return the first element of the queue. + */ + override def dequeue: A = q.dequeue; + + /** Returns the first element in the queue, or throws an error if there + * is no element contained in the queue. + * + * @return the first element. + */ + override def front: A = q.front; + + /** Removes all elements from the queue. After this operation is completed, + * the queue will be empty. + */ + override def clear: Unit = q.clear; + + /** Returns an iterator over all elements on the queue. + * + * @return an iterator over all queue elements. + */ + override def elements: Iterator[A] = q.elements; + + /** This method clones the queue. + * + * @return a queue with the same elements. + */ + override def clone(): Queue[A] = new QueueProxy(q.clone()); +} diff --git a/sources/scala/collection/mutable/Scriptable.scala b/sources/scala/collection/mutable/Scriptable.scala new file mode 100644 index 0000000000..448109bde3 --- /dev/null +++ b/sources/scala/collection/mutable/Scriptable.scala @@ -0,0 +1,24 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.collection.mutable; + + +/** Classes that implement the Scriptable trait allow + * messages to be sent to objects of that class. + * + * @author Matthias Zenger + * @version 1.0, 09/05/2004 + */ +trait Scriptable[A] { + + /** Send a message to this scriptable object. + */ + def <<(cmd: A): Unit; +} diff --git a/sources/scala/collection/mutable/StackProxy.scala b/sources/scala/collection/mutable/StackProxy.scala new file mode 100644 index 0000000000..5ee8bbb140 --- /dev/null +++ b/sources/scala/collection/mutable/StackProxy.scala @@ -0,0 +1,106 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.collection.mutable; + + +/** A stack implements a data structure which allows to store and retrieve + * objects in a last-in-first-out (LIFO) fashion. + * + * @author Matthias Zenger + * @version 1.0, 10/05/2004 + */ +class StackProxy[A](s: Stack[A]) extends Stack[A] with SeqProxy[A](s) { + + /** Access element number n. + * + * @return the element at index n. + */ + override def apply(n: Int): A = s.apply(n); + + /** Returns the length of this stack. + */ + override def length: Int = s.length; + + /** Checks if the stack is empty. + * + * @return true, iff there is no element on the stack + */ + override def isEmpty: Boolean = s.isEmpty; + + /** Pushes a single element on top of the stack. + * + * @param elem the element to push onto the stack + */ + override def +=(elem: A): Unit = s += elem; + + /** Pushes all elements provided by an Iterable object + * on top of the stack. The elements are pushed in the order they + * are given out by the iterator. + * + * @param iter an iterable object + */ + override def ++=(iter: Iterable[A]): Unit = s ++= iter; + + + /** Pushes all elements provided by an iterator + * on top of the stack. The elements are pushed in the order they + * are given out by the iterator. + * + * @param iter an iterator + */ + override def ++=(it: Iterator[A]): Unit = s ++= it; + + /** Pushes a sequence of elements on top of the stack. The first element + * is pushed first, etc. + * + * @param elems a sequence of elements + */ + override def push(elems: A*): Unit = s ++= elems; + + /** Returns the top element of the stack. This method will not remove + * the element from the stack. An error is signaled if there is no + * element on the stack. + * + * @return the top element + */ + override def top: A = s.top; + + /** Removes the top element from the stack. + */ + override def pop: A = s.pop; + + /** + * Removes all elements from the stack. After this operation completed, + * the stack will be empty. + */ + override def clear: Unit = s.clear; + + /** Returns an iterator over all elements on the stack. This iterator + * is stable with respect to state changes in the stack object; i.e. + * such changes will not be reflected in the iterator. The iterator + * issues elements in the order they were inserted into the stack + * (FIFO order). + * + * @return an iterator over all stack elements. + */ + override def elements: Iterator[A] = s.elements; + + /** Creates a list of all stack elements in FIFO order. + * + * @return the created list. + */ + override def toList: List[A] = s.toList; + + /** This method clones the stack. + * + * @return a stack with the same elements. + */ + override def clone(): Stack[A] = new StackProxy(s.clone()); +} diff --git a/sources/scala/collection/mutable/Undoable.scala b/sources/scala/collection/mutable/Undoable.scala new file mode 100644 index 0000000000..62e7335411 --- /dev/null +++ b/sources/scala/collection/mutable/Undoable.scala @@ -0,0 +1,24 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.collection.mutable; + + +/** Classes that implement the Undoable trait provide an operation + * undo which can be used to undo the last operation. + * + * @author Matthias Zenger + * @version 1.0, 08/07/2003 + */ +trait Undoable { + + /** Undo the last operation. + */ + def undo: Unit; +} -- cgit v1.2.3