com.neophob.PixelController.java Source code

Java tutorial

Introduction

Here is the source code for com.neophob.PixelController.java

Source

/**
 * Copyright (C) 2011-2013 Michael Vogt <michu@neophob.com>
 *
 * This file is part of PixelController.
 *
 * PixelController 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.
 *
 * PixelController 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 PixelController.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.neophob;

import java.awt.event.WindowListener;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang3.StringUtils;

import processing.core.PApplet;

import com.neophob.sematrix.core.glue.Collector;
import com.neophob.sematrix.core.glue.FileUtils;
import com.neophob.sematrix.core.jmx.TimeMeasureItemGlobal;
import com.neophob.sematrix.core.output.ArduinoOutput;
import com.neophob.sematrix.core.output.Output;
import com.neophob.sematrix.core.properties.ApplicationConfigurationHelper;
import com.neophob.sematrix.core.properties.ConfigConstant;
import com.neophob.sematrix.core.setup.InitApplication;
import com.neophob.sematrix.gui.GeneratorGuiCreator;
import com.neophob.sematrix.gui.OutputGui;
import com.neophob.sematrix.gui.handler.KeyboardHandler;
import com.neophob.sematrix.gui.handler.WindowHandler;

/**
 * The Class PixelController.
 *
 * @author michu
 */
public class PixelController extends PApplet {

    /** The log. */
    private static final Logger LOG = Logger.getLogger(PixelController.class.getName());

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = -1336765543826338205L;

    /** The Constant FPS. */
    public static final int FPS = 25;

    /** setup gui constants */
    private static final int TEXT_Y_OFFSET = 140;
    private static final int TEXT_Y_HEIGHT = 15;

    private static final int SETUP_FONT_BIG = 20;
    private static final int SETUP_FONT_SMALL = 12;

    private static final int SETUP_WINDOW_WIDTH = 600;
    private static final int SETUP_WINDOW_HEIGHT = 500;

    private Collector collector;

    /** The output. */
    private Output output;

    private OutputGui matrixEmulator;

    /** more setup stuff */
    private boolean initialized = false;
    private boolean initializationFailed = false;

    private int setupStep = 0;
    private float steps = 1f / 7f;
    private ApplicationConfigurationHelper applicationConfig;
    private FileUtils fileUtils;

    /**
     * 
     * @param text
     * @param textYOffset
     */
    public void drawSetupText(String text, int textYOffset) {
        fill(240);
        textSize(SETUP_FONT_SMALL);
        text(text, 40, textYOffset);
    }

    /**
     * 
     * @param val
     */
    public void drawProgressBar(float val) {
        fill(64);
        rect(10, 40, 580, 50);

        if (val > 1.0) {
            val = 1.0f;
        }

        fill(227, 122, 182);
        rect(10, 40, 580 * val, 50);
    }

    /**
     * 
     */
    public void setup() {
        try {
            LOG.log(Level.INFO, "\n\nPixelController " + getVersion() + " - http://www.pixelinvaders.ch\n\n");

            size(SETUP_WINDOW_WIDTH, SETUP_WINDOW_HEIGHT);
            background(0);
            noStroke();

            //try to display the pixelcontroller logo
            String splashimg = "setup" + File.separatorChar + "splash.jpg";
            try {
                image(loadImage(splashimg), 0, 111);
            } catch (Exception e) {
                LOG.log(Level.INFO, "Failed to load splash logo (" + splashimg + ")", e);
            }

            //write pixelcontroller text
            textSize(SETUP_FONT_BIG);
            fill(227, 122, 182);
            text("PixelController " + getVersion(), 10, 29);

            text("Loading...", 10, 120);
            drawProgressBar(0.0f);
            drawSetupText("Load Configuration", TEXT_Y_OFFSET + TEXT_Y_HEIGHT * setupStep);
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Setup() call failed!", e);
        }
    }

    /**
     * Asynchronous initialize PixelController and display progress in GUI
     */
    public void asyncInitApplication() {
        try {

            switch (setupStep) {
            case 0:
                fileUtils = new FileUtils();
                applicationConfig = InitApplication.loadConfiguration(fileUtils);
                String rootPath = applicationConfig.getResourcePath();
                if (StringUtils.isEmpty(rootPath)) {
                    //use processing root path
                    rootPath = this.sketchPath;
                }

                setupStep++;
                drawProgressBar(steps);
                drawSetupText("Create Collector", TEXT_Y_OFFSET + TEXT_Y_HEIGHT * setupStep);
                return;

            case 1:
                this.collector = Collector.getInstance();
                setupStep++;
                drawProgressBar(steps * setupStep);
                drawSetupText("Initialize System", TEXT_Y_OFFSET + TEXT_Y_HEIGHT * setupStep);
                return;

            case 2:
                this.collector.init(fileUtils, applicationConfig);
                frameRate(applicationConfig.parseFps());
                noSmooth();
                setupStep++;
                drawProgressBar(steps * setupStep);
                drawSetupText("Initialize OSC Server", TEXT_Y_OFFSET + TEXT_Y_HEIGHT * setupStep);
                return;

            case 3:
                this.collector.initDaemons(applicationConfig);
                setupStep++;
                drawProgressBar(steps * setupStep);
                drawSetupText("Initialize Output device", TEXT_Y_OFFSET + TEXT_Y_HEIGHT * setupStep);
                return;

            case 4:
                this.output = InitApplication.getOutputDevice(this.collector, applicationConfig);
                if (this.output == null) {
                    throw new IllegalArgumentException("No output device found!");
                }
                this.collector.setOutput(output);
                setupStep++;
                drawProgressBar(steps * setupStep);
                drawSetupText("Apply Settings", TEXT_Y_OFFSET + TEXT_Y_HEIGHT * setupStep);
                return;

            case 5:
                InitApplication.setupInitialConfig(collector, applicationConfig);
                setupStep++;
                drawProgressBar(steps * setupStep);
                drawSetupText("Initialize GUI", TEXT_Y_OFFSET + TEXT_Y_HEIGHT * setupStep);
                return;

            case 6:
                this.matrixEmulator = new OutputGui(applicationConfig, this.output, this);

                //create gui window
                if (applicationConfig.getProperty(ConfigConstant.SHOW_DEBUG_WINDOW, "true")
                        .equalsIgnoreCase("true")) {
                    //create GUI Window
                    GeneratorGuiCreator ggc = new GeneratorGuiCreator(this,
                            applicationConfig.getDebugWindowMaximalXSize(),
                            applicationConfig.getDebugWindowMaximalYSize(), getVersion());
                    //register GUI Window in the Keyhandler class, needed to do some specific actions (select a visual...)
                    KeyboardHandler.setRegisterGuiClass(ggc.getGuiCallbackAction());
                }
                setupStep++;
                drawProgressBar(steps * setupStep);
                drawSetupText("Finished", TEXT_Y_OFFSET + TEXT_Y_HEIGHT * setupStep);

                try {
                    //now start a little hack, remove all window listeners, so we can control
                    //the closing behavior ourselves.
                    for (WindowListener wl : frame.getWindowListeners()) {
                        frame.removeWindowListener(wl);
                    }

                    //add our own window listener
                    frame.addWindowListener(new WindowHandler(this));
                } catch (Exception e) {
                    LOG.log(Level.INFO, "failed to remove/add window listeners", e);
                }
                return;

            default:
                break;
            }

            LOG.log(Level.INFO, "--- PixelController Setup END ---");
            LOG.log(Level.INFO, "---------------------------------");
            LOG.log(Level.INFO, "");

            background(0);
            initialized = true;

        } catch (Exception e) {
            LOG.log(Level.INFO, "Failed to init PixelController!", e);
            textSize(SETUP_FONT_BIG);
            fill(227, 122, 182);

            int errorYPos = 370;
            text("PixelController Error", 10, errorYPos);

            drawSetupText("Failed to initialize PixelController! See log/pixelcontroller.log for more detail!s",
                    errorYPos + 20);
            drawSetupText("Error message:", errorYPos + 40);
            drawSetupText("     " + e.getMessage(), errorYPos + 60);
            initializationFailed = true;
        }
    }

    /* (non-Javadoc)
     * @see processing.core.PApplet#draw()
     */
    public void draw() {

        if (initializationFailed) {
            throw new IllegalArgumentException("PixelController failed to start...");
        }

        if (!initialized) {
            asyncInitApplication();
            return;
        }

        if (Collector.getInstance().isInPauseMode()) {
            //no update here, we're in pause mode
            return;
        }

        // update all generators
        try {
            Collector.getInstance().updateSystem();
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Collector.getInstance().updateSystem() failed!", e);
        }

        //TODO calculate fps in pixelcontroller-core
        this.collector.getPixConStat().setCurrentFps(frameRate);

        // update matrixEmulator instance
        long startTime = System.currentTimeMillis();
        this.matrixEmulator.update();
        this.collector.getPixConStat().trackTime(TimeMeasureItemGlobal.MATRIX_EMULATOR_WINDOW,
                System.currentTimeMillis() - startTime);
        if (this.output != null && this.output.getClass().isAssignableFrom(ArduinoOutput.class)) {
            this.output.logStatistics();
        }
    }

    /**
     * register single keyboard handler
     */
    public void keyPressed() {
        if (keyCode == ESC) { //ignored
            key = 0;
        } else {
            KeyboardHandler.keyboardHandler(key, keyCode);
        }
    }

    /**
     * 
     * @return
     */
    public String getVersion() {
        String version = this.getClass().getPackage().getImplementationVersion();
        if (StringUtils.isNotBlank(version)) {
            return "v" + version;
        }
        return "Developer Snapshot";
    }

    /**
     * Is PixelController finished initializing?
     * 
     * @return
     */
    public boolean isInitialized() {
        return initialized;
    }

    /**
     * The main method.
     *
     * @param args the arguments
     */
    public static void main(String args[]) {
        PApplet.main(new String[] { PixelController.class.getName().toString() });
    }

}