net.sf.fmj.ejmf.toolkit.media
Class AbstractController

java.lang.Object
  extended by net.sf.fmj.ejmf.toolkit.media.AbstractClock
      extended by net.sf.fmj.ejmf.toolkit.media.AbstractController
All Implemented Interfaces:
Clock, Controller, Duration
Direct Known Subclasses:
AbstractPlayer

public abstract class AbstractController
extends AbstractClock
implements Controller

The AbstractController class provides a basic implementation of a javax.media.Controller. Subclasses should implement the following abstract "do" methods to transition their Controller:

Follow these rules when implementing these methods:

  1. Do not return until the state change is complete. Once the state change is complete, return ASAP.
  2. Do not call one another. They will be called in the correct order at the correct time.
  3. Do not set the current or target states. They are set automatically.
  4. Do not post any TransitionEvents. They are posted automatically.
  5. Do not call any of the Clock routines. They will be called automatically.
  6. Return true if successful. If unsuccessful, post an appropriate ControllerErrorEvent and return false.
  7. When the end of the media has been reached, call endOfMedia(). This will post an EndOfMediaEvent and set the appropriate states. Do not post an EndOfMediaEvent in any other way.

Other abstact methods that should be implemented are:

From the book: Essential JMF, Gordon, Talley (ISBN 0130801046). Used with permission.

Author:
Steve Talley
See Also:
AbstractPlayer

Field Summary
 
Fields inherited from interface javax.media.Controller
LATENCY_UNKNOWN, Prefetched, Prefetching, Realized, Realizing, Started, Unrealized
 
Fields inherited from interface javax.media.Clock
RESET
 
Fields inherited from interface javax.media.Duration
DURATION_UNBOUNDED, DURATION_UNKNOWN
 
Constructor Summary
AbstractController()
          Construct a AbstractController.
 
Method Summary
 void addControl(Control newControl)
          Add a Control to this Controller.
 void addControllerListener(ControllerListener listener)
          Specify a ControllerListener to which this Controller will send events.
 void blockUntilStart(Time t)
          For a given time-base start time, block until the AbstractController should be started.
 void close()
          Close the Controller.
 void deallocate()
          Deallocate Controller on current thread.
abstract  void doClose()
          Close the Controller.
abstract  boolean doDeallocate()
          Implement to deallocate the Controller.
abstract  boolean doPrefetch()
          Implement to prefetch the Controller.
abstract  boolean doRealize()
          Implement to realize the Controller.
abstract  void doSetMediaTime(Time t)
          Override to provide implementation-specific functionality.
abstract  float doSetRate(float rate)
          Override to provide implementation-specific functionality.
abstract  boolean doStop()
          Implement to stop the Controller.
abstract  boolean doSyncStart(Time t)
          Implement to start the Controller.
protected  void endOfMedia()
          Indicates to the framework that the end of media has been reached.
 Control getControl(java.lang.String forName)
          Get the Control that supports the class or interface specified.
 Control[] getControls()
          Get a list of the Control objects that this Controller supports.
 Time getDuration()
          Returns DURATION_UNKNOWN.
 Time getMediaTime()
          Calculates the current media time based on the current time-base time, the time-base start time, the media start time, and the rate.
 int getPreviousState()
          Get the previous state of this Controller.
 Time getStartLatency()
          Returns LATENCY_UNKNOWN.
 int getState()
          Get the current state of this Controller.
 int getTargetState()
          Get the target state of this Controller.
protected  ThreadQueue getThreadQueue()
          Gets the ThreadQueue object for this AbstractController.
 TimeBase getTimeBase()
          Get the TimeBase that this Controller is using.
protected  void postControllerClosedEvent()
          Post a ControllerClosedEvent to the Media Event Queue.
protected  void postControllerErrorEvent(java.lang.String msg)
          Post a ControllerClosedEvent to the Media Event Queue.
protected  void postDataStarvedEvent()
          Post a DataStarvedEvent to the Media Event Queue.
protected  void postDeallocateEvent()
          Post a DeallocateEvent to the Media Event Queue.
protected  void postEndOfMediaEvent()
          Post a EndOfMediaEvent to the Media Event Queue.
protected  void postEvent(ControllerEvent event)
          Post a ControllerEvent to the Media Event Queue
protected  void postPrefetchCompleteEvent()
          Post a PrefetchCompleteEvent to the Media Event Queue.
protected  void postRealizeCompleteEvent()
          Post a RealizeCompleteEvent to the Media Event Queue.
protected  void postRestartingEvent()
          Post a RestartingEvent to the Media Event Queue.
