javauis/m2g_qt/javasrc/com/nokia/microedition/m2g/M2GSVGAnimator.java
changeset 80 d6dafc5d983f
child 87 1627c337e51e
equal deleted inserted replaced
78:71ad690e91f5 80:d6dafc5d983f
       
     1 /*
       
     2 * Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 package com.nokia.microedition.m2g;
       
    19 
       
    20 import javax.microedition.m2g.*;
       
    21 import java.util.*;
       
    22 import javax.microedition.lcdui.*;
       
    23 import javax.microedition.lcdui.game.GameCanvas;
       
    24 import java.lang.ref.WeakReference;
       
    25 import com.nokia.mj.impl.rt.support.Finalizer;
       
    26 import com.nokia.mj.impl.utils.Logger;
       
    27 
       
    28 
       
    29 public class M2GSVGAnimator extends SVGAnimator 
       
    30 {
       
    31     //--------------------------------------------------
       
    32     // STATIC CONSTANTS
       
    33     //--------------------------------------------------
       
    34     private static final String ANIMATOR_CANVAS_BASE_CLASS =
       
    35         "javax.microedition.lcdui.Canvas";
       
    36     // Exception text
       
    37     /* Optimization: static finals changed to local variables
       
    38     private static final String COMPONENT_BASE_CLASS_NOT_SUPPORTED_ESTR =
       
    39     "The requested componentBaseClass is not supported by the implementation.";
       
    40     private static final String ILLEGAL_TIME_INCREMENT_ESTR =
       
    41     "The timeIncrement is less than or equal to zero.";
       
    42     private static final String ANIMATOR_PLAY_ESTR =
       
    43     "The animator is not currently in the stopped or paused state.";
       
    44     private static final String ANIMATOR_PAUSE_ESTR =
       
    45     "The animator is not in the playing  state.";
       
    46     private static final String ANIMATOR_STOP_ESTR =
       
    47     "The animator is not in the playing or paused state.";
       
    48     private static final String INVALID_RUNNABLE_ESTR =
       
    49     "The runnable is null.";
       
    50     private static final String ANIMATOR_IS_STOPPED_ESTR =
       
    51     "The animator is in the stopped state.";
       
    52     private static final String RUNNABLE_IS_NULL_ESTR =
       
    53     "The runnable is null.";
       
    54     private static final String ANIMATOR_INVOKE_ESTR =
       
    55     "The animator is in the stopped state.";
       
    56     */
       
    57 
       
    58     //--------------------------------------------------
       
    59     // VARIABLES
       
    60     //--------------------------------------------------
       
    61     private M2GSVGCanvas    iSVGCanvas      = null;
       
    62     private Finalizer mFinalizer;
       
    63 
       
    64     //--------------------------------------------------
       
    65     // METHODS
       
    66     //--------------------------------------------------
       
    67     /**
       
    68      * Constructor
       
    69      * @param aImage
       
    70      */
       
    71     protected M2GSVGAnimator(SVGImage aImage)
       
    72     {
       
    73 				
       
    74         iSVGCanvas = new M2GSVGCanvas(false, aImage);
       
    75         mFinalizer = new Finalizer()
       
    76         {	
       
    77             public void finalizeImpl()
       
    78             {
       
    79             		
       
    80                 doFinalize();
       
    81             }
       
    82         };
       
    83 				
       
    84     }
       
    85 
       
    86     /**
       
    87      * @see javax.microedition.m2g.SVGAnimator#getTargetComponent()
       
    88      */
       
    89     public Object getTargetComponent()
       
    90     {
       
    91         return iSVGCanvas;
       
    92     }
       
    93 
       
    94     /**
       
    95     * @see javax.microedition.m2g.SVGAnimator#getTimeIncrement()
       
    96     */
       
    97     public float getTimeIncrement()
       
    98     {
       
    99         return iSVGCanvas.getTimeIncrement();
       
   100     }
       
   101 
       
   102     /**
       
   103     * @see javax.microedition.m2g.SVGAnimator#invokeAndWait()
       
   104     */
       
   105     public void invokeAndWait(java.lang.Runnable runnable)
       
   106     {
       
   107         if (runnable == null)
       
   108         {
       
   109             throw new NullPointerException(
       
   110                 /*SF*/"The runnable is null."/*SF*/);
       
   111         }
       
   112         if (iSVGCanvas.isStopped())
       
   113         {
       
   114             throw new IllegalStateException(
       
   115                 /*SF*/"The animator is in the stopped state."/*SF*/);
       
   116         }
       
   117         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "invokeAndWait()");
       
   118         runnable.run();
       
   119     }
       
   120 
       
   121     /**
       
   122      * @see javax.microedition.m2g.SVGAnimator#invokeLater()
       
   123      */
       
   124     public void invokeLater(java.lang.Runnable runnable)
       
   125     {
       
   126         if (runnable == null)
       
   127         {
       
   128             throw new NullPointerException(
       
   129                 /*SF*/"The runnable is null."/*SF*/);
       
   130         }
       
   131         if (iSVGCanvas.isStopped())
       
   132         {
       
   133             throw new IllegalStateException(
       
   134                 /*SF*/"The animator is in the stopped state."/*SF*/);
       
   135         }
       
   136         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "invokeLater()");
       
   137         Thread thread = new Thread(runnable);
       
   138         thread.start();
       
   139     }
       
   140 
       
   141     /**
       
   142      * @see javax.microedition.m2g.SVGAnimator#pause()
       
   143      */
       
   144     public void pause()
       
   145     {
       
   146         if (!iSVGCanvas.isPlaying())
       
   147         {
       
   148             throw new IllegalStateException(
       
   149                 /*SF*/"The animator is not in the playing or paused state."/*SF*/);
       
   150         }
       
   151         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "pause()");
       
   152         iSVGCanvas.pause();
       
   153     }
       
   154 
       
   155     /**
       
   156     * @see javax.microedition.m2g.SVGAnimator#play()
       
   157     */
       
   158     public void play()
       
   159     {
       
   160 				
       
   161         if (iSVGCanvas.isPlaying())
       
   162         {
       
   163             throw new IllegalStateException(
       
   164                 /*SF*/"The animator is not currently in the stopped or paused state."/*SF*/);
       
   165         }
       
   166         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "play()");
       
   167         
       
   168         iSVGCanvas.play();
       
   169     }
       
   170 
       
   171     private void doFinalize()
       
   172     {
       
   173         if (mFinalizer != null)
       
   174         {
       
   175 						
       
   176             registeredFinalize();
       
   177             mFinalizer = null;
       
   178         }
       
   179     }
       
   180 
       
   181     /**
       
   182      * Finalize
       
   183      */
       
   184     synchronized void registeredFinalize()
       
   185     {
       
   186         iSVGCanvas.cancel();
       
   187         iSVGCanvas = null;
       
   188     }
       
   189 
       
   190 
       
   191     /**
       
   192      * @see javax.microedition.m2g.SVGAnimator#setSVGEventListener()
       
   193      */
       
   194     public void setSVGEventListener(SVGEventListener svgEventListener)
       
   195     {
       
   196         iSVGCanvas.setEventListener(svgEventListener);
       
   197     }
       
   198 
       
   199     /**
       
   200      * @see javax.microedition.m2g.SVGAnimator#setTimeIncrement()
       
   201      */
       
   202     public void setTimeIncrement(float timeIncrement)
       
   203     {
       
   204     		
       
   205         if (timeIncrement <= 0)
       
   206         {
       
   207             throw new IllegalArgumentException(
       
   208                 /*SF*/"The time increment is less than or equal to zero."/*SF*/);
       
   209         }
       
   210         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "setTimeIncrement() - "
       
   211                    + timeIncrement);
       
   212         iSVGCanvas.setTimeIncrement(timeIncrement);
       
   213         
       
   214     }
       
   215 
       
   216     /**
       
   217      * @see javax.microedition.m2g.SVGAnimator#stop()
       
   218      */
       
   219     public void stop()
       
   220     {
       
   221     		
       
   222         if (iSVGCanvas.isStopped())
       
   223         {
       
   224             throw new IllegalStateException(
       
   225                 /*SF*/"The animator is not in the playing or paused state."/*SF*/);
       
   226         }
       
   227         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "stop()");
       
   228 
       
   229         iSVGCanvas.stop();
       
   230         
       
   231     }
       
   232 
       
   233     //--------------------------------------------------
       
   234     // STATIC METHODS
       
   235     //--------------------------------------------------
       
   236     /**
       
   237      * Builds animator
       
   238      * @param svgImage -
       
   239      * @return SVGAnimator
       
   240      * @see javax.microedition.m2g.SVGAnimator#createAnimator()
       
   241      */
       
   242     public static SVGAnimator buildAnimator(SVGImage svgImage)
       
   243     {
       
   244 	   		
       
   245         if (svgImage == null)
       
   246         {
       
   247         		
       
   248             throw new NullPointerException();
       
   249         }
       
   250         
       
   251         return new M2GSVGAnimator(svgImage);
       
   252     }
       
   253 
       
   254     /**
       
   255      * Builds animator
       
   256      * @param svgImage -
       
   257      * @param componentBaseClass -
       
   258      * @return SVGAnimator
       
   259      * @see javax.microedition.m2g.SVGAnimator#createAnimator()
       
   260      */
       
   261     public static SVGAnimator buildAnimator(
       
   262         SVGImage svgImage, String componentBaseClass)
       
   263     {
       
   264         if (svgImage == null)
       
   265         {
       
   266             throw new NullPointerException();
       
   267         }
       
   268         if ((componentBaseClass != null) &&
       
   269                 (!componentBaseClass.equals(ANIMATOR_CANVAS_BASE_CLASS)))
       
   270         {
       
   271             throw new IllegalArgumentException(
       
   272                 /*SF*/"The requested componentBaseClass is not supported by the implementation."/*SF*/);
       
   273         }
       
   274         return buildAnimator(svgImage);
       
   275     }
       
   276 }
       
   277 
       
   278 //--------------------------------------------------
       
   279 // OTHER CLASSES
       
   280 //--------------------------------------------------
       
   281 
       
   282 /**
       
   283  * Canvas
       
   284  */
       
   285 class M2GSVGCanvas extends GameCanvas implements M2GDOMChangeObserver
       
   286 {
       
   287     //--------------------------------------------------
       
   288     // STATIC CONSTANTS
       
   289     //--------------------------------------------------
       
   290     public static final int STATE_STOPPED = 1;
       
   291     public static final int STATE_PLAYING = 2;
       
   292     public static final int STATE_PAUSED  = 3;
       
   293     public static final float DEFAULT_DELTA_TIME = 0.1f;  // (10fps) - defined by specs
       
   294 
       
   295     //--------------------------------------------------
       
   296     // VARIABLES
       
   297     //--------------------------------------------------
       
   298     private int                 iState;
       
   299     private SVGImage            iSVGImage;
       
   300     private ScalableGraphics    iSg;
       
   301     private Graphics            iOffscreen      = null;
       
   302     private M2GSVGSVGElement    iRootElement    = null;
       
   303 
       
   304     private float               iDeltaTime;
       
   305     private Timer               iTimer          = null;
       
   306     private SVGCanvasTask       iTask           = null;
       
   307 
       
   308     private SVGEventListener    iEventListener  = null;
       
   309 
       
   310     /**
       
   311      * True if the GameCanvas is in background or false otherwise
       
   312      */
       
   313     private boolean iWasPlaying                 = false;
       
   314 
       
   315     //--------------------------------------------------
       
   316     // METHODS
       
   317     //--------------------------------------------------
       
   318     /**
       
   319      * @see javax.microedition.lcdui.game.GameCanvas#GameCanvas()
       
   320      */
       
   321     public M2GSVGCanvas(boolean aSuppressKeyEvents, SVGImage aSVGImage)
       
   322     {					
       
   323 
       
   324         super(aSuppressKeyEvents);
       
   325 				
       
   326         // get the instance to the Graphics of the offscreen buffer
       
   327         iOffscreen = getGraphics();
       
   328 
       
   329         iSVGImage     = aSVGImage;
       
   330 
       
   331         // down-casting to M2GDocument/M2GSVGSVGElement to have access to internal methods
       
   332         M2GDocument doc = (M2GDocument)iSVGImage.getDocument();
       
   333         iRootElement  = (M2GSVGSVGElement)iSVGImage.getDocument().getDocumentElement();
       
   334         
       
   335 				
       
   336         iState = STATE_STOPPED;
       
   337         // Create render context
       
   338         iSg = ScalableGraphics.createInstance();
       
   339         iSg.setRenderingQuality(ScalableGraphics.RENDERING_QUALITY_HIGH);
       
   340         iDeltaTime = DEFAULT_DELTA_TIME;
       
   341 
       
   342         doc.registerDOMChangeObserver(this);
       
   343         
       
   344         
       
   345         
       
   346         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "Ctor - delta time:"
       
   347                    + iDeltaTime + ", state:" + iState);
       
   348     }
       
   349 
       
   350     /**
       
   351      * Handles any change in DOM.
       
   352      * <br>
       
   353      * While in PAUSE state, SVGAnimator must repaint any changes in SVGImage
       
   354      * done via the API (e.g. setTrait(), insertBefore())
       
   355      * <br>
       
   356      * @see M2GDOMChangeObserver.notifyDOMChange()
       
   357      * @since S60 3.2
       
   358      */
       
   359     public void notifyDOMChange()
       
   360     {
       
   361         if (isPaused())
       
   362         {
       
   363             repaint();
       
   364         }
       
   365     }
       
   366 
       
   367     /**
       
   368      * Cancel a timed task
       
   369      */
       
   370     public void cancel()
       
   371     {
       
   372         if (iTimer != null)
       
   373         {
       
   374             iTimer.cancel();
       
   375         }
       
   376         if (iTask != null)
       
   377         {
       
   378             iTask.cancel();
       
   379         }
       
   380         iTask = null;
       
   381         iTimer = null;
       
   382     }
       
   383 
       
   384     /**
       
   385      * Returns event listener
       
   386      * @return event listener
       
   387      */
       
   388     public synchronized SVGEventListener getEventListener()
       
   389     {
       
   390         return iEventListener;
       
   391     }
       
   392 
       
   393     /**
       
   394      * @see javax.microedition.m2g.SVGAnimator#getTimeIncrement()
       
   395      */
       
   396     public synchronized float getTimeIncrement()
       
   397     {
       
   398         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "getTimeIncrement() - "
       
   399                    + iDeltaTime);
       
   400         return iDeltaTime;
       
   401     }
       
   402 
       
   403     /**
       
   404      * Increases the increment time of the SVGImage.
       
   405      * Increment is done only if the playing state is active.
       
   406      * @see javax.microedition.m2g.SVGImage#incrementTime()
       
   407      */
       
   408     public synchronized void increaseCurrentTime(float time)
       
   409     {
       
   410         if (iState == STATE_PLAYING)
       
   411         {
       
   412             // update the time only in java side
       
   413             // the time in engine side is updated during rendering
       
   414             iRootElement.incrementTimeNoUpdate(time);
       
   415         }
       
   416     }
       
   417 
       
   418     /**
       
   419     * Checks if playing
       
   420     * @return true if playing
       
   421     */
       
   422     public synchronized boolean isPlaying()
       
   423     {
       
   424         return iState == STATE_PLAYING;
       
   425     }
       
   426 
       
   427     /**
       
   428      * Checks if paused
       
   429      * @return true if paused
       
   430      */
       
   431     public synchronized boolean isPaused()
       
   432     {
       
   433         return iState == STATE_PAUSED;
       
   434     }
       
   435 
       
   436     /**
       
   437      * Checks if stopped
       
   438      * @return true if stopped
       
   439      */
       
   440     public synchronized boolean isStopped()
       
   441     {
       
   442         return iState == STATE_STOPPED;
       
   443     }
       
   444 
       
   445     /**
       
   446      * @see javax.microedition.lcdui.Canvas#keyPressed()
       
   447      */
       
   448     protected synchronized void keyPressed(int keyCode)
       
   449     {
       
   450         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "keyPressed() - " + keyCode);
       
   451         if (iEventListener != null)
       
   452         {
       
   453             iEventListener.keyPressed(keyCode);
       
   454         }
       
   455     }
       
   456 
       
   457     /**
       
   458      * @see javax.microedition.lcdui.Canvas#keyReleased()
       
   459      */
       
   460     protected synchronized void keyReleased(int keyCode)
       
   461     {
       
   462         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "keyReleased() - " + keyCode);
       
   463         if (iEventListener != null)
       
   464         {
       
   465             iEventListener.keyReleased(keyCode);
       
   466         }
       
   467     }
       
   468 
       
   469     /**
       
   470      * @see javax.microedition.lcdui.Canvas#pointerPressed()
       
   471      * @see javax.microedition.m2g.SVGEventListener#pointerPressed()
       
   472      */
       
   473     protected synchronized void pointerPressed(int x, int y)
       
   474     {
       
   475         Logger.LOG(Logger.EJavaUI, Logger.EInfo,
       
   476                    "pointerPressed() - x:" + x + ", y:" + y);
       
   477         if (iEventListener != null)
       
   478         {
       
   479             iEventListener.pointerPressed(x, y);
       
   480         }
       
   481     }
       
   482 
       
   483     /**
       
   484      * @see javax.microedition.lcdui.Canvas#pointerReleased()
       
   485      * @see javax.microedition.m2g.SVGEventListener#pointerReleased()
       
   486      */
       
   487     protected synchronized void pointerReleased(int x, int y)
       
   488     {
       
   489         Logger.LOG(Logger.EJavaUI, Logger.EInfo,
       
   490                    "pointerReleased() - x:" + x + ", y:" + y);
       
   491         if (iEventListener != null)
       
   492         {
       
   493             iEventListener.pointerReleased(x, y);
       
   494         }
       
   495     }
       
   496 
       
   497     /**
       
   498      * @see javax.microedition.lcdui.game.GameCanvas#paint()
       
   499      */
       
   500     public void paint(Graphics g)
       
   501     {
       
   502         // Clears bitmap
       
   503         
       
   504         g.setColor(255, 255, 255);
       
   505         g.fillRect(0, 0, getWidth(), getHeight());
       
   506 
       
   507         try
       
   508         {
       
   509         		
       
   510             iSg.bindTarget(g);
       
   511 
       
   512 						
       
   513             // NOTE: Source is defaultly fully opaque
       
   514             iSg.render(0, 0, iSVGImage);
       
   515             
       
   516         }
       
   517         finally
       
   518         {
       
   519         		
       
   520             iSg.releaseTarget();
       
   521             
       
   522         }
       
   523     }
       
   524 
       
   525     /**
       
   526      * Paints a frame to the offscreen of this GameCanvas
       
   527      * @note GameCanvas.getGraphics() is not used since it always creates a new instance of Graphics
       
   528      */
       
   529     public void paintToOffscreen()
       
   530     {
       
   531         paint(iOffscreen);
       
   532     }
       
   533 
       
   534     /**
       
   535      * @see javax.microedition.m2g.SVGAnimator#setSVGEventListener()
       
   536      */
       
   537     public synchronized void setEventListener(SVGEventListener eventListener)
       
   538     {
       
   539         iEventListener = eventListener;
       
   540     }
       
   541 
       
   542     /**
       
   543      * @see javax.microedition.m2g.SVGAnimator#setTimeIncrement()
       
   544      */
       
   545     public synchronized void setTimeIncrement(float aDeltaTime)
       
   546     {
       
   547         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "setTimeIncrement() - "
       
   548                    + aDeltaTime);
       
   549 
       
   550         iDeltaTime = aDeltaTime;
       
   551     }
       
   552 
       
   553 
       
   554     /**
       
   555      * @see javax.microedition.lcdui.Canvas#showNotify()
       
   556      * @see javax.microedition.m2g.SVGEventListener#showNotify()
       
   557      */
       
   558     protected synchronized void showNotify()
       
   559     {
       
   560         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "showNotify()");
       
   561 
       
   562         if (iEventListener != null)
       
   563         {
       
   564             iEventListener.showNotify();
       
   565         }
       
   566 
       
   567         // A common use-case could be that the developer plays the animation by themselves
       
   568         // in SVGEventListener.showNotify().
       
   569         // Therefore we play the animation only if the developer didn't resume it already.
       
   570         if (iWasPlaying)
       
   571         {
       
   572             iWasPlaying = false;
       
   573             play();
       
   574         }
       
   575     }
       
   576 
       
   577     /**
       
   578      * @see javax.microedition.lcdui.Canvas#hideNotify()
       
   579      * @see javax.microedition.m2g.SVGEventListener#hideNotify()
       
   580      */
       
   581     protected synchronized void hideNotify()
       
   582     {
       
   583         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "hideNotify()");
       
   584 
       
   585         if (iEventListener != null)
       
   586         {
       
   587             iEventListener.hideNotify();
       
   588         }
       
   589 
       
   590         // A common use-case could be that developer pause the animation by themselves
       
   591         // in SVGEventListener.hideNotify().
       
   592         // Therefore we pause the animation only if the developer didn't pause it already.
       
   593         if (isPlaying())
       
   594         {
       
   595             pause();
       
   596             iWasPlaying = true;
       
   597         }
       
   598     }
       
   599 
       
   600 
       
   601     /**
       
   602      * @see javax.microedition.lcdui.Canvas#sizeChanged()
       
   603      * @see javax.microedition.m2g.SVGEventListener#sizeChanged()
       
   604      */
       
   605     protected synchronized void sizeChanged(int w, int h)
       
   606     {
       
   607         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "sizeChanged() - w:"
       
   608                    + w + ", h:" + h);
       
   609 
       
   610         // get a new instance of offscreen Graphics since the Graphics object
       
   611         // does not update its size or clipping area.
       
   612         // If not updating this, the GameCanvas is clipped when it is switched
       
   613         // to full-screen
       
   614         if (iOffscreen != null)
       
   615         {
       
   616             // sizeChanged() is called twice when the Canvas is set as Displayable.
       
   617             // If we try to get the Graphics object (first time), the Graphics object is not
       
   618             // fully initialized, so GameCanvas.getGraphics() will throw a NullPointerException
       
   619             iOffscreen = getGraphics();
       
   620         }
       
   621 
       
   622         if (iSVGImage != null)
       
   623         {
       
   624             iSVGImage.setViewportWidth(w);
       
   625             iSVGImage.setViewportHeight(h);
       
   626         }
       
   627 
       
   628         if (iEventListener != null)
       
   629         {
       
   630             iEventListener.sizeChanged(w, h);
       
   631         }
       
   632     }
       
   633 
       
   634     /**
       
   635      * @see javax.microedition.m2g.SVGAnimator#play()
       
   636      */
       
   637     public synchronized void play()
       
   638     {
       
   639         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "play()");
       
   640 				
       
   641         if (iState == STATE_PLAYING)
       
   642         {
       
   643             // don't do anything if animation is already playing
       
   644             return;
       
   645         }
       
   646 
       
   647         if ((iState == STATE_PAUSED)||(iState == STATE_STOPPED))
       
   648         {
       
   649             iTask = new SVGCanvasTask(this);
       
   650             iTimer = new Timer();
       
   651         }
       
   652         iState = STATE_PLAYING;
       
   653         if (iTimer != null && iTask != null)
       
   654         {
       
   655 
       
   656             iTimer.schedule(iTask,0,(long)(iDeltaTime*1000.0f));
       
   657 
       
   658         }
       
   659     }
       
   660 
       
   661     /**
       
   662      * @see javax.microedition.m2g.SVGAnimator#pause()
       
   663      */
       
   664     public synchronized void pause()
       
   665     {
       
   666         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "pause()");
       
   667 
       
   668         if (iState == STATE_PLAYING)
       
   669         {
       
   670             iTask.cancel();
       
   671             iTask = null;
       
   672             iTimer.cancel();
       
   673             iTimer = null;
       
   674         }
       
   675         iState = STATE_PAUSED;
       
   676 
       
   677     }
       
   678 
       
   679     /**
       
   680      * @see javax.microedition.m2g.SVGAnimator#stop()
       
   681      */
       
   682     public synchronized void stop()
       
   683     {
       
   684         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "stop()");
       
   685         if (iState == STATE_PLAYING)
       
   686         {
       
   687             iTask.cancel();
       
   688             iTask = null;
       
   689             iTimer.cancel();
       
   690             iTimer = null;
       
   691         }
       
   692         iState = STATE_STOPPED;
       
   693     }
       
   694 }
       
   695 
       
   696 /**
       
   697  * Timer task for rendering frames
       
   698  */
       
   699 class SVGCanvasTask extends TimerTask
       
   700 {
       
   701     //--------------------------------------------------
       
   702     // VARIABLES
       
   703     //--------------------------------------------------
       
   704     // private WeakReference   iWeakCanvas;
       
   705 
       
   706     private M2GSVGCanvas    iCanvas                 = null;
       
   707     private long           iPrevTime        = 0;
       
   708 
       
   709     //--------------------------------------------------
       
   710     // METHODS
       
   711     //--------------------------------------------------
       
   712     /**
       
   713      * Constructor
       
   714      * @param aCanvas SVG canvas
       
   715      */
       
   716     public SVGCanvasTask(M2GSVGCanvas aCanvas)
       
   717     {
       
   718         // iWeakCanvas = new WeakReference(aCanvas);
       
   719         // iCanvas = (M2GSVGCanvas)iWeakCanvas.get();
       
   720 
       
   721         iCanvas = aCanvas;
       
   722         iPrevTime = System.currentTimeMillis();
       
   723     }
       
   724     /**
       
   725         * Updates the animation time and generates frames which get flushed to the screen
       
   726         * <br>
       
   727         * * @note The timing for the next frame is decided upon the max(iDeltaTime*1000, elapsedTime)
       
   728           * iDeltaTime:  FrameTime set by client.
       
   729           * elapsedTime: Actual Time taken for rendering
       
   730               the  max(iDeltaTime*1000, elapsedTime) will be incremented on the SVGElement
       
   731         * @note rendering will be done only in PLAY state.
       
   732         * @note While in PAUSE state, SVGAnimator will repaint any changes done
       
   733         * to SVGImage via <code>M2GDOMChangeObserver.notifyDOMChange()</code>
       
   734         */
       
   735     public void run()
       
   736     {
       
   737         Logger.LOG(Logger.EJavaUI, Logger.EInfo,
       
   738                    "SVGCanvasTask: run() - begin");
       
   739 
       
   740         if (iCanvas == null)
       
   741         {
       
   742             return;
       
   743         }
       
   744 
       
   745         try
       
   746         {
       
   747             synchronized (iCanvas)
       
   748             {
       
   749                 long elapsedTime = System.currentTimeMillis()- iPrevTime;
       
   750                 if (elapsedTime > 0)
       
   751                     iCanvas.increaseCurrentTime((float)(elapsedTime/ 1000.));
       
   752                 iPrevTime = System.currentTimeMillis();
       
   753                 iCanvas.paintToOffscreen();
       
   754                 iCanvas.flushGraphics();
       
   755             }
       
   756         }
       
   757         catch (Exception e)
       
   758         {
       
   759             Logger.ELOG(Logger.EJavaUI,
       
   760                         "SVGCanvasTask: run() - exception: " + e.toString());
       
   761         }
       
   762         Logger.LOG(Logger.EJavaUI, Logger.EInfo, "SVGCanvasTask: run() - end");
       
   763 
       
   764     }
       
   765 }