/* * JAME 6.2.1 * http://jame.sourceforge.net * * Copyright 2001, 2016 Andrea Medeghini * * This file is part of JAME. * * JAME is an application for creating fractals and other graphics artifacts. * * JAME is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * JAME 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with JAME. If not, see <http://www.gnu.org/licenses/>. * */ package net.sf.jame.contextfree.extensions.image; import java.awt.Graphics2D; import java.util.HashMap; import java.util.Map; import net.sf.jame.contextfree.ContextFreeManager; import net.sf.jame.contextfree.ContextFreeRuntime; import net.sf.jame.contextfree.renderer.DefaultContextFreeRenderer; import net.sf.jame.contextfree.renderer.SimpleContextFreeRenderer; import net.sf.jame.core.util.IntegerVector2D; import net.sf.jame.core.util.Tile; import net.sf.jame.twister.image.extension.ImageExtensionRuntime; import net.sf.jame.twister.renderer.TwisterRenderer; import net.sf.jame.twister.renderer.TwisterRenderingHints; /** * @author Andrea Medeghini */ public class ContextFreeImageRuntime extends ImageExtensionRuntime<ContextFreeImageConfig> { // private static final Logger logger = Logger.getLogger(ContextFreeImageRuntime.class); private Map<Object, Object> hints = new HashMap<Object, Object>(); private ContextFreeRuntime contextFreeRuntime; private RendererStrategy rendererStrategy; private int lastStatus; private Tile tile; /** * @see net.sf.jame.core.extension.ConfigurableExtensionRuntime#configReloaded() */ @Override public void configReloaded() { contextFreeRuntime = new ContextFreeRuntime(getConfig().getContextFreeConfig()); if (rendererStrategy != null) { rendererStrategy.dispose(); rendererStrategy = null; } } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#startRenderer() */ @Override public void startRenderer() { if (rendererStrategy != null) { rendererStrategy.startRenderer(); } } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#abortRenderer() */ @Override public void abortRenderer() { if (rendererStrategy != null) { rendererStrategy.abortRenderer(); } } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#joinRenderer() */ @Override public void joinRenderer() throws InterruptedException { if (rendererStrategy != null) { rendererStrategy.joinRenderer(); } } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#getRenderingStatus() */ @Override public int getRenderingStatus() { if (rendererStrategy != null) { return rendererStrategy.getRenderingStatus(); } return 0; } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#isDynamic() */ @Override public boolean isDynamic() { if (rendererStrategy != null) { return rendererStrategy.isDynamic(); } return false; } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#prepareImage(boolean) */ @Override public void prepareImage(final boolean isDynamicRequired) { if (rendererStrategy != null) { rendererStrategy.prepareImage(isDynamicRequired); } } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#drawImage(java.awt.Graphics2D) */ @Override public void drawImage(final Graphics2D g2d) { if (rendererStrategy != null) { rendererStrategy.drawImage(g2d); } } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#drawImage(java.awt.Graphics2D, int, int) */ @Override public void drawImage(final Graphics2D g2d, final int x, final int y) { if (rendererStrategy != null) { rendererStrategy.drawImage(g2d, x, y); } } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#drawImage(java.awt.Graphics2D, int, int, int, int) */ @Override public void drawImage(final Graphics2D g2d, final int x, final int y, final int w, final int h) { if (rendererStrategy != null) { rendererStrategy.drawImage(g2d, x, y, w, h); } } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#getImageSize() */ @Override public IntegerVector2D getImageSize() { return tile.getImageSize(); } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#setTile(net.sf.jame.core.util.Tile) */ @Override public void setTile(final Tile tile) { if (this.tile != tile) { this.tile = tile; // if (hints.get(TwisterRenderingHints.KEY_TYPE) == TwisterRenderingHints.TYPE_OVERLAY || hints.get(TwisterRenderingHints.KEY_TYPE) == TwisterRenderingHints.TYPE_PREVIEW) { if (hints.get(TwisterRenderingHints.KEY_TYPE) == TwisterRenderingHints.TYPE_OVERLAY) { rendererStrategy = new OverlayRendererStrategy(tile); } else { rendererStrategy = new DefaultRendererStrategy(tile); } } } /** * @see net.sf.jame.twister.image.extension.ImageExtensionRuntime#setRenderingHints(java.util.Map) */ @Override public void setRenderingHints(final Map<Object, Object> hints) { this.hints = hints; } /** * @see net.sf.jame.core.extension.ExtensionRuntime#dispose() */ @Override public void dispose() { if (rendererStrategy != null) { rendererStrategy.dispose(); rendererStrategy = null; } if (contextFreeRuntime != null) { contextFreeRuntime.dispose(); contextFreeRuntime = null; } super.dispose(); } /** * @see net.sf.jame.core.config.RuntimeElement#isChanged() */ @Override public boolean isChanged() { boolean isChanged = (contextFreeRuntime != null) && (contextFreeRuntime.changeCount() > 0); final int status = (rendererStrategy != null) ? rendererStrategy.getRenderingStatus() : -1; isChanged |= (status == TwisterRenderer.STATUS_RENDERING) || (lastStatus == TwisterRenderer.STATUS_RENDERING); lastStatus = status; return super.isChanged() || isChanged; } private interface RendererStrategy { /** * */ public void dispose(); /** * @param isDynamicRequired */ public void prepareImage(boolean isDynamicRequired); /** * @param g2d */ public void drawImage(final Graphics2D g2d); /** * @param g2d * @param x * @param y */ public void drawImage(Graphics2D g2d, int x, int y); /** * @param g2d * @param x * @param y * @param w * @param h */ public void drawImage(Graphics2D g2d, int x, int y, int w, int h); /** * @return */ public int getRenderingStatus(); /** * */ public void startRenderer(); /** * */ public void abortRenderer(); /** * @throws InterruptedException */ public void joinRenderer() throws InterruptedException; /** * @return */ public boolean isDynamic(); } private class DefaultRendererStrategy implements RendererStrategy { private ContextFreeManager manager; private int dynamicCount = 0; private boolean dirty = true; /** * @param tile */ public DefaultRendererStrategy(final Tile tile) { if (hints.get(TwisterRenderingHints.KEY_QUALITY) == TwisterRenderingHints.QUALITY_REALTIME) { if (hints.get(TwisterRenderingHints.KEY_MEMORY) == TwisterRenderingHints.MEMORY_LOW) { manager = new ContextFreeManager(new DefaultContextFreeRenderer(Thread.MIN_PRIORITY + 2)); } else { manager = new ContextFreeManager(new DefaultContextFreeRenderer(Thread.MIN_PRIORITY + 2)); } } else { manager = new ContextFreeManager(new SimpleContextFreeRenderer(Thread.MIN_PRIORITY + 1)); } manager.setRenderingHints(hints); manager.setRuntime(contextFreeRuntime); loadConfig(); manager.setTile(tile); manager.start(); } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#startRenderer() */ public void startRenderer() { manager.startRenderer(); } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#abortRenderer() */ public void abortRenderer() { manager.abortRenderer(); } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#joinRenderer() */ public void joinRenderer() throws InterruptedException { manager.joinRenderer(); } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#getRenderingStatus() */ public int getRenderingStatus() { return manager.getRenderingStatus(); } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#drawImage(java.awt.Graphics2D) */ public void drawImage(final Graphics2D g2d) { if (tile != null) { manager.drawImage(g2d); if (dirty) { dirty = false; try { manager.joinRenderer(); manager.startRenderer(); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); } } } } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#drawImage(java.awt.Graphics2D, int, int) */ public void drawImage(final Graphics2D g2d, final int x, final int y) { if (tile != null) { manager.drawImage(g2d, x, y); if (dirty) { dirty = false; try { manager.joinRenderer(); manager.startRenderer(); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); } } } } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#drawImage(java.awt.Graphics2D, int, int, int, int) */ public void drawImage(final Graphics2D g2d, final int x, final int y, final int w, final int h) { if (tile != null) { manager.drawImage(g2d, x, y, w, h); if (dirty) { dirty = false; try { manager.joinRenderer(); manager.startRenderer(); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); } } } } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#prepareImage(boolean) */ public void prepareImage(final boolean isDynamicRequired) { if (isDynamicRequired) { boolean isChanged = contextFreeRuntime.isChanged(); isChanged |= contextFreeRuntime.isViewChanged(); if (isChanged) { dynamicCount = 0; dirty = true; } if (dynamicCount >= 1) { dirty = true; } if (dirty) { manager.abortRenderer(); loadConfig(); } } else { loadConfig(); } if (manager.isDynamic()) { dynamicCount += 1; } else { dynamicCount = 0; } } private void loadConfig() { manager.setView(getConfig().getContextFreeConfig().getView()); } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#dispose() */ public void dispose() { if (manager != null) { manager.stop(); manager.dispose(); manager = null; } } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#isDynamic() */ public boolean isDynamic() { return dynamicCount > 0; } } private class OverlayRendererStrategy implements RendererStrategy { /** * @param tile */ public OverlayRendererStrategy(final Tile tile) { } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#startRenderer() */ public void startRenderer() { } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#abortRenderer() */ public void abortRenderer() { } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#joinRenderer() */ public void joinRenderer() throws InterruptedException { } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#getRenderingStatus() */ public int getRenderingStatus() { return -1; } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#drawImage(java.awt.Graphics2D) */ public void drawImage(final Graphics2D g2d) { } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#drawImage(java.awt.Graphics2D, int, int) */ public void drawImage(final Graphics2D g2d, final int x, final int y) { } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#drawImage(java.awt.Graphics2D, int, int, int, int) */ public void drawImage(final Graphics2D g2d, final int x, final int y, final int w, final int h) { } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#prepareImage(boolean) */ public void prepareImage(final boolean isDynamicRequired) { contextFreeRuntime.isChanged(); } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#dispose() */ public void dispose() { } /** * @see net.sf.jame.ContextFreeImageRuntime.extensions.image.ContextFreeImageRuntime.RendererStrategy#isDynamic() */ public boolean isDynamic() { return false; } } }