Scrapped using a Comparable for the keys to a DSet on this side of things.

- There is no such thing as Comparable in ActionScript, I had made my own,
  but String (one of the most common keys) couldn't implement it, and String
  is a final class (like in Java). It would be a huge inconvenience to have
  to wrap String objects.
- The language also has no .equals() method in the base class. The strict
  equality operator (===) works like equals() except that objects that
  aren't one of the base types (String, Number, Boolean, int) are compared
  by reference. I added a "Equalable" interface, if the key in a DSet
  implements that interface then equals() is called, otherwise the strict
  equality operator is used.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3897 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2006-03-01 19:43:22 +00:00
parent ee25f8f1a8
commit 703b309108
6 changed files with 48 additions and 58 deletions
@@ -31,11 +31,9 @@ public class InvocationRegistration
} }
// documentation inherited from interface DSetEntry // documentation inherited from interface DSetEntry
public function getKey () :Comparable public function getKey () :Object
{ {
return null; // TODO receiverCode; return receiverCode;
// TODO: maybe we drop the concept of Comparable and just
// use any old objects: screw performance
} }
// documentation inherited // documentation inherited
@@ -95,7 +95,7 @@ public /* abstract */ class DEvent
class DummyEntry implements com.threerings.presents.dobj.DSetEntry class DummyEntry implements com.threerings.presents.dobj.DSetEntry
{ {
public function getKey () :com.threerings.util.Comparable public function getKey () :Object
{ {
return null; return null;
} }
@@ -7,7 +7,6 @@ import flash.util.StringBuilder;
import mx.collections.ArrayCollection; import mx.collections.ArrayCollection;
import com.threerings.util.ClassUtil; import com.threerings.util.ClassUtil;
import com.threerings.util.Comparable;
import com.threerings.io.ObjectInputStream; import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream; import com.threerings.io.ObjectOutputStream;
@@ -245,7 +244,7 @@ public class DObject // extends EventDispatcher
/** /**
* Calls by derived instances when a set remover method was called. * Calls by derived instances when a set remover method was called.
*/ */
protected function requestEntryRemove (name :String, key :Comparable) :void protected function requestEntryRemove (name :String, key :Object) :void
{ {
// dispatch an entry removed event // dispatch an entry removed event
postEvent(new EntryRemovedEvent(_oid, name, key, null)); postEvent(new EntryRemovedEvent(_oid, name, key, null));
+30 -48
View File
@@ -2,12 +2,14 @@ package com.threerings.presents.dobj {
import flash.util.StringBuilder; import flash.util.StringBuilder;
import mx.collections.IViewCursor;
import com.threerings.util.Equalable;
import com.threerings.io.ObjectInputStream; import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream; import com.threerings.io.ObjectOutputStream;
import com.threerings.io.Streamable; import com.threerings.io.Streamable;
import com.threerings.util.Comparable;
import com.threerings.presents.Log; import com.threerings.presents.Log;
/** /**
@@ -54,7 +56,7 @@ public class DSet
* Returns true if an entry in the set has a key that * Returns true if an entry in the set has a key that
* <code>equals()</code> the supplied key. Returns false otherwise. * <code>equals()</code> the supplied key. Returns false otherwise.
*/ */
public function containsKey (key :Comparable) :Boolean public function containsKey (key :Object) :Boolean
{ {
return getByKey(key) != null; return getByKey(key) != null;
} }
@@ -64,13 +66,11 @@ public class DSet
* the specified key or null if no entry could be found that matches * the specified key or null if no entry could be found that matches
* the key. * the key.
*/ */
public function getByKey (key :Comparable) :DSetEntry public function getByKey (key :Object) :DSetEntry
{ {
// o(n) for now // o(n) for now
// TODO for each (var entry :DSetEntry in _entries) {
for (var ii :int = 0; ii < _entries.length; ii++) { if (isSameKey(key, entry.getKey())) {
var entry :DSetEntry = _entries[ii];
if (key.compareTo(entry.getKey()) == 0) {
return entry; return entry;
} }
} }
@@ -82,22 +82,12 @@ public class DSet
* support modification (nor iteration while modifications are being * support modification (nor iteration while modifications are being
* made to the set). It should not be kept around as it can quickly * made to the set). It should not be kept around as it can quickly
* become out of date. * become out of date.
*
* @deprecated
*/ */
// public Iterator entries () public function getCursor () :IViewCursor
// { {
// return iterator(); return null; // jesus, what a pain in the ass to make our
// } // own IViewCursor since we can't have inner classes
/**
* Returns an iterator over the entries of this set. It does not
* support modification (nor iteration while modifications are being
* made to the set). It should not be kept around as it can quickly
* become out of date.
*/
// public Iterator iterator ()
// {
// // the crazy sanity checks // // the crazy sanity checks
// if (_size < 0 ||_size > _entries.length || // if (_size < 0 ||_size > _entries.length ||
// (_size > 0 && _entries[_size-1] == null)) { // (_size > 0 && _entries[_size-1] == null)) {
@@ -134,7 +124,7 @@ public class DSet
// protected int _ssize = _size; // protected int _ssize = _size;
// protected int _expectedModCount = _modCount; // protected int _expectedModCount = _modCount;
// }; // };
// } }
/** /**
* Copies the elements of this distributed set into the supplied * Copies the elements of this distributed set into the supplied
@@ -193,13 +183,12 @@ public class DSet
* @return the old matching entry if found and removed, null if not * @return the old matching entry if found and removed, null if not
* found. * found.
*/ */
internal function removeKey (key :Comparable) :DSetEntry internal function removeKey (key :Object) :DSetEntry
{ {
// o(n) for now // o(n) for now
// TODO
for (var ii :int = 0; ii < _entries.length; ii++) { for (var ii :int = 0; ii < _entries.length; ii++) {
var entry :DSetEntry = _entries[ii]; var entry :DSetEntry = _entries[ii];
if (key.compareTo(entry.getKey()) == 0) { if (isSameKey(key, entry.getKey())) {
_entries.splice(ii, 1); _entries.splice(ii, 1);
return entry; return entry;
} }
@@ -219,17 +208,27 @@ public class DSet
*/ */
internal function update (elem :DSetEntry) :DSetEntry internal function update (elem :DSetEntry) :DSetEntry
{ {
var key :Comparable = elem.getKey(); var key :Object = elem.getKey();
for (var ii :int = 0; ii < _entries.length; ii++) { for (var ii :int = 0; ii < _entries.length; ii++) {
var entry :DSetEntry = _entries[ii]; var entry :DSetEntry = _entries[ii];
if (key.compareTo(entry.getKey()) == 0) { if (isSameKey(key, entry.getKey())) {
_entries[ii] = elem; _entries[ii] = elem;
return entry; return entry; // return the old entry
} }
} }
return null; return null;
} }
/**
* Internal function to determine whether a key matches the key for
* an existing entry.
*/
private function isSameKey (key :Object, otherKey :Object) :Boolean
{
return (key is Equalable) ? (key as Equalable).equals(otherKey)
: (key === otherKey);
}
/** /**
* Generates a string representation of this set instance. * Generates a string representation of this set instance.
*/ */
@@ -244,7 +243,8 @@ public class DSet
// documentation inherited from interface Streamable // documentation inherited from interface Streamable
public function writeObject (out :ObjectOutputStream) :void public function writeObject (out :ObjectOutputStream) :void
{ {
Log.warning("TODO!"); out.writeObject(_entries);
out.writeInt(_entries.length);
} }
// documentation inherited from interface Streamable // documentation inherited from interface Streamable
@@ -256,23 +256,5 @@ public class DSet
/** The entries of the set (in a sparse array). */ /** The entries of the set (in a sparse array). */
protected var _entries :Array; protected var _entries :Array;
// /** Used to check for concurrent modification. */
// protected transient int _modCount;
//
// /** The default capacity of a set instance. */
// protected static final int INITIAL_CAPACITY = 2;
//
// /** Used for lookups and to keep the set contents sorted on
// * insertions. */
// protected static Comparator ENTRY_COMP = new Comparator() {
// public int compare (Object o1, Object o2) {
// Comparable c1 = (o1 instanceof Entry) ?
// ((Entry)o1).getKey() : (Comparable)o1;
// Comparable c2 = (o2 instanceof Entry) ?
// ((Entry)o2).getKey() : (Comparable)o2;
// return c1.compareTo(c2);
// }
// };
} }
} }
@@ -2,10 +2,8 @@ package com.threerings.presents.dobj {
import com.threerings.io.Streamable; import com.threerings.io.Streamable;
import com.threerings.util.Comparable;
public interface DSetEntry extends Streamable public interface DSetEntry extends Streamable
{ {
function getKey () :Comparable; function getKey () :Object;
} }
} }
+13
View File
@@ -0,0 +1,13 @@
package com.threerings.util {
/**
* An interface we can use to implement equals(), which is standard and
* very useful in Java.
*/
public interface Equalable {
/**
* Return true to see if this instance is equal to the specified object.
*/
function equals (other :Object) :Boolean;
}
}