package greenfoot.platforms.standalone;
import greenfoot.Actor;
import greenfoot.World;
import greenfoot.WorldVisitor;
import greenfoot.core.WorldHandler;
import greenfoot.export.GreenfootScenarioViewer;
import greenfoot.gui.WorldRenderer;
import greenfoot.platforms.WorldHandlerDelegate;
import javafx.animation.AnimationTimer;
import threadchecker.OnThread;
import threadchecker.Tag;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicReference;
| Implementation for running scenarios in a standalone application or applet.
|
| @author Poul Henriksen
|
@OnThread(Tag.Simulation)
public class WorldHandlerDelegateStandAlone
implements WorldHandlerDelegate{
@OnThread(Tag.Any)
private final GreenfootScenarioViewer viewer;
private boolean lockScenario;
private final WorldRenderer worldRenderer = new WorldRenderer();
private long lastFramePaint;
@OnThread(Tag.Any)
private final AtomicReference<BufferedImage> pendingImage = new AtomicReference<>(null);
@OnThread(Tag.Any)
private final ConcurrentLinkedQueue<BufferedImage> oldImages = new ConcurrentLinkedQueue<>();
@OnThread(Tag.FXPlatform)
public WorldHandlerDelegateStandAlone(GreenfootScenarioViewer viewer, boolean lockScenario)
{
this.viewer = viewer;
this.lockScenario = lockScenario;
new AnimationTimer() {
@Override
@OnThread(Tag.FXPlatform)
public void handle(long now)
{
BufferedImage worldImage = pendingImage.getAndSet(null);
if (worldImage != null)
{
viewer.setWorldImage(worldImage);
oldImages.add(worldImage);
}
}
}.start();
}
public boolean maybeShowPopup(MouseEvent e)
{
return false;
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseMoved(MouseEvent e)
{
}
@Override
@OnThread(Tag.Any)
public void setWorld(final World oldWorld, final World newWorld)
{
}
@Override
@OnThread(Tag.Any)
public void instantiateNewWorld(String className, Runnable runIfError)
{
WorldHandler.getInstance().clearWorldSet();
World newWorld = viewer.instantiateNewWorld();
if (! WorldHandler.getInstance().checkWorldSet()) {
WorldHandler.getInstance().setWorld(newWorld, false);
}
}
@OnThread(Tag.Any)
public void discardWorld(World world)
{
BufferedImage image = pendingImage.getAndSet(null);
if (image != null)
{
oldImages.add(image);
}
}
public void addActor(Actor actor, int x, int y)
{
}
@Override
public void objectAddedToWorld(Actor actor)
{
}
@Override
public String ask(String prompt)
{
String r = viewer.ask(prompt);
return r;
}
@Override
public void paint(World world, boolean forcePaint)
{
if (world == null)
return;
long now = System.nanoTime();
if (now - lastFramePaint < 10_000_000L)
return;
lastFramePaint = now;
int imageWidth = WorldVisitor.getWidthInPixels(world);
int imageHeight = WorldVisitor.getHeightInPixels(world);
BufferedImage worldImage = oldImages.poll();
if (worldImage == null || worldImage.getHeight() != imageHeight
|| worldImage.getWidth() != imageWidth)
{
worldImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
}
worldRenderer.renderWorld(world, worldImage);
BufferedImage oldImage = pendingImage.getAndSet(worldImage);
if (oldImage != null)
{
oldImages.add(oldImage);
}
}
@Override
public void notifyStoppedWithError()
{
}
}
top,
use,
map,
class WorldHandlerDelegateStandAlone
. WorldHandlerDelegateStandAlone
. handle
. maybeShowPopup
. mouseClicked
. mouseMoved
. setWorld
. instantiateNewWorld
. discardWorld
. addActor
. objectAddedToWorld
. ask
. paint
. notifyStoppedWithError
200 neLoCode
+ 2 LoComm