From 9a30debf425afa6f528bf6496e55d2de5a83bd29 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Tue, 15 May 2007 16:59:58 +0000 Subject: [PATCH] Type safety and widening. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@246 ed5b42cb-e716-0410-a449-f6a68f950b19 --- .../media/AbstractMediaManager.java | 151 ++++++++---------- .../media/animation/AnimationManager.java | 32 ++-- .../media/sprite/SpriteManager.java | 96 +++++------ 3 files changed, 134 insertions(+), 145 deletions(-) diff --git a/src/java/com/threerings/media/AbstractMediaManager.java b/src/java/com/threerings/media/AbstractMediaManager.java index ce8f922d..a4e570b7 100644 --- a/src/java/com/threerings/media/AbstractMediaManager.java +++ b/src/java/com/threerings/media/AbstractMediaManager.java @@ -66,25 +66,22 @@ public abstract class AbstractMediaManager } /** - * Must be called every frame so that the media can be properly - * updated. + * Must be called every frame so that the media can be properly updated. */ public void tick (long tickStamp) { _tickStamp = tickStamp; tickAllMedia(tickStamp); dispatchNotifications(); - // we clear our tick stamp when we're about to be painted, this - // lets us handle situations when yet more media is slipped in - // between our being ticked and our being painted + // we clear our tick stamp when we're about to be painted, this lets us handle situations + // when yet more media is slipped in between our being ticked and our being painted } /** - * This will always be called prior to the {@link #paint} calls for a - * particular tick. Because it is possible that there will be no dirty - * regions and thus no calls to {@link #paint} this method exists so - * that the media manager can guarantee that it will be notified when - * all ticking is complete and the painting phase has begun. + * This will always be called prior to the {@link #paint} calls for a particular tick. Because + * it is possible that there will be no dirty regions and thus no calls to {@link #paint} this + * method exists so that the media manager can guarantee that it will be notified when all + * ticking is complete and the painting phase has begun. */ public void willPaint () { @@ -93,41 +90,36 @@ public abstract class AbstractMediaManager } /** - * Renders all registered media in the given layer that intersect - * the supplied clipping rectangle to the given graphics context. + * Renders all registered media in the given layer that intersect the supplied clipping + * rectangle to the given graphics context. * - * @param layer the layer to render; one of {@link #FRONT}, {@link - * #BACK}, or {@link #ALL}. The front layer contains all animations - * with a positive render order; the back layer contains all - * animations with a negative render order; all, both. + * @param layer the layer to render; one of {@link #FRONT}, {@link #BACK}, or {@link #ALL}. + * The front layer contains all animations with a positive render order; the back layer + * contains all animations with a negative render order; all, both. */ public void paint (Graphics2D gfx, int layer, Shape clip) { for (int ii = 0, nn = _media.size(); ii < nn; ii++) { - AbstractMedia media = (AbstractMedia)_media.get(ii); + AbstractMedia media = _media.get(ii); int order = media.getRenderOrder(); try { - if (((layer == ALL) || - (layer == FRONT && order >= 0) || - (layer == BACK && order < 0)) && - clip.intersects(media.getBounds())) { + if (((layer == ALL) || (layer == FRONT && order >= 0) || + (layer == BACK && order < 0)) && clip.intersects(media.getBounds())) { media.paint(gfx); } } catch (Exception e) { - Log.warning("Failed to render media " + - "[media=" + media + ", e=" + e + "]."); + Log.warning("Failed to render media [media=" + media + ", e=" + e + "]."); Log.logStackTrace(e); } } } /** - * If the manager is paused for some length of time, it should - * be fast forwarded by the appropriate number of milliseconds. This - * allows media to smoothly pick up where they left off rather than - * abruptly jumping into the future, thinking that some outrageous - * amount of time passed since their last tick. + * If the manager is paused for some length of time, it should be fast forwarded by the + * appropriate number of milliseconds. This allows media to smoothly pick up where they left + * off rather than abruptly jumping into the future, thinking that some outrageous amount of + * time passed since their last tick. */ public void fastForward (long timeDelta) { @@ -136,14 +128,13 @@ public abstract class AbstractMediaManager Thread.dumpStack(); } - for (int ii=0, nn=_media.size(); ii < nn; ii++) { - ((AbstractMedia) _media.get(ii)).fastForward(timeDelta); + for (int ii = 0, nn = _media.size(); ii < nn; ii++) { + _media.get(ii).fastForward(timeDelta); } } /** - * Returns true if the specified media is being managed by this media - * manager. + * Returns true if the specified media is being managed by this media manager. */ public boolean isManaged (AbstractMedia media) { @@ -151,8 +142,7 @@ public abstract class AbstractMediaManager } /** - * Called by a {@link VirtualMediaPanel} when the view that contains our - * media is scrolled. + * Called by a {@link VirtualMediaPanel} when the view that contains our media is scrolled. * * @param dx the scrolled distance in the x direction (in pixels). * @param dy the scrolled distance in the y direction (in pixels). @@ -161,7 +151,7 @@ public abstract class AbstractMediaManager { // let our media know for (int ii = 0, ll = _media.size(); ii < ll; ii++) { - ((AbstractMedia)_media.get(ii)).viewLocationDidChange(dx, dy); + _media.get(ii).viewLocationDidChange(dx, dy); } } @@ -180,29 +170,26 @@ public abstract class AbstractMediaManager } /** - * Calls {@link AbstractMedia#tick} on all media to give them a chance - * to move about, change their look, generate dirty regions, and so - * forth. + * Calls {@link AbstractMedia#tick} on all media to give them a chance to move about, change + * their look, generate dirty regions, and so forth. */ protected void tickAllMedia (long tickStamp) { - // we use _tickpos so that it can be adjusted if media is added or - // removed during the tick dispatch + // we use _tickpos so that it can be adjusted if media is added or removed during the tick + // dispatch for (_tickpos = 0; _tickpos < _media.size(); _tickpos++) { - tickMedia((AbstractMedia) _media.get(_tickpos), tickStamp); + tickMedia(_media.get(_tickpos), tickStamp); } _tickpos = -1; } /** - * Inserts the specified media into this manager, return true on - * success. + * Inserts the specified media into this manager, return true on success. */ protected boolean insertMedia (AbstractMedia media) { if (_media.contains(media)) { - Log.warning("Attempt to insert media more than once " + - "[media=" + media + "]."); + Log.warning("Attempt to insert media more than once [media=" + media + "]."); Thread.dumpStack(); return false; } @@ -210,20 +197,17 @@ public abstract class AbstractMediaManager media.init(this); int ipos = _media.insertSorted(media, RENDER_ORDER); - // if we've started our tick but have not yet painted our media, - // we need to take care that this newly added media will be ticked - // before our upcoming render + // if we've started our tick but have not yet painted our media, we need to take care that + // this newly added media will be ticked before our upcoming render if (_tickStamp > 0L) { if (_tickpos == -1) { - // if we're done with our own call to tick(), we - // definitely need to tick this new media + // if we're done with our own call to tick(), we need to tick this new media tickMedia(media, _tickStamp); } else if (ipos <= _tickpos) { - // otherwise, we're in the middle of our call to tick() - // and we only need to tick this guy if he's being - // inserted before our current tick position (if he's - // inserted after our current position, we'll get to him - // as part of this tick iteration) + // otherwise, we're in the middle of our call to tick() and we only need to tick + // this guy if he's being inserted before our current tick position (if he's + // inserted after our current position, we'll get to him as part of this tick + // iteration) _tickpos++; tickMedia(media, _tickStamp); } @@ -242,8 +226,7 @@ public abstract class AbstractMediaManager } /** - * Removes the specified media from this manager, return true on - * success. + * Removes the specified media from this manager, return true on success. */ protected boolean removeMedia (AbstractMedia media) { @@ -252,22 +235,19 @@ public abstract class AbstractMediaManager _media.remove(mpos); media.invalidate(); media.shutdown(); - // if we're in the middle of ticking, we need to adjust the - // _tickpos if necessary + // if we're in the middle of ticking, we need to adjust the _tickpos if necessary if (mpos <= _tickpos) { _tickpos--; } return true; } - Log.warning("Attempt to remove media that wasn't inserted " + - "[media=" + media + "]."); + Log.warning("Attempt to remove media that wasn't inserted [media=" + media + "]."); return false; } /** - * Clears all media from the manager and calls {@link - * AbstractMedia#shutdown} on each. This does not invalidate the - * media's vacated bounds; it is assumed that it will be ok. + * Clears all media from the manager and calls {@link AbstractMedia#shutdown} on each. This + * does not invalidate the media's vacated bounds; it is assumed that it will be ok. */ protected void clearMedia () { @@ -276,29 +256,30 @@ public abstract class AbstractMediaManager Thread.dumpStack(); } - for (int ii=_media.size() - 1; ii >= 0; ii--) { - AbstractMedia media = (AbstractMedia) _media.remove(ii); - media.shutdown(); + for (int ii = _media.size() - 1; ii >= 0; ii--) { + _media.remove(ii).shutdown(); } } /** - * Queues the notification for dispatching after we've ticked all the - * media. + * Queues the notification for dispatching after we've ticked all the media. */ public void queueNotification (ObserverList observers, ObserverOp event) { - _notify.add(new Tuple(observers, event)); + _notify.add(new Tuple(observers, event)); } + /** Type safety jockeying. */ + protected abstract SortableArrayList createMediaList (); + /** * Dispatches all queued media notifications. */ protected void dispatchNotifications () { for (int ii = 0, nn = _notify.size(); ii < nn; ii++) { - Tuple tuple = (Tuple)_notify.get(ii); - ((ObserverList)tuple.left).apply((ObserverOp)tuple.right); + Tuple tuple = _notify.get(ii); + tuple.left.apply(tuple.right); } _notify.clear(); } @@ -310,28 +291,26 @@ public abstract class AbstractMediaManager protected RegionManager _remgr; /** List of observers to notify at the end of the tick. */ - protected ArrayList _notify = new ArrayList(); + protected ArrayList> _notify = + new ArrayList>(); /** Our render-order sorted list of media. */ - protected SortableArrayList _media = new SortableArrayList(); + protected SortableArrayList _media; - /** The position in our media list that we're ticking in the middle of - * a call to {@link #tick} otherwise -1. */ + /** The position in our media list that we're ticking (while in the middle of a call to {@link + * #tick}) otherwise -1. */ protected int _tickpos = -1; - /** The tick stamp if the manager is in the midst of a call to {@link - * #tick}, else 0. */ + /** The tick stamp if the manager is in the midst of a call to {@link #tick}, else 0. */ protected long _tickStamp; /** Used to sort media by render order. */ - protected static final Comparator RENDER_ORDER = new Comparator() { - public int compare (Object o1, Object o2) { - int result = (((AbstractMedia)o1)._renderOrder - - ((AbstractMedia)o2)._renderOrder); - return (result != 0) ? result : - // find some other way to keep them stable relative to - // each other - o1.hashCode() - o2.hashCode(); + protected static final Comparator RENDER_ORDER = + new Comparator() { + public int compare (AbstractMedia am1, AbstractMedia am2) { + int result = am1._renderOrder - am2._renderOrder; + // if render order is same, use hashcode to keep them stable relative to each other + return (result != 0) ? result : am1.hashCode() - am2.hashCode(); } }; } diff --git a/src/java/com/threerings/media/animation/AnimationManager.java b/src/java/com/threerings/media/animation/AnimationManager.java index 9b2f9207..be15a8f7 100644 --- a/src/java/com/threerings/media/animation/AnimationManager.java +++ b/src/java/com/threerings/media/animation/AnimationManager.java @@ -21,19 +21,20 @@ package com.threerings.media.animation; +import com.samskivert.util.SortableArrayList; + +import com.threerings.media.AbstractMedia; import com.threerings.media.AbstractMediaManager; import com.threerings.media.MediaHost; /** - * Manages a collection of animations, ticking them when the animation - * manager itself is ticked and generating events when animations finish - * and suchlike. + * Manages a collection of animations, ticking them when the animation manager itself is ticked and + * generating events when animations finish and suchlike. */ public class AnimationManager extends AbstractMediaManager { /** - * Registers the given {@link Animation} with the animation manager - * for ticking and painting. + * Registers the given {@link Animation} with the animation manager for ticking and painting. */ public void registerAnimation (Animation anim) { @@ -41,23 +42,22 @@ public class AnimationManager extends AbstractMediaManager } /** - * Un-registers the given {@link Animation} from the animation - * manager. The bounds of the animation will automatically be - * invalidated so that they are properly rerendered in the absence of - * the animation. + * Un-registers the given {@link Animation} from the animation manager. The bounds of the + * animation will automatically be invalidated so that they are properly rerendered in the + * absence of the animation. */ public void unregisterAnimation (Animation anim) { removeMedia(anim); } - // documentation inherited + @Override // from AbstractMediaManager protected void tickAllMedia (long tickStamp) { super.tickAllMedia(tickStamp); - for (int ii = _media.size() - 1; ii >= 0; ii--) { - Animation anim = (Animation)_media.get(ii); + for (int ii = _anims.size() - 1; ii >= 0; ii--) { + Animation anim = _anims.get(ii); if (!anim.isFinished()) { continue; } @@ -69,4 +69,12 @@ public class AnimationManager extends AbstractMediaManager // Log.info("Removed finished animation " + anim + "."); } } + + @Override // from AbstractMediaManager + protected SortableArrayList createMediaList () + { + return (_anims = new SortableArrayList()); + } + + protected SortableArrayList _anims; } diff --git a/src/java/com/threerings/media/sprite/SpriteManager.java b/src/java/com/threerings/media/sprite/SpriteManager.java index 15488eac..2acb80f9 100644 --- a/src/java/com/threerings/media/sprite/SpriteManager.java +++ b/src/java/com/threerings/media/sprite/SpriteManager.java @@ -29,7 +29,9 @@ import java.util.List; import java.util.Iterator; import com.samskivert.util.Predicate; +import com.samskivert.util.SortableArrayList; +import com.threerings.media.AbstractMedia; import com.threerings.media.AbstractMediaManager; import com.threerings.media.MediaHost; @@ -39,21 +41,19 @@ import com.threerings.media.MediaHost; public class SpriteManager extends AbstractMediaManager { /** - * When an animated view processes its dirty rectangles, it may - * require an expansion of the dirty region which may in turn - * require the invalidation of more sprites than were originally - * invalid. In such cases, the animated view can call back to the - * sprite manager, asking it to append the sprites that intersect - * a particular region to the given list. + * When an animated view processes its dirty rectangles, it may require an expansion of the + * dirty region which may in turn require the invalidation of more sprites than were originally + * invalid. In such cases, the animated view can call back to the sprite manager, asking it to + * append the sprites that intersect a particular region to the given list. * * @param list the list to fill with any intersecting sprites. * @param shape the shape in which we have interest. */ - public void getIntersectingSprites (List list, Shape shape) + public void getIntersectingSprites (List list, Shape shape) { - int size = _media.size(); + int size = _sprites.size(); for (int ii = 0; ii < size; ii++) { - Sprite sprite = (Sprite)_media.get(ii); + Sprite sprite = _sprites.get(ii); if (sprite.intersects(shape)) { list.add(sprite); } @@ -61,21 +61,20 @@ public class SpriteManager extends AbstractMediaManager } /** - * When an animated view is determining what entity in its view is - * under the mouse pointer, it may require a list of sprites that are - * "hit" by a particular pixel. The sprites' bounds are first checked - * and sprites with bounds that contain the supplied point are further - * checked for a non-transparent at the specified location. + * When an animated view is determining what entity in its view is under the mouse pointer, it + * may require a list of sprites that are "hit" by a particular pixel. The sprites' bounds are + * first checked and sprites with bounds that contain the supplied point are further checked + * for a non-transparent at the specified location. * - * @param list the list to fill with any intersecting sprites, the - * sprites with the highest render order provided first. + * @param list the list to fill with any intersecting sprites, the sprites with the highest + * render order provided first. * @param x the x (screen) coordinate to be checked. * @param y the y (screen) coordinate to be checked. */ - public void getHitSprites (List list, int x, int y) + public void getHitSprites (List list, int x, int y) { - for (int ii = _media.size() - 1; ii >= 0; ii--) { - Sprite sprite = (Sprite)_media.get(ii); + for (int ii = _sprites.size() - 1; ii >= 0; ii--) { + Sprite sprite = _sprites.get(ii); if (sprite.hitTest(x, y)) { list.add(sprite); } @@ -83,8 +82,7 @@ public class SpriteManager extends AbstractMediaManager } /** - * Finds the sprite with the highest render order that hits the - * specified pixel. + * Finds the sprite with the highest render order that hits the specified pixel. * * @param x the x (screen) coordinate to be checked * @param y the y (screen) coordinate to be checked @@ -93,8 +91,8 @@ public class SpriteManager extends AbstractMediaManager public Sprite getHighestHitSprite (int x, int y) { // since they're stored in lowest -> highest order.. - for (int ii = _media.size() - 1; ii >= 0; ii--) { - Sprite sprite = (Sprite)_media.get(ii); + for (int ii = _sprites.size() - 1; ii >= 0; ii--) { + Sprite sprite = _sprites.get(ii); if (sprite.hitTest(x, y)) { return sprite; } @@ -116,27 +114,25 @@ public class SpriteManager extends AbstractMediaManager } /** - * Returns a list of all sprites registered with the sprite manager. - * The returned list is immutable, sprites should be added or removed - * using {@link #addSprite} or {@link #removeSprite}. + * Returns a list of all sprites registered with the sprite manager. The returned list is + * immutable, sprites should be added or removed using {@link #addSprite} or {@link + * #removeSprite}. */ - public List getSprites () + public List getSprites () { - return Collections.unmodifiableList(_media); + return Collections.unmodifiableList(_sprites); } /** - * Returns an iterator over our managed sprites. Do not call - * {@link Iterator#remove}. + * Returns an iterator over our managed sprites. Do not call {@link Iterator#remove}. */ - public Iterator enumerateSprites () + public Iterator enumerateSprites () { - return _media.iterator(); + return _sprites.iterator(); } /** - * Removes the specified sprite from the set of sprites managed by - * this manager. + * Removes the specified sprite from the set of sprites managed by this manager. * * @param sprite the sprite to remove. */ @@ -151,14 +147,14 @@ public class SpriteManager extends AbstractMediaManager public void removeSprites (Predicate pred) { int idxoff = 0; - for (int ii = 0, ll = _media.size(); ii < ll; ii++) { - Sprite sprite = (Sprite)_media.get(ii-idxoff); + for (int ii = 0, ll = _sprites.size(); ii < ll; ii++) { + Sprite sprite = _sprites.get(ii-idxoff); if (pred.isMatch(sprite)) { - _media.remove(sprite); + _sprites.remove(sprite); sprite.invalidate(); sprite.shutdown(); - // we need to preserve the original "index" relative to the - // current tick position, so we don't decrement ii directly + // we need to preserve the original "index" relative to the current tick position, + // so we don't decrement ii directly idxoff++; if (ii <= _tickpos) { _tickpos--; @@ -174,8 +170,8 @@ public class SpriteManager extends AbstractMediaManager */ public void renderSpritePaths (Graphics2D gfx) { - for (int ii=0, nn=_media.size(); ii < nn; ii++) { - Sprite sprite = (Sprite)_media.get(ii); + for (int ii=0, nn=_sprites.size(); ii < nn; ii++) { + Sprite sprite = _sprites.get(ii); sprite.paintPath(gfx); } } @@ -192,7 +188,7 @@ public class SpriteManager extends AbstractMediaManager // // gather a list of all sprite collisions // int size = _sprites.size(); // for (int ii = 0; ii < size; ii++) { -// Sprite sprite = (Sprite)_sprites.get(ii); +// Sprite sprite = _sprites.get(ii); // checkCollisions(ii, size, sprite); // } // } @@ -224,7 +220,7 @@ public class SpriteManager extends AbstractMediaManager // int edgeX = bounds.x + bounds.width; // // for (int ii = (idx + 1); ii < size; ii++) { -// Sprite other = (Sprite)_sprites.get(ii); +// Sprite other = _sprites.get(ii); // Rectangle obounds = other.getBounds(); // if (obounds.x > edgeX) { // // since sprites are stored in the list sorted by @@ -243,13 +239,19 @@ public class SpriteManager extends AbstractMediaManager // protected static final Comparator SPRITE_COMP = new SpriteComparator(); // // /** Used to sort sprites. */ -// protected static class SpriteComparator implements Comparator +// protected static class SpriteComparator implements Comparator // { -// public int compare (Object o1, Object o2) +// public int compare (Sprite s1, Sprite s2) // { -// Sprite s1 = (Sprite)o1; -// Sprite s2 = (Sprite)o2; // return (s2.getX() - s1.getX()); // } // } + + @Override // from AbstractMediaManager + protected SortableArrayList createMediaList () + { + return (_sprites = new SortableArrayList()); + } + + protected SortableArrayList _sprites; }