protected  void postStartEvent()
          Post a StartEvent to the Media Event Queue.
protected  void postStopAtTimeEvent()
          Post a StopAtTimeEvent to the Media Event Queue.
protected  void postStopByRequestEvent()
          Post a StopByRequestEvent to the Media Event Queue.
protected  void postStopEvent()
          Post a StopEvent to the Media Event Queue.
protected  void postTransitionEvent()
          Post a TransitionEvent to the Media Event Queue.
 void prefetch()
          Prefetch Controller on new thread.
 void realize()
          Realize Controller on new thread.
 void removeControl(Control oldControl)
          Remove a Control from this Controller.
 void removeControllerListener(ControllerListener listener)
          Remove the specified listener from this Controller's listener list.
 void setMediaTime(Time t)
          Sets the media time.
 float setRate(float rate)
          Set the temporal scale factor.
protected  void setState(int state)
          Set the current state of this Controller.
 void setStopTime(Time mediaStopTime)
          Sets the stop time for this AbstractController.
protected  void setTargetState(int state)
          Set the targetState state of this Controller.
 void setTimeBase(TimeBase timebase)
          Set the TimeBase for this Clock.
 void stop()
          Stop Controller on current thread and post a StopByRequestEvent.
protected  void stopAtTime()
          Stop Controller on current thread and post a StopAtTimeEvent.
protected  boolean stopController()
          Stop the controller.
protected  void stopInRestart()
          Stop Controller on current thread and post a RestartingEvent.
protected  void synchronousPrefetch()
          Realize the AbstractController synchronously.
protected  void synchronousRealize()
          Realize the AbstractController synchronously.
protected  void synchronousSyncStart(Time t)
          SyncStart the AbstractController synchronously at the previously-specified time-base start time.
 void syncStart(Time t)
          SyncStart Controller on new thread.
 
Methods inherited from class net.sf.fmj.ejmf.toolkit.media.AbstractClock
getMediaNanoseconds, getMediaStartTime, getRate, getStopTime, getSyncTime, getTimeBaseStartTime, mapToTimeBase
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface javax.media.Clock
getMediaNanoseconds, getRate, getStopTime, getSyncTime, mapToTimeBase
 

Constructor Detail

AbstractController

public AbstractController()
Construct a AbstractController.

Method Detail

doRealize

public abstract boolean doRealize()
Implement to realize the Controller.

This method should not be called directly. Instead, call realize().

Returns:
True if successful, false otherwise.

doPrefetch

public abstract boolean doPrefetch()
Implement to prefetch the Controller.

This method should not be called directly. Instead, call prefetch().

Returns:
True if successful, false otherwise.

doSyncStart

public abstract boolean doSyncStart(Time t)
Implement to start the Controller.

This method should not be called directly. Instead, call syncStart().

Returns:
True if successful, false otherwise.

doDeallocate

public abstract boolean doDeallocate()
Implement to deallocate the Controller.

This method should not be called directly. Instead, call prefetch().

Returns:
True if successful, false otherwise.

doStop

public abstract boolean doStop()
Implement to stop the Controller.

This method should not be called directly. Instead, call stop().

Returns:
True if successful, false otherwise.

doClose

public abstract void doClose()
Close the Controller. Typically this method will release as many resources as possible, especially those that may be needed by other Controllers.

This method should not be called directly. Instead, call close().


doSetMediaTime

public abstract void doSetMediaTime(Time t)
Override to provide implementation-specific functionality. When this method is called, it is guaranteed that the Controller is Stopped and that the given time is within the Controller's duration.

This method should not be called directly. Instead, call setMediaTime().

Parameters:
t - The media time to set

doSetRate

public abstract float doSetRate(float rate)
Override to provide implementation-specific functionality. When this method is called, it is guaranteed that the Controller is Stopped.

This method should not be called directly. Instead, call setRate().

Parameters:
rate - The requested rate to set
Returns:
The actual rate that was set

setTimeBase

public void setTimeBase(TimeBase timebase)
                 throws IncompatibleTimeBaseException
Set the TimeBase for this Clock. This method can only be called on a Stopped Clock. A ClockStartedError is thrown if setTimeBase is called on a Started Clock.

A Clock has a default TimeBase that is determined by the implementation. To reset a Clock to its default TimeBase, call setTimeBase(null).

Specified by:
setTimeBase in interface Clock
Overrides:
setTimeBase in class AbstractClock
Parameters:
timebase - The new TimeBase or null to reset the Clock to its default TimeBase.
Throws:
IncompatibleTimeBaseException - Thrown if the Clock can't use the specified TimeBase.

