|
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 } |