/* * Session.java * (FScape) * * Copyright (c) 2001-2016 Hanns Holger Rutz. All rights reserved. * * This software is published under the GNU General Public License v3+ * * * For further information, please contact Hanns Holger Rutz at * contact@sciss.de * * * Changelog: * 25-Jan-05 created * 15-Jul-05 removed SessionChangeListener stuff. relies more on SessionCollection.Listener * for doc.tracks * 21-Jan-06 implements OSCRouter ; moved a lot of actions from DocumentFrame to this class * 24-Jun-06 created from de.sciss.eisenkraut.session.Session */ package de.sciss.fscape.session; import de.sciss.common.ProcessingThread; import de.sciss.fscape.Application; import de.sciss.fscape.net.OSCRoot; import de.sciss.fscape.net.OSCRouter; import de.sciss.fscape.net.OSCRouterWrapper; import de.sciss.fscape.net.RoutedOSCMessage; import de.sciss.util.Flag; import javax.swing.undo.UndoManager; import java.awt.*; import java.io.File; public class Session implements OSCRouter { private ModulePanel frame = null; // --- --- private boolean dirty = false; private final Session enc_this = this; private static int nodeIDAlloc = 0; private final int nodeID; private final OSCRouterWrapper osc; private File file = null; private ProcessingThread currentPT = null; public Session() { nodeID = ++nodeIDAlloc; osc = new OSCRouterWrapper(null, this); } public int getNodeID() { return nodeID; } /** * Checks if a process is currently running. This method should be called * before launching a process using the <code>start()</code> method. * If a process is ongoing, this method waits for a default timeout period * for the thread to finish. * * @return <code>true</code> if a new process can be launched, <code>false</code> * if a previous process is ongoing and a new process cannot be launched * @throws IllegalMonitorStateException if called from outside the event thread * @synchronization must be called in the event thread */ public boolean checkProcess() { return checkProcess( 500 ); } /** * Checks if a process is currently running. This method should be called * before launching a process using the <code>start()</code> method. * If a process is ongoing, this method waits for a given timeout period * for the thread to finish. * * @param timeout the maximum duration in milliseconds to wait for an ongoing process * @return <code>true</code> if a new process can be launched, <code>false</code> * if a previous process is ongoing and a new process cannot be launched * @throws IllegalMonitorStateException if called from outside the event thread * @synchronization must be called in the event thread */ public boolean checkProcess( int timeout ) { //System.out.println( "checking..." ); if( !EventQueue.isDispatchThread() ) throw new IllegalMonitorStateException(); if( currentPT == null ) return true; if( timeout == 0 ) return false; //System.out.println( "sync " + timeout ); currentPT.sync( timeout ); //System.out.println( "sync done" ); return( (currentPT == null) || !currentPT.isRunning() ); } /** * Starts a <code>ProcessingThread</code>. Only one thread * can exist at a time. To ensure that no other thread is running, * call <code>checkProcess()</code>. * * @param process the thread to launch * @throws IllegalMonitorStateException if called from outside the event thread * @throws IllegalStateException if another process is still running * @see #checkProcess() * @synchronization must be called in the event thread */ public void start( ProcessingThread process ) { if( !EventQueue.isDispatchThread() ) throw new IllegalMonitorStateException(); if( this.currentPT != null ) throw new IllegalStateException( "Process already running" ); currentPT = process; currentPT.addListener( new ProcessingThread.Listener() { public void processStarted( ProcessingThread.Event e ) {} public void processStopped( ProcessingThread.Event e ) { currentPT = null; } }); currentPT.start(); } public ModulePanel getFrame() { return frame; } public void setFrame( ModulePanel frame ) { this.frame = frame; } public File getFile() { return file; } public void setFile( File f ) { file = f; } public String getName() { if (file != null) { String f = file.getName(); int i = f.lastIndexOf('.'); return i < 0 ? f : f.substring(0, i); } else { return getResourceString("Untitled"); } } private void updateTitle() { // if( frame != null ) frame.updateTitle(); } private String getResourceString( String key ) { return key; } public ProcessingThread closeDocument(boolean force, Flag wasClosed) { return frame.closeDocument(force, wasClosed); // XXX should be in here not frame!!! } // ------------- OSCRouter interface ------------- public String oscGetPathComponent() { return null; } public void oscRoute( RoutedOSCMessage rom ) { osc.oscRoute( rom ); } public void oscAddRouter( OSCRouter subRouter ) { if( osc != null ) osc.oscAddRouter( subRouter ); } public void oscRemoveRouter( OSCRouter subRouter ) { if( osc != null ) osc.oscRemoveRouter( subRouter ); } public void oscCmd_close(RoutedOSCMessage rom) { if (frame == null) { OSCRoot.failed(rom.msg, getResourceString("errWindowNotFound")); } final ProcessingThread pt; final boolean force; try { if (rom.msg.getArgCount() > 1) { force = ((Number) rom.msg.getArg(1)).intValue() != 0; } else { force = false; } pt = closeDocument(force, new Flag(false)); if (pt != null) { pt.start(); // pt.addListener(new ProcessingThread.Listener() { // @Override // public void processStarted(ProcessingThread.Event e) { // System.out.println("PROC STARTED"); // } // // @Override // public void processStopped(ProcessingThread.Event e) { // System.out.println("PROC STOPPED"); // } // }); } else { // System.out.println("WAS CLOSED"); } } catch (IndexOutOfBoundsException e1) { OSCRoot.failedArgCount(rom); } catch (ClassCastException e1) { OSCRoot.failedArgType(rom, 1); } } public void oscCmd_start(RoutedOSCMessage rom) { if (frame == null) { OSCRoot.failed(rom.msg, getResourceString("errWindowNotFound")); } frame.start(); } public void oscCmd_stop(RoutedOSCMessage rom) { if (frame == null) { OSCRoot.failed(rom.msg, getResourceString("errWindowNotFound")); } frame.stop(); } public void oscCmd_pause(RoutedOSCMessage rom) { if (frame == null) { OSCRoot.failed(rom.msg, getResourceString("errWindowNotFound")); } frame.pause(); } public void oscCmd_resume(RoutedOSCMessage rom) { if (frame == null) { OSCRoot.failed(rom.msg, getResourceString("errWindowNotFound")); } frame.resume(); } public void oscCmd_activate(RoutedOSCMessage rom) { if (frame == null) { OSCRoot.failed(rom.msg, getResourceString("errWindowNotFound")); } // frame.setVisible(true); Application.documentHandler.setActive(this); // frame.toFront(); // frame.requestFocus(); } public Object oscQuery_id() { return new Integer(getNodeID()); } public Object oscQuery_process() { if (frame == null) { return null; } final String className = frame.getClass().getName(); final int i = className.lastIndexOf('.'); final boolean dlg = className.endsWith("Dlg"); return className.substring(i + 1, className.length() - (dlg ? 3 : 0)); } public Object oscQuery_running() { if (frame == null) { return null; } return new Integer(frame.isThreadRunning() ? 1 : 0); } public Object oscQuery_progression() { if (frame == null) { return null; } return new Float(frame.getProgression()); } public Object oscQuery_error() { if (frame == null) { return null; } final Exception e = frame.getError(); return (e == null ? "" : e.getClass().getName() + " : " + e.getLocalizedMessage()); } public Object oscQuery_dirty() { return new Integer(isDirty() ? 1 : 0); } public Object oscQuery_name() { return getName(); // getDisplayDescr().file.getName(); } public Object oscQuery_file() { return (file == null ? "" : file.getAbsolutePath()); } // ---------------- Document interface ---------------- public UndoManager getUndoManager() { throw new IllegalStateException("Not implemented"); // return undo; } public void dispose() { // undo.discardAllEdits(); if( osc != null ) { osc.remove(); // osc = null; } // if( frame != null ) { //// frame.setVisible( false ); // frame.dispose(); // frame = null; // } } public boolean isDirty() { return dirty; } public void setDirty( boolean dirty ) { if( !this.dirty == dirty ) { this.dirty = dirty; updateTitle(); } } }