📄 abstractcontroller.java
字号:
//////////////////////////////////////////////////////////// /** * Returns DURATION_UNKNOWN. This method should be * overridden to report a more precise duration. */ public Time getDuration() { return DURATION_UNKNOWN; } //////////////////////////////////////////////////////////// // // javax.media.Controller methods // //////////////////////////////////////////////////////////// /** * Realize Controller on new thread. Subclasses should * override doRealize() to do the actual work to transition * the Controller. * <p> * Checks for Controller state prerequisites and creates a * RealizeThread to realize the AbstractController. If there * is already a thread transitioning the AbstractController * forward, then the target state of the AbstractController is * set to Realized and the method returns. * <p> * Asynchronous method -- Start synchronous transition on * another thread and return ASAP. */ public final synchronized void realize() { // Has this state already been reached? if( currentState >= Realized ) { postRealizeCompleteEvent(); return; } // Set the target state if( targetState < Realized ) { setTargetState(Realized); } // Realize on a separate thread Thread thread = new Thread() { public void run() { if( AbstractController.this.getState() < Realized ) { synchronousRealize(); } } }; threadqueue.addThread(thread); } /** * Prefetch Controller on new thread. Subclasses should * override doPrefetch() to do the actual work to transition * the Controller. * <p> * Checks for Controller state prerequisites and creates a * PrefetchThread to prefetch the AbstractController. If there * is already a thread transitioning the AbstractController * forward, then the target state of the AbstractController is * set to Prefetched and the method returns. * <p> * Asynchronous method -- Start synchronous transition on * another thread and return ASAP. */ public final synchronized void prefetch() { // Has this state already been reached? if( currentState >= Prefetched ) { postPrefetchCompleteEvent(); return; } // Set the target state if( targetState < Prefetched ) { setTargetState(Prefetched); } // Prefetch on a separate thread Thread thread = new Thread() { public void run() { if( AbstractController.this.getState() < Prefetched ) { synchronousPrefetch(); } } }; threadqueue.addThread(thread); } /** * SyncStart Controller on new thread. Subclasses should * override doSyncStart() to do the actual work to transition the * Controller. * <p> * Checks for Controller state prerequisites and creates a * SyncStartThread to syncstart the AbstractController. The * target state of the AbstractController is then set to * Started and the thread is started. * <p> * Asynchronous method -- Start synchronous transition on * another thread and return ASAP. */ public final synchronized void syncStart(final Time t) { // Enforce state prereqs if (currentState == Started) { throw new ClockStartedError( "syncStart() cannot be called on a started Clock"); } // Enforce state prereqs if(currentState != Prefetched) { throw new NotPrefetchedError( "Cannot start the Controller before it has been prefetched"); } // Set the target state setTargetState(Started); // SyncStart on a separate thread Thread thread = new Thread() { public void run() { if( AbstractController.this.getState() < Started ) { synchronousSyncStart(t); } } }; threadqueue.addThread(thread); } /** * Deallocate Controller on current thread. Subclasses * should override doDeallocate() to do the actual work to * transition the Controller. After ensuring state * prerequisites, this method will call doDeallocate(). If * doDeallocate() returns true, then the Controller is placed * in the appropriate state and a DeallocateCompleteEvent is * posted. Otherwise, it is assumed that the controller has * posted a ControllerErrorEvent detailing the reasons for * it's failure. * <p> * Synchronous method -- return when transition complete */ public final synchronized void deallocate() { int state; // Enforce state prereq if( currentState == Started ) { throw new ClockStartedError( "deallocate() cannot be called on a started Controller"); } // Kill any forward-transitioning thread if (threadqueue != null) // may be already stopped an nulled by close() threadqueue.stopThreads(); // Do the actual deallocating. If this returns false, // the deallocate was unsuccessful. Rely on the Controller // to post the ControllerErrorEvent and return without // modifying the current or target states. if( doDeallocate() ) { // The deallocate was successful // Return to previous state as dictated by the spec if( currentState == Unrealized || currentState == Realizing ) { state = Unrealized; } else { state = Realized; } // Set current and target states and post event setState(state); setTargetState(state); postDeallocateEvent(); } } /** * Stop Controller on current thread and post a * StopByRequestEvent. Subclasses should override doStop() * to do the actual work to stop the Controller. */ public final void stop() { if( stopController() ) { postStopByRequestEvent(); } } /** * Stop Controller on current thread and post a * StopAtTimeEvent. Subclasses should override doStop() to * do the actual work to stop the Controller. * <p> * This method is usually only called (indirectly) by the * StopTimeMonitor class. * <p> * Synchronous method -- return when transition complete */ protected void stopAtTime() { if( stopController() ) { postStopAtTimeEvent(); } } /** * Stop Controller on current thread and post a * RestartingEvent. Subclasses should override doStop() to * do the actual work to stop the Controller. * <p> * This method is usually only called (indirectly) by * Player.setMediaTime() or Player.setRate() when a managed * Controller must be stopped before its media time and rate, * respectively, can be set. * <p> * Synchronous method -- return when transition complete */ protected void stopInRestart() { if( stopController() ) { postRestartingEvent(); } } /** * Stop the controller. If the Controller is Realizing or * Prefetching, then the target state will be set to Realized * or Prefetched, respectively, and the Controller will stop * when it completes the transition. If the Controller is * Started, this method will call doStop(). If doStop() * returns true, then the Controller is placed in the * Prefetched state and a StopEvent is posted. If doStop() * returns false, it is assumed that the controller has * posted a ControllerErrorEvent detailing the reasons for * it's failure. * <p> * Synchronous method -- return when transition complete * * @return boolean indicating whether the * stop was successful. */ protected synchronized boolean stopController() { // Kill any forward-transitioning threads. if (threadqueue != null) threadqueue.stopThreads(); switch(currentState) { // Stop any scheduled forward transitions case Unrealized: case Realized: case Prefetched: setTargetState(currentState); return true; // If the Controller was Realizing, return it to the // Unrealized state. case Realizing: setState(Unrealized); setTargetState(Unrealized); return true; // If the Controller was Prefetching, return it to // the Realized state. case Prefetching: setState(Realized); setTargetState(Realized); return true; } // If we are here, then the Controller is Started // Do the actual stopping. If this returns false, the // stop was unsuccessful. Rely on the Controller to post the // ControllerErrorEvent and return without modifying the // current or target states. if(! doStop() ) { return false; } // The stop was successful // Stop the Clock super.stop(); // Set state. The StopEvent will be posted by // one of the protected synchronous Stop methods setState(Prefetched); setTargetState(Prefetched); return true; } /** * Close the Controller. Release resources held by this * Controller. Subclasses should implement doClose() to * add additional functionality. */ public synchronized final void close() { // Stop the Controller in case it is Started stop(); // Call implementation-specific functionality doClose(); // Set some resources to null controls = null; threadqueue = null; // Post a ControllerClosedEvent postControllerClosedEvent(); } //////////////////////////////////////////////////////////// // // Control methods // //////////////////////////////////////////////////////////// /** * Add a Control to this Controller. * * @param newControl * The Control to add. */ public void addControl(Control newControl) { synchronized(controls) { if(! controls.contains(newControl) ) { controls.addElement(newControl); } } } /** * Remove a Control from this Controller. * * @param oldControl * The Control to remove. */ public void removeControl(Control oldControl) { controls.removeElement(oldControl); } /** * Get a list of the Control objects that this Controller * supports. If there are no controls, an array of length * zero is returned. * * @return A list of Controller Controls. * */ public Control[] getControls() { Control[] array; synchronized(controls) { array = new Control[ controls.size() ]; controls.copyInto(array); } return array; } /** * Get the Control that supports the class or interface * specified. The full class or interface name should be * specified. Null is returned if the Control is not * supported. * * @return Control for the given class or interface * name, or null if no such Control is supported. */ public Control getControl(String forName) { Class c; try { c = Class.forName(forName); } catch(Exception e) { return null; } synchronized(controls) { for(int i = 0, n = controls.size(); i < n; i++) { Control control = (Control)controls.elementAt(i); if( c.isInstance(control) ) { return control; } } } return null; } //////////////////////////////////////////////////////////// // // Listener methods // //////////////////////////////////////////////////////////// /** * Specify a ControllerListener to which this Controller will * send events. * * @param listener * The listener to which the Controller will post * events. */ public void addControllerListener(ControllerListener listener) { synchronized(listeners) { if(! listeners.contains(listener) ) { listeners.addElement(listener); } } } /** * Remove the specified listener from this Controller's * listener list. * * @param listener * The listener that has been receiving events * from this Controller. * */ public void removeControllerListener(ControllerListener listener) { synchronized(listeners) { listeners.removeElement(listener); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -