PageRenderTime 55ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/flash/0.2/fr/minuit4/debug/FPS.as

http://minuit4.googlecode.com/
ActionScript | 542 lines | 388 code | 100 blank | 54 comment | 15 complexity | cfab148c313d8216a0fb66748a12a94e MD5 | raw file
  1. /**
  2. * Written by :
  3. * @author Floz - Florian Zumbrunn
  4. * www.floz.fr || www.minuit4.fr
  5. *
  6. * Version log :
  7. *
  8. * 05.09.10 2.01 Arno + Bouton pour le garbage collector
  9. * 11.07.10 2.0 Floz + Réecriture complčte
  10. * + Suppression des events ACTIVATE et DEACTIVATE
  11. * + Changement de technique pour calculer les FPS (męme technique que celui de MrDoob)
  12. * 19.04.10 1.1 David Ronai + Ajout des bouttons + et - pour gérer le framerate
  13. * 11.07.09 1.0 Floz + Correction de quelques morceaux de codes.
  14. * + Ajout d'une valeur "moyenne" des fps.
  15. * + Ajout d'une courbe représentative de la moyenne des fps.
  16. * 07.05.09 0.5 Floz + Ajout d'un parametre dans le constructeur pour rendre partiellement visible l'outil
  17. * 24.03.09 0.4 Floz + Courbe supplémentaire pour les millisecondes
  18. * 08.03.09 0.3 Floz + Possibilité de déplacer le composant, et de cacher/afficher le graphique.
  19. * 08.03.09 0.2 Floz + Refonte pour ajout d'un graphique de performances
  20. * 28.08.08 0.1 Floz + Premičre version
  21. */
  22. package fr.minuit4.debug
  23. {
  24. import flash.display.Bitmap;
  25. import flash.display.BitmapData;
  26. import flash.display.Graphics;
  27. import flash.display.PixelSnapping;
  28. import flash.display.Shape;
  29. import flash.display.Sprite;
  30. import flash.events.Event;
  31. import flash.events.MouseEvent;
  32. import flash.events.TimerEvent;
  33. import flash.geom.Rectangle;
  34. import flash.system.System;
  35. import flash.text.TextField;
  36. import flash.text.TextFieldAutoSize;
  37. import flash.text.TextFormat;
  38. import flash.utils.getTimer;
  39. import flash.utils.Timer;
  40. public class FPS extends Sprite
  41. {
  42. // - PRIVATE VARIABLES -----------------------------------------------------------
  43. private const MEM_MAX:int = 500;
  44. private const MS_MAX:int = 200;
  45. private var _width:Number;
  46. private var _height:Number;
  47. private var _expand:Boolean;
  48. private var _scroll:int;
  49. private var _cntTitle:Sprite;
  50. private var _cntGraph:Sprite;
  51. private var _cntBts:Sprite;
  52. private var _btPlus:FPSButton;
  53. private var _btMinus:FPSButton;
  54. private var _btGC:FPSButton;
  55. private var _background:Shape;
  56. private var _curves:BitmapData;
  57. private var _rect:Rectangle;
  58. private var _timerChangeFPS:Timer;
  59. private var _prevFps:int;
  60. private var _prevMem:int;
  61. private var _prevMoy:int;
  62. private var _prevMs:int;
  63. private var _fps:int;
  64. private var _mem:int;
  65. private var _moy:int;
  66. private var _ms:int;
  67. private var _moyValue:int;
  68. private var _moyTick:int;
  69. private var _moyRefresh:int = 10;
  70. private var _cntTexts:Sprite;
  71. private var _tfFps:TextField;
  72. private var _tfMem:TextField;
  73. private var _tfMoy:TextField;
  74. private var _tfMs:TextField;
  75. private var _running:Boolean;
  76. private var _prevTime:int;
  77. private var _prevIntervalTime:int;
  78. private var _currentTime:int;
  79. private var _ticks:int;
  80. private var _diffFps:int;
  81. // - PUBLIC VARIABLES ------------------------------------------------------------
  82. // - CONSTRUCTOR -----------------------------------------------------------------
  83. /**
  84. * Instancie un nouvel objet FPS.
  85. * - FPS correspond au nombre d'image par secondes
  86. * - MEM correspond ŕ la mémoire physique utilisée par l'application (en mo)
  87. * - MS correspond au nombre de millisecondes écoulées entre deux ticks de ENTER_FRAME.
  88. * Chaque secondes, les paramčtres principaux seront mis ŕ jour.
  89. * @param width Number La largeur de l'outil.
  90. * @param height Number La hauteur de l'outil.
  91. * @param expand Boolean Fermé si false, ouvert si true.
  92. * @param scroll int Permet de définir combien de combien de pixels le graphisme sera décalé ŕ chaque seconde.
  93. */
  94. public function FPS( width:Number = 250, height:Number = 50, expand:Boolean = true, scroll:int = 2 )
  95. {
  96. _width = width;
  97. _height = height;
  98. _scroll = scroll;
  99. init();
  100. this.expand = expand;
  101. start();
  102. }
  103. // - EVENTS HANDLERS -------------------------------------------------------------
  104. private function mouseDownHandler(e:MouseEvent):void
  105. {
  106. stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true );
  107. startDrag();
  108. }
  109. private function mouseUpHandler(e:MouseEvent):void
  110. {
  111. stage.removeEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
  112. stopDrag();
  113. }
  114. private function btFpsDownHandler(e:MouseEvent):void
  115. {
  116. switch( e.currentTarget )
  117. {
  118. case _btPlus: _diffFps = 1; break;
  119. case _btMinus: _diffFps = -1; break;
  120. }
  121. onChangeFPS();
  122. stage.addEventListener( MouseEvent.MOUSE_UP, btFpsUpHandler, false, 0, true );
  123. _timerChangeFPS.addEventListener( TimerEvent.TIMER, timerHandler, false, 0, true );
  124. _timerChangeFPS.start();
  125. }
  126. private function timerHandler(e:TimerEvent):void
  127. {
  128. onChangeFPS();
  129. }
  130. private function btFpsUpHandler(e:MouseEvent):void
  131. {
  132. stage.removeEventListener( MouseEvent.MOUSE_UP, btFpsUpHandler );
  133. _timerChangeFPS.removeEventListener( TimerEvent.TIMER, timerHandler );
  134. _timerChangeFPS.stop();
  135. }
  136. private function doubleClickHandler(e:MouseEvent):void
  137. {
  138. expand = !expand;
  139. }
  140. private function enterFrameHandler(e:Event):void
  141. {
  142. _currentTime = getTimer();
  143. if ( _currentTime - 1000 > _prevIntervalTime )
  144. {
  145. _fps = ( _ticks / stage.frameRate ) * stage.frameRate;
  146. if ( _fps > stage.frameRate ) _fps = stage.frameRate;
  147. _moyValue += _fps;
  148. if ( ( ++_moyTick % _moyRefresh ) == 0 )
  149. {
  150. _moy = ( _moy + _moyValue ) / ( _moyRefresh + 1 );
  151. _moyValue = 0;
  152. }
  153. _mem = System.totalMemory / 1048576;
  154. if( _expand )
  155. updateCurves();
  156. _ticks = 0;
  157. _prevIntervalTime = _currentTime;
  158. }
  159. ++_ticks;
  160. _ms = int( _currentTime - _prevTime );
  161. _prevTime = _currentTime;
  162. updateTexts();
  163. }
  164. // - PRIVATE METHODS -------------------------------------------------------------
  165. private function init():void
  166. {
  167. initTitle();
  168. initGraph();
  169. initTexts();
  170. initBts();
  171. _rect = new Rectangle( _curves.width - _scroll, 0, _scroll, _curves.height );
  172. initListeners();
  173. }
  174. private function initTitle():void
  175. {
  176. _cntTitle = new Sprite();
  177. var g:Graphics = _cntTitle.graphics;
  178. g.beginFill( FPSColorEnum.BG_COLOR );
  179. g.drawRect( 0, 0, _width + 1, 20 );
  180. g.endFill();
  181. addChild( _cntTitle );
  182. _cntTitle.doubleClickEnabled =
  183. _cntTitle.buttonMode = true;
  184. }
  185. private function initGraph():void
  186. {
  187. _cntGraph = new Sprite();
  188. var g:Graphics = _cntGraph.graphics;
  189. g.lineStyle( 0, 0xe5e5e5 );
  190. g.beginFill( 0xffffff );
  191. g.drawRect( 0, 0, _width, _height );
  192. g.endFill();
  193. g.beginFill( 0xeeeeee );
  194. g.drawRect( 5, 5, _width - 10, _height - 10 );
  195. g.endFill();
  196. _cntGraph.y = _cntTitle.height;
  197. addChild( _cntGraph );
  198. _cntGraph.mouseEnabled =
  199. _cntGraph.mouseChildren = false;
  200. _curves = new BitmapData( _width - 11, _height - 11, false, 0xeeeeee );
  201. var b:Bitmap = new Bitmap( _curves, PixelSnapping.AUTO, false );
  202. b.x = 6;
  203. b.y = 6;
  204. _cntGraph.addChild( b );
  205. _prevFps =
  206. _prevMem =
  207. _prevMs = _curves.height;
  208. }
  209. private function initTexts():void
  210. {
  211. _cntTexts = new Sprite();
  212. _cntTexts.mouseChildren =
  213. _cntTexts.mouseEnabled = false;
  214. _cntTitle.addChild( _cntTexts );
  215. _tfFps = new TextField();
  216. _tfFps.x = 5;
  217. _tfFps.y = 2;
  218. formatText( _tfFps, FPSColorEnum.FPS );
  219. _tfFps.text = "FPS : ...";
  220. _tfMem = new TextField();
  221. _tfMem.x = 75;
  222. _tfMem.y = 2;
  223. formatText( _tfMem, FPSColorEnum.MEM );
  224. _tfMem.text = "MEM : ...";
  225. _tfMoy = new TextField();
  226. _tfMoy.x = 125;
  227. _tfMoy.y = 2;
  228. formatText( _tfMoy, FPSColorEnum.MOY );
  229. _tfMoy.text = "MS : ...";
  230. _tfMs = new TextField();
  231. _tfMs.x = _width - 50;
  232. _tfMs.y = 2;
  233. formatText( _tfMs, FPSColorEnum.MS );
  234. _tfMs.text = "MS : ...";
  235. }
  236. private function initBts():void
  237. {
  238. _cntBts = new Sprite();
  239. _cntBts.x = ( ( _cntTitle.x + _cntTitle.width ) >> 0 ) + 1;
  240. addChild( _cntBts );
  241. _btPlus = new FPSButton( "+" );
  242. _cntBts.addChild( _btPlus );
  243. _btMinus = new FPSButton( "-" );
  244. _btMinus.y = ( ( _btPlus.y + _btPlus.height ) >> 0 ) + 1;
  245. _cntBts.addChild( _btMinus );
  246. _btGC = new FPSButton("GC");
  247. _btGC.y = ( ( _btMinus.y + _btMinus.height ) >> 0 ) + 1;
  248. _cntBts.addChild(_btGC);
  249. }
  250. private function initListeners():void
  251. {
  252. _cntTitle.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true );
  253. _cntTitle.addEventListener( MouseEvent.DOUBLE_CLICK, doubleClickHandler, false, 0, true );
  254. _timerChangeFPS = new Timer( 100 );
  255. _btPlus.addEventListener( MouseEvent.MOUSE_DOWN, btFpsDownHandler, false, 0, true );
  256. _btMinus.addEventListener( MouseEvent.MOUSE_DOWN, btFpsDownHandler, false, 0, true );
  257. _btGC.addEventListener(MouseEvent.CLICK, btGCClickHandler, false, 0, true);
  258. }
  259. private function btGCClickHandler(e:MouseEvent):void
  260. {
  261. System.gc();
  262. drawLine(_curves.width - _scroll, 0,_curves.width - _scroll, _height, FPSColorEnum.GC);
  263. }
  264. private function onExpand():void
  265. {
  266. _cntGraph.visible = _expand;
  267. }
  268. private function updateCurves():void
  269. {
  270. _curves.lock();
  271. _curves.scroll( -_scroll, 0 );
  272. _curves.fillRect( _rect, 0xeeeeee );
  273. var nextFps:int = getNextVal( _fps, stage.frameRate );
  274. drawCurve( _prevFps, nextFps, FPSColorEnum.FPS );
  275. _prevFps = nextFps;
  276. var nextMem:int = getNextVal( _mem, MEM_MAX );
  277. drawCurve( _prevMem, nextMem, FPSColorEnum.MEM );
  278. _prevMem = nextMem;
  279. var nextMoy:int = getNextVal( _moy, stage.frameRate );
  280. drawCurve( _prevMoy, nextMoy, FPSColorEnum.MOY );
  281. _prevMoy = nextMoy;
  282. var nextMs:int = getNextVal( _ms, MS_MAX );
  283. drawCurve( _prevMs, nextMs, FPSColorEnum.MS );
  284. _prevMs = nextMs;
  285. _curves.unlock();
  286. }
  287. private function updateTexts():void
  288. {
  289. _tfFps.text = "FPS : " + _fps.toString() + " / " + int(stage.frameRate);
  290. _tfMem.text = "MEM : " + _mem.toString();
  291. _tfMoy.text = "MOY FPS : " + _moy.toString();
  292. _tfMs.text = "MS : " + _ms.toString();
  293. }
  294. private function formatText( tf:TextField, color:uint ):void
  295. {
  296. tf.autoSize = TextFieldAutoSize.LEFT;
  297. tf.textColor = color;
  298. tf.selectable = false;
  299. var format:TextFormat = new TextFormat( "_sans", 9 );
  300. tf.defaultTextFormat = format;
  301. _cntTexts.addChild( tf );
  302. }
  303. private function getNextVal( currentVal:int, maxVal:int ):int
  304. {
  305. var r:Number = currentVal / maxVal;
  306. if ( r > 1 ) r = 1;
  307. return int( ( 1 - r ) * ( _curves.height - 1 ) );
  308. }
  309. private function drawCurve( currentVal:int, newVal:int, color:uint ):void
  310. {
  311. drawLine( _curves.width - _scroll, currentVal, _curves.width - 1, newVal, color );
  312. }
  313. /**
  314. * Draw a pixel line !
  315. * @param x0 int Start point on the X axis.
  316. * @param y0 int Start point on the Y axis.
  317. * @param x1 int End point on the X axis.
  318. * @param y1 int End point on the Y axis.
  319. * @param c int Line's color.
  320. */
  321. private function drawLine( x0:int, y0:int, x1:int, y1:int, c:uint = 0xff000000 ):void
  322. {
  323. var dx:int = x1 - x0;
  324. var dy:int = y1 - y0;
  325. var xinc:int = ( dx > 0 ) ? 1 : -1;
  326. var yinc:int = ( dy > 0 ) ? 1 : -1;
  327. if ( dx < 0 ) dx = -dx;
  328. if ( dy < 0 ) dy = -dy;
  329. _curves.setPixel( x0, y0, c );
  330. var cumul:int, i:int;
  331. if ( dx > dy )
  332. {
  333. cumul = dx >> 1;
  334. for ( i = 1; i <= dx; ++i )
  335. {
  336. x0 += xinc;
  337. cumul += dy;
  338. if ( cumul >= dx )
  339. {
  340. y0 += yinc;
  341. cumul -= dx;
  342. }
  343. _curves.setPixel( x0, y0, c );
  344. }
  345. }
  346. else
  347. {
  348. cumul = dy >> 1;
  349. for ( i = 1; i <= dy; ++i )
  350. {
  351. y0 += yinc;
  352. cumul += dx;
  353. if ( cumul >= dy )
  354. {
  355. x0 += xinc;
  356. cumul -= dy;
  357. }
  358. _curves.setPixel( x0, y0, c );
  359. }
  360. }
  361. }
  362. private function onChangeFPS():void
  363. {
  364. stage.frameRate += _diffFps;
  365. }
  366. // - PUBLIC METHODS --------------------------------------------------------------
  367. /**
  368. * Permet de démarrer l'outil de suivi de performances.
  369. * Il se lance par défaut dčs l'ajout au stage.
  370. */
  371. public function start():void
  372. {
  373. if ( _running )
  374. return;
  375. _prevTime = getTimer();
  376. addEventListener( Event.ENTER_FRAME, enterFrameHandler, false, 0, true );
  377. _running = true;
  378. }
  379. /**
  380. * Permet de stopper l'outil de suivi de performances.
  381. */
  382. public function stop():void
  383. {
  384. if ( !_running )
  385. return;
  386. removeEventListener( Event.ENTER_FRAME, enterFrameHandler );
  387. _running = false;
  388. }
  389. // - GETTERS & SETTERS -----------------------------------------------------------
  390. public function get expand():Boolean { return _expand; }
  391. public function set expand(value:Boolean):void
  392. {
  393. _expand = value;
  394. onExpand();
  395. }
  396. public function get running():Boolean { return _running; }
  397. }
  398. }
  399. import flash.display.Graphics;
  400. import flash.display.Sprite;
  401. import flash.text.TextField;
  402. import flash.text.TextFieldAutoSize;
  403. import flash.text.TextFormat;
  404. final class FPSButton extends Sprite
  405. {
  406. private var _label:String;
  407. public function FPSButton( label:String ):void
  408. {
  409. _label = label;
  410. initBg();
  411. initText();
  412. this.mouseChildren = false;
  413. this.buttonMode = true;
  414. }
  415. private function initBg():void
  416. {
  417. var g:Graphics = this.graphics;
  418. g.beginFill( FPSColorEnum.BG_COLOR );
  419. g.drawRect( 0, 0, 20, 20 );
  420. g.endFill();
  421. }
  422. private function initText():void
  423. {
  424. var format:TextFormat = new TextFormat( "_sans", 9, 0xffffff );
  425. var tf:TextField = new TextField();
  426. tf.autoSize = TextFieldAutoSize.LEFT;
  427. tf.defaultTextFormat = format;
  428. tf.text = _label;
  429. tf.x = ( ( this.width - tf.width ) >> 1 ) + 1;
  430. tf.y = ( ( this.height - tf.height ) >> 1 );
  431. addChild( tf );
  432. }
  433. }
  434. final class FPSColorEnum
  435. {
  436. public static const FPS:uint = 0xff0000;
  437. public static const MEM:uint = 0x00ff00;
  438. public static const MOY:uint = 0xff6600;
  439. public static const MS:uint = 0x0099ff;
  440. public static const GC:uint = 0;
  441. public static const BG_COLOR:uint = 0x222222;
  442. }