getTimeBase

public TimeBase getTimeBase()
Get the TimeBase that this Controller is using.

Specified by:
getTimeBase in interface Clock
Overrides:
getTimeBase in class AbstractClock

setStopTime

public void setStopTime(Time mediaStopTime)
Sets the stop time for this AbstractController. Posts a StopTimeChangeEvent if the stop time given is different than the current stop time.

Specified by:
setStopTime in interface Clock
Overrides:
setStopTime in class AbstractClock
Parameters:
mediaStopTime - The time at which you want the Clock to stop, in media time.
Throws:
NotRealizedError - If the Controller is not Realized.
ClockStartedError - If the Controller is Started.

setMediaTime

public void setMediaTime(Time t)
Sets the media time.

Specified by:
setMediaTime in interface Clock
Overrides:
setMediaTime in class AbstractClock
Parameters:
t - The media time to set
Throws:
NotRealizedError - If the Controller is not Realized.
ClockStartedError - If the Controller is Started.

getMediaTime

public Time getMediaTime()
Calculates the current media time based on the current time-base time, the time-base start time, the media start time, and the rate.

Specified by:
getMediaTime in interface Clock
Overrides:
getMediaTime in class AbstractClock
Returns:
The current media time

setRate

public float setRate(float rate)
Set the temporal scale factor. The argument suggests the scale factor to use.

The setRate method returns the actual rate set by the Clock. Clocks should set their rate as close to the requested value as possible, but are not required to set the rate to the exact value of any argument other than 1.0. A Clock is only guaranteed to set its rate exactly to 1.0.

Specified by:
setRate in interface Clock
Overrides:
setRate in class AbstractClock
Parameters:
rate - The temporal scale factor (rate) to set.
Returns:
The actual rate set.
Throws:
NotRealizedError - If the Controller is not Realized.
ClockStartedError - If the Controller is Started.

getDuration

public Time getDuration()
Returns DURATION_UNKNOWN. This method should be overridden to report a more precise duration.

Specified by:
getDuration in interface Duration

realize

public final void realize()
Realize Controller on new thread. Subclasses should override doRealize() to do the actual work to transition the Controller.

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.

Asynchronous method -- Start synchronous transition on another thread and return ASAP.

Specified by:
realize in interface Controller

prefetch

public final void prefetch()
Prefetch Controller on new thread. Subclasses should override doPrefetch() to do the actual work to transition the Controller.

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.

Asynchronous method -- Start synchronous transition on another thread and return ASAP.

Specified by:
prefetch in interface Controller

syncStart

public final void syncStart(Time t)
SyncStart Controller on new thread. Subclasses should override doSyncStart() to do the actual work to transition the Controller.

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.

Asynchronous method -- Start synchronous transition on another thread and return ASAP.

Specified by:
syncStart in interface Clock
Overrides:
syncStart in class AbstractClock

deallocate

public final void deallocate()
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.

Synchronous method -- return when transition complete

Specified by:
deallocate in interface Controller

stop

public final void stop()
Stop Controller on current thread and post a StopByRequestEvent. Subclasses should override doStop() to do the actual work to stop the Controller.

Specified by:
stop in interface Clock
Overrides:
stop in class AbstractClock

stopAtTime

protected void stopAtTime()
Stop Controller on current thread and post a StopAtTimeEvent. Subclasses should override doStop() to do the actual work to stop the Controller.

This method is usually only called (indirectly) by the StopTimeMonitor class.

Synchronous method -- return when transition complete


stopInRestart

protected void stopInRestart()
Stop Controller on current thread and post a RestartingEvent. Subclasses should override doStop() to do the actual work to stop the Controller.

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.

Synchronous method -- return when transition complete


stopController

protected boolean stopController()
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.

Synchronous method -- return when transition complete

Returns:
boolean indicating whether the stop was successful.

close

public final void close()
Close the Controller. Release resources held by this Controller. Subclasses should implement doClose() to add additional functionality.

Specified by:
close in interface Controller

addControl

public void addControl(Control newControl)
Add a Control to this Controller.

Parameters:
newControl - The Control to add.

removeControl

public void removeControl(Control oldControl)
Remove a Control from this Controller.

Parameters:
oldControl - The Control to remove.

getControls

public Control[] getControls()
Get a list of the Control objects that this Controller supports. If there are no controls, an array of length zero is returned.

Specified by:
getControls in interface Controller
Returns:
A list of Controller Controls.

getControl

public Control getControl(java.lang.String forName)
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.

Specified by:
getControl in interface Controller
Returns:
Control for the given class or interface name, or null if no such Control is supported.

