From 7dfff1decbf14b279e8352c87644c076f8424c0e Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Tue, 4 Dec 2001 22:34:04 +0000 Subject: [PATCH] Editable mania! I love to delegate. Augmented standard scene and spot scene models with versions that provide access to data only needed by the editor and loader. Filtered that whole paradigm down through the locations and portals and all that. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@737 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../threerings/whirled/spot/data/Portal.java | 7 +- .../whirled/spot/data/SpotSceneModel.java | 6 +- .../whirled/spot/tools/EditableLocation.java | 69 +++++++++ .../whirled/spot/tools/EditablePortal.java | 65 +++++++++ .../whirled/spot/tools/EditableSpotScene.java | 12 +- .../spot/tools/EditableSpotSceneImpl.java | 137 +++++++++++++++--- .../spot/tools/EditableSpotSceneModel.java | 20 +++ .../whirled/tools/EditableScene.java | 36 ++++- .../whirled/tools/EditableSceneImpl.java | 37 ++++- .../whirled/tools/EditableSceneModel.java | 22 +++ 10 files changed, 362 insertions(+), 49 deletions(-) create mode 100644 src/java/com/threerings/whirled/spot/tools/EditableLocation.java create mode 100644 src/java/com/threerings/whirled/spot/tools/EditablePortal.java create mode 100644 src/java/com/threerings/whirled/spot/tools/EditableSpotSceneModel.java create mode 100644 src/java/com/threerings/whirled/tools/EditableSceneModel.java diff --git a/src/java/com/threerings/whirled/spot/data/Portal.java b/src/java/com/threerings/whirled/spot/data/Portal.java index ba30812c3..2e88a4833 100644 --- a/src/java/com/threerings/whirled/spot/data/Portal.java +++ b/src/java/com/threerings/whirled/spot/data/Portal.java @@ -1,5 +1,5 @@ // -// $Id: Portal.java,v 1.2 2001/11/29 00:16:31 mdb Exp $ +// $Id: Portal.java,v 1.3 2001/12/04 22:34:04 mdb Exp $ package com.threerings.whirled.spot.data; @@ -27,11 +27,6 @@ public class Portal extends Location * the target scene when they "use" this portal. */ public int targetLocationId; - /** During the offline scene creation process, a portal will have a - * huamn readable name. This is not serialized or transmitted over the - * wire. */ - public String name; - /** * Constructs a portal with the supplied values. */ diff --git a/src/java/com/threerings/whirled/spot/data/SpotSceneModel.java b/src/java/com/threerings/whirled/spot/data/SpotSceneModel.java index 06463fbb7..421e369f2 100644 --- a/src/java/com/threerings/whirled/spot/data/SpotSceneModel.java +++ b/src/java/com/threerings/whirled/spot/data/SpotSceneModel.java @@ -1,5 +1,5 @@ // -// $Id: SpotSceneModel.java,v 1.4 2001/12/03 19:40:11 mdb Exp $ +// $Id: SpotSceneModel.java,v 1.5 2001/12/04 22:34:04 mdb Exp $ package com.threerings.whirled.spot.data; @@ -21,8 +21,8 @@ import com.threerings.whirled.data.SceneModel; */ public class SpotSceneModel extends SceneModel { - /** The unique identifier of each location in this scene (including - * portals). */ + /** The unique (within the scope of this scene) identifier of each + * location in this scene (including portals). */ public int[] locationIds; /** The x coordinates of the locations in this scene (including diff --git a/src/java/com/threerings/whirled/spot/tools/EditableLocation.java b/src/java/com/threerings/whirled/spot/tools/EditableLocation.java new file mode 100644 index 000000000..05d69ad20 --- /dev/null +++ b/src/java/com/threerings/whirled/spot/tools/EditableLocation.java @@ -0,0 +1,69 @@ +// +// $Id: EditableLocation.java,v 1.1 2001/12/04 22:34:04 mdb Exp $ + +package com.threerings.whirled.tools.spot; + +import com.threerings.whirled.spot.data.Location; + +/** + * An editable location contains a name as well as the standard location + * information. + */ +public class EditableLocation +{ + /** The location whose data we extend. (My kingdom for multiple + * inheritance.) */ + public Location location; + + /** The human-readable name of this location. */ + public String name; + + /** + * Constructs an editable location. A location delegate will be + * created with the supplied basic location information. + */ + public EditableLocation (int id, int x, int y, int orientation, + int clusterIndex, String name) + { + this(new Location(id, x, y, orientation, clusterIndex), name); + } + + /** + * Constructs an editable location with the supplied location + * delegate. + */ + public EditableLocation (Location source, String name) + { + location = source; + this.name = name; + } + + /** + * Generates a string representation of this instance. + */ + public String toString () + { + StringBuffer buf = new StringBuffer("["); + delegatesToString(buf); + toString(buf); + return buf.append("]").toString(); + } + + /** + * Generates a string representation of this instance's delegates into + * the supplied string buffer. + */ + protected void delegatesToString (StringBuffer buf) + { + buf.append(location); + } + + /** + * Generates a string representation of this instance's members into + * the supplied string buffer. + */ + protected void toString (StringBuffer buf) + { + buf.append(", name=").append(name); + } +} diff --git a/src/java/com/threerings/whirled/spot/tools/EditablePortal.java b/src/java/com/threerings/whirled/spot/tools/EditablePortal.java new file mode 100644 index 000000000..e6c8f1ec4 --- /dev/null +++ b/src/java/com/threerings/whirled/spot/tools/EditablePortal.java @@ -0,0 +1,65 @@ +// +// $Id: EditablePortal.java,v 1.1 2001/12/04 22:34:04 mdb Exp $ + +package com.threerings.whirled.tools.spot; + +import com.threerings.whirled.spot.data.Portal; + +/** + * An editable portal contains a name as well as the standard portal + * information. + */ +public class EditablePortal extends EditableLocation +{ + /** The portal whose data we extend. (My kingdom for multiple + * inheritance.) */ + public Portal portal; + + /** The human-readable name of the scene to which this portal + * links. */ + public String targetSceneName; + + /** The human-readable name of the location to which this portal links + * in its target scene. */ + public String targetLocName; + + /** + * Constructs an editable portal. A portal delegate will be created + * with the supplied basic portal information. + */ + public EditablePortal ( + int id, int x, int y, int orientation, int targetSceneId, + int targetLocId, String name, String targetSceneName, + String targetLocName) + { + this(new Portal(id, x, y, orientation, targetSceneId, targetLocId), + name, targetSceneName, targetLocName); + } + + /** + * Constructs an editable portal with the specified portal delegate + * and specified extended information. + */ + public EditablePortal (Portal source, String name, + String targetSceneName, String targetLocName) + { + super(source, name); + portal = source; + this.targetSceneName = targetSceneName; + this.targetLocName = targetLocName; + } + + // documentation inherited + protected void delegatesToString (StringBuffer buf) + { + buf.append(portal); + } + + // documentation inherited + protected void toString (StringBuffer buf) + { + super.toString(buf); + buf.append(", targetScene=").append(targetSceneName); + buf.append(", targetLoc=").append(targetLocName); + } +} diff --git a/src/java/com/threerings/whirled/spot/tools/EditableSpotScene.java b/src/java/com/threerings/whirled/spot/tools/EditableSpotScene.java index 6acdc1cb8..8b8b3c8e1 100644 --- a/src/java/com/threerings/whirled/spot/tools/EditableSpotScene.java +++ b/src/java/com/threerings/whirled/spot/tools/EditableSpotScene.java @@ -1,5 +1,5 @@ // -// $Id: EditableSpotScene.java,v 1.2 2001/11/20 04:18:11 mdb Exp $ +// $Id: EditableSpotScene.java,v 1.3 2001/12/04 22:34:04 mdb Exp $ package com.threerings.whirled.tools.spot; @@ -30,24 +30,24 @@ public interface EditableSpotScene /** * Adds a location to this scene. */ - public void addLocation (Location location); + public void addLocation (EditableLocation location); /** * Removes the specified location from the scene. */ - public void removeLocation (Location location); + public void removeLocation (EditableLocation location); /** * Adds a portal to this scene (it should be added appropriately to * both the location and portal arrays). */ - public void addPortal (Portal portal); + public void addPortal (EditablePortal portal); /** * Removes a portal from this scene (it should be removed accordingly * from both the location and portal arrays). */ - public void removePortal (Portal portal); + public void removePortal (EditablePortal portal); /** * Implementations must provide a scene model that represents the @@ -56,5 +56,5 @@ public interface EditableSpotScene * or generate one at the time this method is called is up to the * implementation. */ - public SpotSceneModel getSpotSceneModel (); + public EditableSpotSceneModel getSpotSceneModel (); } diff --git a/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneImpl.java b/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneImpl.java index 1e8c46760..182c887a1 100644 --- a/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneImpl.java +++ b/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneImpl.java @@ -1,12 +1,13 @@ // -// $Id: EditableSpotSceneImpl.java,v 1.2 2001/11/20 04:18:11 mdb Exp $ +// $Id: EditableSpotSceneImpl.java,v 1.3 2001/12/04 22:34:04 mdb Exp $ package com.threerings.whirled.tools.spot; +import java.util.ArrayList; import com.samskivert.util.ListUtil; import com.threerings.crowd.data.PlaceConfig; -import com.threerings.whirled.data.SceneModel; +import com.threerings.whirled.tools.EditableSceneModel; import com.threerings.whirled.tools.EditableSceneImpl; import com.threerings.whirled.spot.client.DisplaySpotSceneImpl; @@ -41,9 +42,12 @@ public class EditableSpotSceneImpl * Creates an instance that will obtain data from the supplied scene * model and update it when changes are made. */ - public EditableSpotSceneImpl (SpotSceneModel model) + public EditableSpotSceneImpl (EditableSpotSceneModel model) { - super(model, null); + super(model.spotSceneModel, null); + + // keep track of this + _emodel = model; // Java doesn't support multiple inheritance (we'll let the reader // decide whether or not that's unfortunate), so we have to @@ -51,6 +55,35 @@ public class EditableSpotSceneImpl // extensions to DisplayScene provided by EditableScene because // we're extending from the DisplaySceneImpl class chain _edelegate = new EditableSceneImpl(model); + + // create our editable location and portal arrays. here the lack + // of multiple inheritance fucks us even harder. we have to let + // the DisplaySceneImpl maintain arrays of locations and portals + // and we maintain mirror arrays for our editable wrappers which + // delegate to the instances in the display scene's arrays. at + // least we can use array lists here to minimize the pain + int lcount = _locations.length; + int pidx = 0; + for (int i = 0; i < lcount; i++) { + EditableLocation loc; + + if (_locations[i] instanceof Portal) { + loc = new EditablePortal( + _portals[pidx], _emodel.locationNames[i], + _emodel.neighborNames[pidx], _emodel.targetLocNames[pidx]); + pidx++; + + // add portals to the portals array + _eportals.add(loc); + + } else { + loc = new EditableLocation( + _locations[i], _emodel.locationNames[i]); + } + + // everything goes into the locations array + _elocations.add(loc); + } } // documentation inherited @@ -74,6 +107,36 @@ public class EditableSpotSceneImpl throw new RuntimeException(errmsg); } + // documentation inherited + public String getName () + { + return _edelegate.getName(); + } + + // documentation inherited + public void setName (String name) + { + _edelegate.setName(name); + } + + // documentation inherited + public String[] getNeighborNames () + { + String errmsg = "Neighbor names can't be fetched directly from the " + + "EditableSpotScene because we need to know the associated " + + "location information to go along with our neighbor connections."; + throw new RuntimeException(errmsg); + } + + // documentation inherited + public void setNeighborNames (String[] neighborNames) + { + String errmsg = "Neighbor names can't be set directly in the " + + "EditableSpotScene because we need to know the associated " + + "location information to go along with our neighbor connections."; + throw new RuntimeException(errmsg); + } + // documentation inherited public void setDefaultEntranceId (int defaultEntranceId) { @@ -81,24 +144,27 @@ public class EditableSpotSceneImpl } // documentation inherited - public void addLocation (Location location) + public void addLocation (EditableLocation eloc) { - // add this location to the end of the list + // add the delegate location to the end of the location array int lcount = _locations.length; Location[] nlocs = new Location[lcount+1]; System.arraycopy(_locations, 0, nlocs, 0, lcount); - nlocs[lcount] = location; + nlocs[lcount] = eloc.location; _locations = nlocs; + + // add it to the editable locations list + _elocations.add(eloc); } // documentation inherited - public void removeLocation (Location location) + public void removeLocation (EditableLocation eloc) { // obtain the index of this location - int lidx = ListUtil.indexOfEqual(_locations, location); + int lidx = ListUtil.indexOfEqual(_locations, eloc.location); if (lidx == -1) { Log.warning("Can't remove location that isn't in our array " + - "[loc=" + location + "]."); + "[loc=" + eloc + "]."); } else { // create a new array minus this location @@ -107,34 +173,40 @@ public class EditableSpotSceneImpl System.arraycopy(_locations, 0, nlocs, 0, lidx); System.arraycopy(_locations, lidx+1, nlocs, lidx, lcount-lidx-1); _locations = nlocs; + + // remove it from the editable locations list + _elocations.remove(lidx); } } // documentation inherited - public void addPortal (Portal portal) + public void addPortal (EditablePortal eport) { - // add it to the locations array as well - addLocation(portal); + // add it to the locations lists as well + addLocation(eport); // now add it to the end of the _portals array int pcount = _portals.length; Portal[] nports = new Portal[pcount+1]; System.arraycopy(_portals, 0, nports, 0, pcount); - nports[pcount] = portal; + nports[pcount] = eport.portal; _portals = nports; + + // and to the editable portals list + _eportals.add(eport); } // documentation inherited - public void removePortal (Portal portal) + public void removePortal (EditablePortal eport) { // remove it from the locations array - removeLocation(portal); + removeLocation(eport); // and remove it from the portals array - int pidx = ListUtil.indexOfEqual(_portals, portal); + int pidx = ListUtil.indexOfEqual(_portals, eport.portal); if (pidx == -1) { Log.warning("Can't remove portal that isn't in our array " + - "[port=" + portal + "]."); + "[port=" + eport + "]."); } else { // create a new array minus this portal @@ -143,21 +215,24 @@ public class EditableSpotSceneImpl System.arraycopy(_portals, 0, nports, 0, pidx); System.arraycopy(_portals, pidx+1, nports, pidx, pcount-pidx-1); _portals = nports; + + // remove it from the editable portals list + _eportals.remove(pidx); } } // documentation inherited - public SceneModel getSceneModel () + public EditableSceneModel getSceneModel () { flushToModel(); return _edelegate.getSceneModel(); } // documentation inherited - public SpotSceneModel getSpotSceneModel () + public EditableSpotSceneModel getSpotSceneModel () { flushToModel(); - return _model; + return _emodel; } /** @@ -174,6 +249,7 @@ public class EditableSpotSceneImpl _model.locationY = new int[lcount]; _model.locationOrients = new int[lcount]; _model.locationClusters = new int[lcount]; + _emodel.locationNames = new String[lcount]; for (int i = 0; i < lcount; i++) { Location loc = _locations[i]; @@ -182,6 +258,9 @@ public class EditableSpotSceneImpl _model.locationY[i] = loc.y; _model.locationOrients[i] = loc.orientation; _model.locationClusters[i] = loc.clusterIndex; + + EditableLocation eloc = (EditableLocation)_elocations.get(i); + _emodel.locationNames[i] = eloc.name; } // flush the portals @@ -189,15 +268,31 @@ public class EditableSpotSceneImpl _model.portalIds = new int[pcount]; _model.neighborIds = new int[pcount]; _model.targetLocIds = new int[pcount]; + _model.targetLocIds = new int[pcount]; + _emodel.neighborNames = new String[pcount]; + _emodel.targetLocNames = new String[pcount]; for (int i = 0; i < pcount; i++) { Portal port = _portals[i]; _model.portalIds[i] = port.locationId; _model.neighborIds[i] = port.targetSceneId; _model.targetLocIds[i] = port.targetLocationId; + + EditablePortal eport = (EditablePortal)_eportals.get(i); + _emodel.neighborNames[i] = eport.targetSceneName; + _emodel.targetLocNames[i] = eport.targetLocName; } } + /** Our editable spot scene model. */ + protected EditableSpotSceneModel _emodel; + /** We have to delegate some methods to this guy. */ protected EditableSceneImpl _edelegate; + + /** A list of the editable locations (and portals) in this scene. */ + protected ArrayList _elocations = new ArrayList(); + + /** A list of just the editable portals in this scene. */ + protected ArrayList _eportals = new ArrayList(); } diff --git a/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneModel.java b/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneModel.java new file mode 100644 index 000000000..7c356f640 --- /dev/null +++ b/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneModel.java @@ -0,0 +1,20 @@ +// +// $Id: EditableSpotSceneModel.java,v 1.1 2001/12/04 22:34:04 mdb Exp $ + +package com.threerings.whirled.tools.spot; + +import com.threerings.whirled.spot.data.SpotSceneModel; +import com.threerings.whirled.tools.EditableSceneModel; + +public class EditableSpotSceneModel extends EditableSceneModel +{ + /** The spot scene model that we extend with editable info. */ + public SpotSceneModel spotSceneModel; + + /** The names of the locations in this scene. */ + public String[] locationNames; + + /** The names of the locations in neighboring scenes to which our + * portals link. */ + public String[] targetLocNames; +} diff --git a/src/java/com/threerings/whirled/tools/EditableScene.java b/src/java/com/threerings/whirled/tools/EditableScene.java index 5da295e7a..cfbbc0f41 100644 --- a/src/java/com/threerings/whirled/tools/EditableScene.java +++ b/src/java/com/threerings/whirled/tools/EditableScene.java @@ -1,5 +1,5 @@ // -// $Id: EditableScene.java,v 1.1 2001/11/12 20:56:56 mdb Exp $ +// $Id: EditableScene.java,v 1.2 2001/12/04 22:34:04 mdb Exp $ package com.threerings.whirled.tools; @@ -40,12 +40,32 @@ public interface EditableScene extends DisplayScene */ public void setNeighborIds (int[] neighborIds); - /** - * Implementations must provide a scene model that represents the - * current state of this editable scene in response to a call to this - * method. Whether they maintain an up to date scene model all along - * or generate one at the time this method is called is up to the - * implementation. + /** + * Returns the human readable name of this scene. */ - public SceneModel getSceneModel (); + public String getName (); + + /** + * Setse the human readable name of this scene. + */ + public void setName (String name); + + /** + * Returns the names of the neighbors of this scene. + */ + public String[] getNeighborNames (); + + /** + * Sets the names of the neighbors of this scene. + */ + public void setNeighborNames (String[] neighborNames); + + /** + * Implementations must provide an editable scene model that + * represents the current state of this editable scene in response to + * a call to this method. Whether they maintain an up to date scene + * model all along or generate one at the time this method is called + * is up to the implementation. + */ + public EditableSceneModel getSceneModel (); } diff --git a/src/java/com/threerings/whirled/tools/EditableSceneImpl.java b/src/java/com/threerings/whirled/tools/EditableSceneImpl.java index 74da2ca79..4085edef6 100644 --- a/src/java/com/threerings/whirled/tools/EditableSceneImpl.java +++ b/src/java/com/threerings/whirled/tools/EditableSceneImpl.java @@ -1,5 +1,5 @@ // -// $Id: EditableSceneImpl.java,v 1.2 2001/11/13 02:25:36 mdb Exp $ +// $Id: EditableSceneImpl.java,v 1.3 2001/12/04 22:34:04 mdb Exp $ package com.threerings.whirled.tools; @@ -17,9 +17,9 @@ public class EditableSceneImpl * Creates an instance that will obtain data from the supplied scene * model and update it when changes are made. */ - public EditableSceneImpl (SceneModel model) + public EditableSceneImpl (EditableSceneModel model) { - super(model, null); + super(model.sceneModel, null); } // documentation inherited @@ -41,8 +41,35 @@ public class EditableSceneImpl } // documentation inherited - public SceneModel getSceneModel () + public String getName () { - return _model; + return _emodel.sceneName; } + + // documentation inherited + public void setName (String name) + { + _emodel.sceneName = name; + } + + // documentation inherited + public String[] getNeighborNames () + { + return _emodel.neighborNames; + } + + // documentation inherited + public void setNeighborNames (String[] neighborNames) + { + _emodel.neighborNames = neighborNames; + } + + // documentation inherited + public EditableSceneModel getSceneModel () + { + return _emodel; + } + + /** A reference to our editable scene model. */ + protected EditableSceneModel _emodel; } diff --git a/src/java/com/threerings/whirled/tools/EditableSceneModel.java b/src/java/com/threerings/whirled/tools/EditableSceneModel.java new file mode 100644 index 000000000..ef6f99e78 --- /dev/null +++ b/src/java/com/threerings/whirled/tools/EditableSceneModel.java @@ -0,0 +1,22 @@ +// +// $Id: EditableSceneModel.java,v 1.1 2001/12/04 22:34:04 mdb Exp $ + +package com.threerings.whirled.tools; + +import com.threerings.whirled.data.SceneModel; + +/** + * The editable scene model contains information above and beyond the + * regular scene model that is necessary for editing and loading scenes. + */ +public class EditableSceneModel +{ + /** The scene model that we extend. */ + public SceneModel sceneModel; + + /** The human readable name of this scene. */ + public String sceneName; + + /** The human readable name of this scene's neighbors. */ + public String[] neighborNames; +}