Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  //
  // Nenya library - tools for developing networked games
  // Copyright (C) 2002-2012 Three Rings Design, Inc., All Rights Reserved
  // https://github.com/threerings/nenya
  //
  // This library is free software; you can redistribute it and/or modify it
  // under the terms of the GNU Lesser General Public License as published
  // by the Free Software Foundation; either version 2.1 of the License, or
  // (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 // Lesser General Public License for more details.
 //
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 package com.threerings.media;
 
 import java.util.List;
 
 import java.awt.Shape;
 
 
 
 import static com.threerings.media.Log.log;

Manages, ticks, and paints AbstractMedia.
 
 public abstract class AbstractMediaManager
     implements MediaConstants
 {
    
Provides this media manager with its host and region manager.
 
     public void init (MediaHost hostRegionManager remgr)
     {
          = host;
          = remgr;
     }

    
Returns region manager in use by this manager.
 
     public RegionManager getRegionManager ()
     {
         return ;
     }

    
Creates a graphics that can be used to compute metrics or whatever else a media might need. The caller should call java.awt.Graphics.dispose() on the returned object when it is done with it.
 
     public Graphics2D createGraphics ()
     {
         return .createGraphics();
     }

    
Must be called every frame so that the media can be properly updated.
 
     public void tick (long 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
     }

    
This will always be called prior to the paint(java.awt.Graphics2D,int,java.awt.Shape) calls for a particular tick. Because it is possible that there will be no dirty regions and thus no calls to paint(java.awt.Graphics2D,int,java.awt.Shape) 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 ()
     {
         // now that we're done ticking, we can safely clear this
          = 0;
     }

    
Renders all registered media in the given layer that intersect the supplied clipping rectangle to the given graphics context.

Parameters:
layer the layer to render; one of MediaConstants.FRONT, MediaConstants.BACK, or MediaConstants.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 gfxint layerShape clip)
    {
        for (int ii = 0, nn = .size(); ii < nnii++) {
            AbstractMedia media = .get(ii);
            int order = media.getRenderOrder();
            try {
                if (((layer == ) || (layer ==  && order >= 0) ||
                     (layer ==  && order < 0)) && clip.intersects(media.getBounds())) {
                    media.paint(gfx);
                }
            } catch (Exception e) {
                .warning("Failed to render media""media"mediae);
            }
        }
    }

    
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)
    {
        if ( > 0) {
            .warning("Egads! Asked to fastForward() during a tick."new Exception());
        }
        for (int ii = 0, nn = .size(); ii < nnii++) {
            .get(ii).fastForward(timeDelta);
        }
    }

    
Returns true if the specified media is being managed by this media manager.
    public boolean isManaged (AbstractMedia media)
    {
        return .contains(media);
    }

    
Called by a VirtualMediaPanel when the view that contains our media is scrolled.

Parameters:
dx the scrolled distance in the x direction (in pixels).
dy the scrolled distance in the y direction (in pixels).
    public void viewLocationDidChange (int dxint dy)
    {
        // let our media know
        for (int ii = 0, ll = .size(); ii < llii++) {
            .get(ii).viewLocationDidChange(dxdy);
        }
    }

    
Called by a AbstractMedia when its render order has changed.
    public void renderOrderDidChange (AbstractMedia media)
    {
        if ( > 0) {
            .warning("Egads! Render order changed during a tick."new Exception());
        }
        .remove(media);
        .insertSorted(media);
    }

    
Calls AbstractMedia.tick(long) 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
        for ( = 0;  < .size(); ++) {
            tickMedia(.get(), tickStamp);
        }
         = -1;
    }

    
Inserts the specified media into this manager, return true on success.
    protected boolean insertMedia (AbstractMedia media)
    {
        if (.contains(media)) {
            .warning("Attempt to insert media more than once [media=" + media + "].",
                        new Exception());
            return false;
        }
        media.init(this);
        int ipos = .insertSorted(media);
        // 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 ( > 0L) {
            if ( == -1) {
                // if we're done with our own call to tick(), we need to tick this new media
                tickMedia(media);
            } else if (ipos <= ) {
                // 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)
                ++;
                tickMedia(media);
            }
        }
        return true;
    }

    
A helper function used to call AbstractMedia.tick(long).
    protected final void tickMedia (AbstractMedia medialong tickStamp)
    {
        if (media._firstTick == 0L) {
            media.willStart(tickStamp);
        }
        media.tick(tickStamp);
    }

    
Removes the specified media from this manager, return true on success.
    protected boolean removeMedia (AbstractMedia media)
    {
        int mpos = .indexOf(media);
        if (mpos != -1) {
            .remove(mpos);
            media.invalidate();
            media.shutdown();
            // if we're in the middle of ticking, we need to adjust the _tickpos if necessary
            if (mpos <= ) {
                --;
            }
            return true;
        }
        .warning("Attempt to remove media that wasn't inserted [media=" + media + "].");
        return false;
    }

    
Clears all media from the manager and calls AbstractMedia.shutdown() on each. This does not invalidate the media's vacated bounds; it is assumed that it will be ok.
    protected void clearMedia ()
    {
        if ( > 0) {
            .warning("Egads! Requested to clearMedia() during a tick."new Exception());
        }
        for (int ii = .size() - 1; ii >= 0; ii--) {
            .remove(ii).shutdown();
        }
    }

    
Queues the notification for dispatching after we've ticked all the media.
    public void queueNotification (ObserverList<ObjectobserversObserverOp<Objectevent)
    {
        .add(new Tuple<ObserverList<Object>,ObserverOp<Object>>(observersevent));
    }

    
Type safety jockeying.
    protected abstract SortableArrayList<? extends AbstractMediacreateMediaList ();

    
Dispatches all queued media notifications.
    protected void dispatchNotifications ()
    {
        for (int ii = 0, nn = .size(); ii < nnii++) {
            Tuple<ObserverList<Object>,ObserverOp<Object>> tuple = .get(ii);
            tuple.left.apply(tuple.right);
        }
        .clear();
    }

    
Used to sort media by render order.
    protected static final Comparator<AbstractMediaRENDER_ORDER =
        new Comparator<AbstractMedia>() {
        public int compare (AbstractMedia am1AbstractMedia am2) {
            return am1.renderCompareTo(am2);
        }
    };

    
The media host we're working with.
    protected MediaHost _host;

    
The region manager.
    protected RegionManager _remgr;

    
List of observers to notify at the end of the tick.
    protected List<Tuple<ObserverList<Object>, ObserverOp<Object>>> _notify = Lists.newArrayList();

    
Our render-order sorted list of media.
    @SuppressWarnings("unchecked"protected SortableArrayList<AbstractMedia_media =
The position in our media list that we're ticking (while in the middle of a call to tick(long)) otherwise -1.
    protected int _tickpos = -1;

    
The tick stamp if the manager is in the midst of a call to tick(long), else 0.
    protected long _tickStamp;
New to GrepCode? Check out our FAQ X