package it.cavallium.warppi.gui.graphicengine.impl.swing; import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; import it.cavallium.warppi.WarpPI; import it.cavallium.warppi.StaticVars; import it.cavallium.warppi.gui.graphicengine.BinaryFont; import it.cavallium.warppi.gui.graphicengine.GraphicEngine; import it.cavallium.warppi.gui.graphicengine.RenderingLoop; import it.cavallium.warppi.gui.graphicengine.Skin; import it.cavallium.warppi.util.EventSubmitter; public class SwingEngine implements GraphicEngine { private final int defaultWidth; private final int defaultHeight; private SwingWindow INSTANCE; public SwingRenderer r; public volatile BufferedImage g; public volatile boolean initialized; public SwingEngine(int defaultWidth, int defaultHeight) { this.defaultWidth = defaultWidth; this.defaultHeight = defaultHeight; } @Override public void setTitle(final String title) { INSTANCE.setTitle(title); } @Override public void setResizable(final boolean r) { INSTANCE.setResizable(r); if (!r) INSTANCE.setUndecorated(true); } @Override public void setDisplayMode(final int ww, final int wh) { INSTANCE.setSize(ww, wh); r.size = new int[] { ww, wh }; SwingRenderer.canvas2d = new int[ww * wh]; g = new BufferedImage(ww, wh, BufferedImage.TYPE_INT_RGB); } @Override public void create() { create(null); } @Override public void create(final Runnable onInitialized) { r = new SwingRenderer(); g = new BufferedImage(r.size[0], r.size[1], BufferedImage.TYPE_INT_RGB); initialized = false; INSTANCE = new SwingWindow(this, defaultWidth, defaultHeight); setResizable(WarpPI.getPlatform().getSettings().isDebugEnabled()); INSTANCE.setVisible(true); initialized = true; if (onInitialized != null) onInitialized.run(); } @Override public EventSubmitter onResize() { return INSTANCE.onResize(); } @Override public int getWidth() { return this.getSize()[0]; } @Override public int getHeight() { return this.getSize()[1]; } @Override public void destroy() { sendPowerOffSignal(); } protected void destroyEngine() { initialized = false; } @Override public void start(final RenderingLoop d) { INSTANCE.setRenderingLoop(d); final Thread th = new Thread(() -> { try { double extratime = 0; while (initialized) { final long start = System.nanoTime(); repaint(); final long end = System.nanoTime(); final double delta = end - start; if (extratime + delta < 50 * 1000d * 1000d) { Thread.sleep((long) Math.floor(50d - (extratime + delta) / 1000d / 1000d)); extratime = 0; } else extratime += delta - 50d; } } catch (final InterruptedException e) { e.printStackTrace(); } }); th.setName("CPU rendering thread"); th.setDaemon(true); th.start(); } @Deprecated() public void refresh() { if (WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getScreen() == null || WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().error != null && WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().error.length() > 0 || WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getScreen() == null || WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getScreen().mustBeRefreshed()) { INSTANCE.c.paintImmediately(0, 0, getWidth(), getHeight()); } } @Override public void repaint() { INSTANCE.c.repaint(); } public void subscribeExit(Runnable subscriber) { INSTANCE.addWindowListener(new WindowListener() { @Override public void windowOpened(WindowEvent e) { } @Override public void windowClosing(WindowEvent e) { subscriber.run(); } @Override public void windowClosed(WindowEvent e) { } @Override public void windowIconified(WindowEvent e) { } @Override public void windowDeiconified(WindowEvent e) { } @Override public void windowActivated(WindowEvent e) { } @Override public void windowDeactivated(WindowEvent e) { } }); } public void sendPowerOffSignal() { INSTANCE.sendPowerOffSignal(); } public abstract class Startable { public Startable() { force = false; } public Startable(final boolean force) { this.force = force; } public boolean force = false; public abstract void run(); } @Override public int[] getSize() { return r.size.clone(); } @Override public boolean isInitialized() { return initialized; } @Override public SwingRenderer getRenderer() { return r; } @Override public BinaryFont loadFont(final String fontName) throws IOException { return new SwingFont(fontName); } @Override public BinaryFont loadFont(final String path, final String fontName) throws IOException { return new SwingFont(path, fontName); } @Override public Skin loadSkin(final String file) throws IOException { return new SwingSkin(file); } @Override public boolean isSupported() { if (StaticVars.startupArguments.isEngineForced() && StaticVars.startupArguments.isCPUEngineForced() == false) return false; return (GraphicsEnvironment.isHeadless()) == false; } @Override public boolean doesRefreshPauses() { return true; } public void setAlphaChanged(final boolean val) { INSTANCE.setAlphaChanged(val); } public void setShiftChanged(final boolean val) { INSTANCE.setShiftChanged(val); } public Insets getInsets() { return INSTANCE.getInsets(); } public void subscribeTouchDevice(MouseMotionListener mouseMotionListener, MouseListener mouseListener) { INSTANCE.c.addMouseListener(mouseListener); INSTANCE.c.addMouseMotionListener(mouseMotionListener); } }