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