Type safety and widening.
git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@246 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -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<ObserverList,ObserverOp>(observers, event));
|
||||
}
|
||||
|
||||
/** Type safety jockeying. */
|
||||
protected abstract SortableArrayList<? extends AbstractMedia> 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<ObserverList,ObserverOp> 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<Tuple<ObserverList,ObserverOp>> _notify =
|
||||
new ArrayList<Tuple<ObserverList,ObserverOp>>();
|
||||
|
||||
/** Our render-order sorted list of media. */
|
||||
protected SortableArrayList _media = new SortableArrayList();
|
||||
protected SortableArrayList<AbstractMedia> _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 <code>0</code>. */
|
||||
/** 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<AbstractMedia> RENDER_ORDER =
|
||||
new Comparator<AbstractMedia>() {
|
||||
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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user