addControllerListener

public void addControllerListener(ControllerListener listener)
Specify a ControllerListener to which this Controller will send events.

Specified by:
addControllerListener in interface Controller
Parameters:
listener - The listener to which the Controller will post events.

removeControllerListener

public void removeControllerListener(ControllerListener listener)
Remove the specified listener from this Controller's listener list.

Specified by:
removeControllerListener in interface Controller
Parameters:
listener - The listener that has been receiving events from this Controller.

getPreviousState

public int getPreviousState()
Get the previous state of this Controller.


setState

protected void setState(int state)
Set the current state of this Controller. This will implicitly set the previous state as well.


getState

public int getState()
Get the current state of this Controller.

Specified by:
getState in interface Controller

setTargetState

protected void setTargetState(int state)
Set the targetState state of this Controller.


getTargetState

public int getTargetState()
Get the target state of this Controller.

Specified by:
getTargetState in interface Controller

endOfMedia

protected void endOfMedia()
                   throws ClockStoppedException
Indicates to the framework that the end of media has been reached. Marks the media time, sets the current and target states to Prefetched, and posts an EndOfMediaEvent.

Throws:
ClockStoppedException - If the AbstractController is not in the Started state.

postEvent

protected void postEvent(ControllerEvent event)
Post a ControllerEvent to the Media Event Queue

Parameters:
event - The ControllerEvent to post.

postTransitionEvent

protected void postTransitionEvent()
Post a TransitionEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, and Target State properties of the TransitionEvent.


postRealizeCompleteEvent

protected void postRealizeCompleteEvent()
Post a RealizeCompleteEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, and Target State properties of the RealizeCompleteEvent.


postPrefetchCompleteEvent

protected void postPrefetchCompleteEvent()
Post a PrefetchCompleteEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, and Target State properties of the PrefetchCompleteEvent.


postDeallocateEvent

protected void postDeallocateEvent()
Post a DeallocateEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, Target State, and Media Time properties of the DeallocateEvent.


postStopEvent

protected void postStopEvent()
Post a StopEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, Target State, and Media Time properties of the StopEvent.


postStopAtTimeEvent

protected void postStopAtTimeEvent()
Post a StopAtTimeEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, Target State, and Media Time properties of the StopAtTimeEvent.


postStartEvent

protected void postStartEvent()
Post a StartEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, Target State, Media Time, and Time-base Time properties of the StartEvent.


postDataStarvedEvent

protected void postDataStarvedEvent()
Post a DataStarvedEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, Target State, and Media Time properties of the DataStarvedEvent.


postEndOfMediaEvent

protected void postEndOfMediaEvent()
Post a EndOfMediaEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, Target State, and Media Time properties of the EndOfMediaEvent.


postRestartingEvent

protected void postRestartingEvent()
Post a RestartingEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, Target State, and Media Time properties of the RestartingEvent.


postStopByRequestEvent

protected void postStopByRequestEvent()
Post a StopByRequestEvent to the Media Event Queue. Automatically fill in the Previous State, Current State, Target State, and Media Time properties of the StopByRequestEvent.


postControllerClosedEvent

protected void postControllerClosedEvent()
Post a ControllerClosedEvent to the Media Event Queue.


postControllerErrorEvent

protected void postControllerErrorEvent(java.lang.String msg)
Post a ControllerClosedEvent to the Media Event Queue.


getThreadQueue

protected ThreadQueue getThreadQueue()
Gets the ThreadQueue object for this AbstractController.


synchronousRealize

protected void synchronousRealize()
Realize the AbstractController synchronously.

This method should not be called directly. Instead, call realize().

Synchronous method -- return when transition complete


synchronousPrefetch

protected void synchronousPrefetch()
Realize the AbstractController synchronously.

This method should not be called directly. Instead, call prefetch().

Synchronous method -- return when transition complete


getStartLatency

public Time getStartLatency()
Returns LATENCY_UNKNOWN. This method should be overridden to report a more precise start latency.

Specified by:
getStartLatency in interface Controller

synchronousSyncStart

protected void synchronousSyncStart(Time t)
SyncStart the AbstractController synchronously at the previously-specified time-base start time.

This method should not be called directly. Instead, call syncStart().

Synchronous method -- return when transition complete


blockUntilStart

public void blockUntilStart(Time t)
For a given time-base start time, block until the AbstractController should be started. For a given time- base start time (t), this method will get the AbstractController's start latency (l) and block until (t - l). This method is useful for implementations of doSyncStart().

If the time-base time (t - l) has already passed, return immediately.