
com.threerings.miso.client.SceneBlockResolver Maven / Gradle / Ivy
//
// 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.miso.client;
import java.awt.EventQueue;
import com.samskivert.util.Histogram;
import com.samskivert.util.LoopingThread;
import com.samskivert.util.Queue;
import static com.threerings.miso.Log.log;
/**
* A separate thread for resolving miso scene blocks.
*/
public class SceneBlockResolver extends LoopingThread
{
public SceneBlockResolver ()
{
super("SceneBlockResolver");
}
/**
* Queues up a scene block for resolution.
*/
public void resolveBlock (SceneBlock block, boolean hipri)
{
log.debug("Queueing block for resolution", "block", block, "hipri", hipri);
if (hipri) {
_queue.prepend(block);
} else {
_queue.append(block);
}
}
/**
* Temporarily suspends the scene block resolution thread.
*/
public synchronized void suspendResolution ()
{
_resolving = false;
}
/**
* Restores the operation of the scene block resolution thread after a
* previous call to {@link #suspendResolution}.
*/
public synchronized void restoreResolution ()
{
_resolving = true;
notify();
}
/**
* Returns the number of scene blocks on the resolution queue.
*/
public int queueSize ()
{
return _queue.size();
}
@Override
public void iterate ()
{
final SceneBlock block = _queue.get();
while (!_resolving) {
synchronized (this) {
try {
wait();
} catch (InterruptedException ie) {
log.info("Resolver interrupted.");
}
}
}
try {
long start = System.currentTimeMillis();
log.debug("Resolving block " + block + ".");
if (block.resolve()) {
log.debug("Resolved block " + block + ".");
}
long elapsed = System.currentTimeMillis() - start;
_histo.addValue((int)elapsed);
// warn if a block takes a long time to resolve
if (elapsed > LONG_RESOLVE_TIME) {
log.warning("Block took long time to resolve [block=" + block +
", elapsed=" + elapsed + "ms].");
}
// queue it up on the AWT thread to complete its resolution
// final boolean report = (_queue.size() == 0);
EventQueue.invokeLater(new Runnable() {
public void run () {
// let the block's panel know that it is resolved
block.wasResolved();
// report statistics
// if (report) {
// log.info("Resolution histogram " + _histo.summarize() + ".");
// }
}
});
} catch (Exception e) {
log.warning("Block failed during resolution " + block + ".", e);
}
}
/** The invoker's queue of units to be executed. */
protected Queue _queue = new Queue();
/** Indicates whether or not we are resolving or suspended. */
protected boolean _resolving = true;
/** Used to time block loading. */
protected Histogram _histo = new Histogram(0, 25, 100);
/** Blocks shouldn't take too long to resolve. */
protected static final long LONG_RESOLVE_TIME = 500L;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy