/* * Copyright (C) 2011 Michael Vogt <michu@neophob.com> * Copyright (C) 2012 Gyver * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package com.gyver.matrixmover; import com.gyver.matrixmover.core.Controller; import com.gyver.matrixmover.core.audio.AudioCaptureThread; import com.gyver.matrixmover.core.timer.AudioTimerTask; import com.gyver.matrixmover.core.timer.ExecutionTimerTask; import com.gyver.matrixmover.gui.DebugFrame; import com.gyver.matrixmover.gui.Frame; import com.gyver.matrixmover.output.ArtnetDevice; import com.gyver.matrixmover.output.NullDevice; import com.gyver.matrixmover.output.Output; import com.gyver.matrixmover.output.OutputDeviceEnum; import com.gyver.matrixmover.properties.PropertiesHelper; import com.gyver.matrixmover.splash.MMSplashScreen; import java.io.FileInputStream; import java.io.InputStream; import java.util.Properties; import java.util.Timer; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import net.sf.nimrod.NimRODLookAndFeel; import net.sf.nimrod.NimRODTheme; /** * Class MatrixMover starting the MatrixMover Programm. * * Code-parts copied from http://github.com/neophob/PixelController * * @author Gyver */ public class MatrixMover { /** The log. */ private static final Logger LOG = Logger.getLogger(MatrixMover.class.getName()); /** The Constant CONFIG_FILENAME. */ private static final String CONFIG_FILENAME = "data/config.properties"; /** The Constant LAF_THEME. */ private static final String LAF_THEME = "data/matrixmover.theme"; /** The output. */ private Output output; private static boolean guiReady = false; private static Frame guiFrame = null; private static Properties config = null; private static Timer fpsTimer = null; private static Timer audioTimer = null; private static Controller controller = null; /** * Prepare MatrixMover to start */ private void setup() { LOG.log(Level.INFO, "MatrixMover Setup START"); MMSplashScreen.initSplash(); MMSplashScreen.setProgress(10, "loading properties"); config = new Properties(); try { InputStream is = new FileInputStream(CONFIG_FILENAME); config.load(is); LOG.log(Level.INFO, "Config loaded, {0} entries", config.size()); } catch (Exception e) { LOG.log(Level.SEVERE, "Failed to load Config", e); throw new IllegalArgumentException("Configuration error!", e); } final PropertiesHelper ph = new PropertiesHelper(config); MMSplashScreen.setProgress(25, "setting up output device"); OutputDeviceEnum outputDeviceEnum = ph.getOutputDevice(); try { switch (outputDeviceEnum) { case NULL: this.output = new NullDevice(ph); break; case ARTNET: this.output = new ArtnetDevice(ph); break; default: throw new IllegalArgumentException(); } } catch (Exception e) { LOG.log(Level.SEVERE, "Unable to initialize output device: " + outputDeviceEnum + ". Using Null device instead.", e); this.output = new NullDevice(ph); } LOG.log(Level.INFO, "Starting Core"); MMSplashScreen.setProgress(35, "startomg programm core"); controller = Controller.getControllerInstance(); controller.initController(ph, output); LOG.log(Level.FINER, "Loading NimROD LAF"); MMSplashScreen.setProgress(50, "loading look and feel"); try { NimRODTheme nt = new NimRODTheme(LAF_THEME); NimRODLookAndFeel NimRODLF = new NimRODLookAndFeel(); NimRODLookAndFeel.setCurrentTheme(nt); UIManager.setLookAndFeel(NimRODLF); } catch (UnsupportedLookAndFeelException ex) { Logger.getLogger(MatrixMover.class.getName()).log(Level.SEVERE, null, ex); } LOG.log(Level.INFO, "Starting Gui"); MMSplashScreen.setProgress(60, "starting gui"); java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { guiFrame = Frame.getFrameInstance(); guiFrame.initFrame(ph, controller); guiFrame.setSize(1200, 800); guiFrame.setLocationRelativeTo(null); MatrixMover.guiReady(true); } }); //wait for gui to fully initialize while (!guiReady) { try { Thread.sleep(100); } catch (InterruptedException ex) { Logger.getLogger(MatrixMover.class.getName()).log(Level.SEVERE, null, ex); } } MMSplashScreen.setProgress(75, "controller post init"); controller.postInit(); // LOG.log(Level.INFO, "Trying to load scenes from scene file"); // MMSplashScreen.setProgress(80, "loading scenes"); // controller.loadScenes(); MMSplashScreen.setProgress(90, "starting timer"); LOG.log(Level.INFO, "Starting timer with {0} FPS", ph.getFps()); fpsTimer = new Timer(); audioTimer = new Timer(); long millisecondsDelay = 1000 / ph.getFps(); fpsTimer.scheduleAtFixedRate(new ExecutionTimerTask(controller), 1, millisecondsDelay); audioTimer.schedule(new AudioTimerTask(controller), 100, millisecondsDelay / 2); AudioCaptureThread act = new AudioCaptureThread(); Thread thread = new Thread(act); thread.start(); controller.setAudioCapture(act, thread); LOG.log(Level.INFO, "MatrixMover Setup END"); MMSplashScreen.setProgress(100, "done loading"); MMSplashScreen.close(); if (guiFrame != null) { guiFrame.setVisible(true); } } private static void guiReady(boolean ready) { MatrixMover.guiReady = ready; } /** * Main method lunching Matrixmover * @param args */ public static void main(String[] args) { // Set uncaught exception handler for controlled crashing Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { showCrashMessage(e); } }); MatrixMover matmove = new MatrixMover(); matmove.setup(); } /** * Shows an error massage to the user if MatrixMover has chrashed. * @param e the throwable to display the massage of */ private static void showCrashMessage(Throwable e) { //shut everything down! if (fpsTimer != null) { fpsTimer.cancel(); fpsTimer.purge(); fpsTimer = null; } if (audioTimer != null) { audioTimer.cancel(); audioTimer.purge(); audioTimer = null; } if (controller != null) { controller.shutDown(); controller = null; } if (guiFrame != null) { guiFrame.dispose(); guiFrame = null; } System.gc(); DebugFrame df = new DebugFrame(e); df.setSize(705, 405); df.setLocationRelativeTo(null); df.setVisible(true); } }