diff --git a/README.md b/README.md
index 1d0dba9..1ffd1b1 100644
--- a/README.md
+++ b/README.md
@@ -3,55 +3,28 @@ stats.as
#### Actionscript Performance Monitor ####
-
+[](http://flattr.com/thing/20491/stats-as)
This class provides a simple info box that will help you monitor your code performance.
-* FPS Frames per second, how many frames were rendered in 1 second. The higher the number, the better.
-* MS Milliseconds needed to render a frame. The lower number, the better.
-* MEM Memory your code is using, if it increases per frame is VERY wrong.
-* MAX Maximum memory the application reached.
+* **FPS** Frames per second, how many frames were rendered in 1 second. The higher the number the better.
+* **MS** Milliseconds needed to render a frame. The lower the number the better.
+* **MEM** Memory your code is using, if it increases per frame is VERY wrong.
+* **MAX** Maximum memory the application reached.
+
+### Screenshot ###
-### How to use ###
+
+
+### Usage ###
addChild( new Stats() );
### Controls ###
-* **LEFT CLICK** on the top-half/bottom-half part of the panel to increase/decrease the movie FPS limit.
+* **CLICK** Top-half / bottom-half part of the panel to increase/decrease the FPS of the application.
### Download ###
-[Stats.as](http://github.com/mrdoob/stats.as/raw/master/src/net/hires/debug/Stats.as)
-
-### Change Log ###
-
-2009 10 22 - v**2.2**
-
-* FlipX of graph to be more logic.
-* Destroy on Event.REMOVED_FROM_STAGE (thx joshtynjala)
-
-
-2009 03 28 - v**2.1**
-
-* Theme support.
-
-
-2009 02 21 - v**2.0**
-
-* changed text system
-* added MAX value (Max memory reached). very useful for spotting memory leaks
-* removed player version on roll over (let me know if this is a bad idea)
-* simplified
-
-
-2009 02 07 - v**1.5**
-
-* onRemovedFromStage() (thx huihuicn.xu)
-
-
-2008 12 14 - v**1.4**
-
-* Code optimisations, should take even less CPU
-* Fixed ugly drawing when transparent (thx makc.the.great)
-* Added Version info on Mouse Over.
+[Stats.as](http://github.com/mrdoob/stats.as/raw/master/src/net/hires/debug/Stats.as)
+[Stats.hx](http://github.com/mrdoob/stats.as/raw/master/src/net/hires/debug/Stats.hx) (Ported by [David Wilhelm](http://github.com/bigfish))
diff --git a/assets/stats_as.png b/assets/stats_as.png
index a72cc09..5a91438 100644
Binary files a/assets/stats_as.png and b/assets/stats_as.png differ
diff --git a/src/net/hires/debug/Stats.as b/src/net/hires/debug/Stats.as
index 29c65ed..509a083 100644
--- a/src/net/hires/debug/Stats.as
+++ b/src/net/hires/debug/Stats.as
@@ -11,24 +11,24 @@
*
**/
-package net.hires.debug
-{
- import flash.display.Bitmap;
+package net.hires.debug {
+
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
+ import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.system.System;
import flash.text.StyleSheet;
import flash.text.TextField;
import flash.utils.getTimer;
- public class Stats extends Sprite
- {
+ public class Stats extends Sprite {
+
protected const WIDTH : uint = 70;
protected const HEIGHT : uint = 100;
-
+
protected var xml : XML;
protected var text : TextField;
@@ -40,42 +40,31 @@ package net.hires.debug
protected var ms_prev : uint;
protected var mem : Number;
protected var mem_max : Number;
-
- protected var graph : Bitmap;
+
+ protected var graph : BitmapData;
protected var rectangle : Rectangle;
-
+
protected var fps_graph : uint;
protected var mem_graph : uint;
protected var mem_max_graph : uint;
-
- protected var theme : Object = { bg: 0x000033, fps: 0xffff00, ms: 0x00ff00, mem: 0x00ffff, memmax: 0xff0070 };
+
+ protected var colors : Colors = new Colors();
/**
* Stats FPS, MS and MEM, all in one.
- *
- * @param _theme Example: { bg: 0x202020, fps: 0xC0C0C0, ms: 0x505050, mem: 0x707070, memmax: 0xA0A0A0 }
*/
- public function Stats( _theme : Object = null ) : void
- {
- if (_theme)
- {
- if (_theme.bg != null) theme.bg = _theme.bg;
- if (_theme.fps != null) theme.fps = _theme.fps;
- if (_theme.ms != null) theme.ms = _theme.ms;
- if (_theme.mem != null) theme.mem = _theme.mem;
- if (_theme.memmax != null) theme.memmax = _theme.memmax;
- }
+ public function Stats() : void {
mem_max = 0;
xml = FPS:MS:MEM:MAX:;
style = new StyleSheet();
- style.setStyle("xml", {fontSize:'9px', fontFamily:'_sans', leading:'-2px'});
- style.setStyle("fps", {color: hex2css(theme.fps)});
- style.setStyle("ms", {color: hex2css(theme.ms)});
- style.setStyle("mem", {color: hex2css(theme.mem)});
- style.setStyle("memMax", {color: hex2css(theme.memmax)});
+ style.setStyle('xml', {fontSize:'9px', fontFamily:'_sans', leading:'-2px'});
+ style.setStyle('fps', {color: hex2css(colors.fps)});
+ style.setStyle('ms', {color: hex2css(colors.ms)});
+ style.setStyle('mem', {color: hex2css(colors.mem)});
+ style.setStyle('memMax', {color: hex2css(colors.memmax)});
text = new TextField();
text.width = WIDTH;
@@ -85,70 +74,72 @@ package net.hires.debug
text.selectable = false;
text.mouseEnabled = false;
- graph = new Bitmap();
- graph.y = 50;
-
- rectangle = new Rectangle( WIDTH - 1, 0, 1, HEIGHT - 50 );
+ rectangle = new Rectangle(WIDTH - 1, 0, 1, HEIGHT - 50);
addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
addEventListener(Event.REMOVED_FROM_STAGE, destroy, false, 0, true);
+
}
- private function init(e : Event) : void
- {
- graphics.beginFill(theme.bg);
+ private function init(e : Event) : void {
+
+ graphics.beginFill(colors.bg);
graphics.drawRect(0, 0, WIDTH, HEIGHT);
graphics.endFill();
addChild(text);
- graph.bitmapData = new BitmapData(WIDTH, HEIGHT - 50, false, theme.bg);
- addChild(graph);
+ graph = new BitmapData(WIDTH, HEIGHT - 50, false, colors.bg);
+ graphics.beginBitmapFill(graph, new Matrix(1, 0, 0, 1, 0, 50));
+ graphics.drawRect(0, 50, WIDTH, HEIGHT - 50);
addEventListener(MouseEvent.CLICK, onClick);
addEventListener(Event.ENTER_FRAME, update);
+
}
-
- private function destroy(e : Event) : void
- {
+
+ private function destroy(e : Event) : void {
+
graphics.clear();
while(numChildren > 0)
removeChildAt(0);
- graph.bitmapData.dispose();
+ graph.dispose();
removeEventListener(MouseEvent.CLICK, onClick);
removeEventListener(Event.ENTER_FRAME, update);
- }
+
+ }
- private function update(e : Event) : void
- {
+ private function update(e : Event) : void {
+
timer = getTimer();
- if( timer - 1000 > ms_prev )
- {
+ if( timer - 1000 > ms_prev ) {
+
ms_prev = timer;
mem = Number((System.totalMemory * 0.000000954).toFixed(3));
mem_max = mem_max > mem ? mem_max : mem;
- fps_graph = Math.min( graph.height, ( fps / stage.frameRate ) * graph.height );
- mem_graph = Math.min( graph.height, Math.sqrt( Math.sqrt( mem * 5000 ) ) ) - 2;
- mem_max_graph = Math.min( graph.height, Math.sqrt( Math.sqrt( mem_max * 5000 ) ) ) - 2;
+ fps_graph = Math.min(graph.height, ( fps / stage.frameRate ) * graph.height);
+ mem_graph = Math.min(graph.height, Math.sqrt(Math.sqrt(mem * 5000))) - 2;
+ mem_max_graph = Math.min(graph.height, Math.sqrt(Math.sqrt(mem_max * 5000))) - 2;
- graph.bitmapData.scroll( -1, 0 );
+ graph.scroll(-1, 0);
- graph.bitmapData.fillRect( rectangle , theme.bg );
- graph.bitmapData.setPixel( graph.width - 1, graph.height - fps_graph, theme.fps);
- graph.bitmapData.setPixel( graph.width - 1, graph.height - ( ( timer - ms ) >> 1 ), theme.ms );
- graph.bitmapData.setPixel( graph.width - 1, graph.height - mem_graph, theme.mem);
- graph.bitmapData.setPixel( graph.width - 1, graph.height - mem_max_graph, theme.memmax);
+ graph.fillRect(rectangle, colors.bg);
+ graph.setPixel(graph.width - 1, graph.height - fps_graph, colors.fps);
+ graph.setPixel(graph.width - 1, graph.height - ( ( timer - ms ) >> 1 ), colors.ms);
+ graph.setPixel(graph.width - 1, graph.height - mem_graph, colors.mem);
+ graph.setPixel(graph.width - 1, graph.height - mem_max_graph, colors.memmax);
- xml.fps = "FPS: " + fps + " / " + stage.frameRate;
+ xml.fps = "FPS: " + fps + " / " + stage.frameRate;
xml.mem = "MEM: " + mem;
- xml.memMax = "MAX: " + mem_max;
+ xml.memMax = "MAX: " + mem_max;
fps = 0;
+
}
fps++;
@@ -158,19 +149,33 @@ package net.hires.debug
text.htmlText = xml;
}
-
- private function onClick(e : MouseEvent) : void
- {
+
+ private function onClick(e : MouseEvent) : void {
+
mouseY / height > .5 ? stage.frameRate-- : stage.frameRate++;
- xml.fps = "FPS: " + fps + " / " + stage.frameRate;
+ xml.fps = "FPS: " + fps + " / " + stage.frameRate;
text.htmlText = xml;
+
}
-
+
// .. Utils
-
- private function hex2css( color : int ) : String
- {
+
+ private function hex2css( color : int ) : String {
+
return "#" + color.toString(16);
+
}
+
}
+
}
+
+class Colors {
+
+ public var bg : uint = 0x000033;
+ public var fps : uint = 0xffff00;
+ public var ms : uint = 0x00ff00;
+ public var mem : uint = 0x00ffff;
+ public var memmax : uint = 0xff0070;
+
+}
\ No newline at end of file
diff --git a/src/net/hires/debug/Stats.hx b/src/net/hires/debug/Stats.hx
new file mode 100644
index 0000000..e026e84
--- /dev/null
+++ b/src/net/hires/debug/Stats.hx
@@ -0,0 +1,187 @@
+/**
+ * stats.hx
+ * http://github.com/mrdoob/stats.as
+ *
+ * Released under MIT license:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * How to use:
+ *
+ * addChild( new Stats() );
+ *
+ **/
+
+package net.hires.debug;
+
+import flash.display.BitmapData;
+import flash.display.Sprite;
+import flash.display.Stage;
+import flash.events.Event;
+import flash.events.MouseEvent;
+import flash.geom.Matrix;
+import flash.geom.Rectangle;
+import flash.system.System;
+import flash.text.StyleSheet;
+import flash.text.TextField;
+import flash.xml.XML;
+
+
+class Stats extends Sprite {
+
+ static inline var GRAPH_WIDTH : Int = 70;
+ static inline var XPOS : Int = 69;//width - 1
+ static inline var GRAPH_HEIGHT : Int = 50;
+ static inline var TEXT_HEIGHT : Int = 50;
+
+ private var xml : XML;
+
+ private var text : TextField;
+ private var style : StyleSheet;
+
+ private var timer : Int;
+ private var fps : Int;
+ private var ms : Int;
+ private var ms_prev : Int;
+ private var mem : Float;
+ private var mem_max : Float;
+
+ private var graph : BitmapData;
+ private var rectangle : Rectangle;
+
+ private var fps_graph : Int;
+ private var mem_graph : Int;
+ private var ms_graph : Int;
+ private var mem_max_graph : Int;
+ private var _stage:Stage;
+
+ /**
+ * Stats FPS, MS and MEM, all in one.
+ */
+ public function new() {
+
+ super();
+ mem_max = 0;
+ fps = 0;
+
+
+ xml = new XML("FPS:MS:MEM:MAX:");
+
+ style = new StyleSheet();
+ style.setStyle('xml', {fontSize:'9px', fontFamily:'_sans', leading:'-2px'});
+ style.setStyle('fps', {color: Colors.fpsCSS });
+ style.setStyle('ms', {color: Colors.msCSS });
+ style.setStyle('mem', {color: Colors.memCSS });
+ style.setStyle('memMax', {color: Colors.memmaxCSS });
+
+ text = new TextField();
+ text.width = GRAPH_WIDTH;
+ text.height = TEXT_HEIGHT;
+ text.styleSheet = style;
+ text.condenseWhite = true;
+ text.selectable = false;
+ text.mouseEnabled = false;
+
+ rectangle = new Rectangle(GRAPH_WIDTH - 1, 0, 1, GRAPH_HEIGHT);
+
+ this.addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
+ this.addEventListener(Event.REMOVED_FROM_STAGE, destroy, false, 0, true);
+
+ }
+
+ private function init(e : Event) {
+
+ _stage = flash.Lib.current.stage;
+ graphics.beginFill(Colors.bg);
+ graphics.drawRect(0, 0, GRAPH_WIDTH, TEXT_HEIGHT);
+ graphics.endFill();
+
+ this.addChild(text);
+
+ graph = new BitmapData(GRAPH_WIDTH, GRAPH_HEIGHT, false, Colors.bg);
+ graphics.beginBitmapFill(graph, new Matrix(1, 0, 0, 1, 0, TEXT_HEIGHT));
+ graphics.drawRect(0, TEXT_HEIGHT, GRAPH_WIDTH, GRAPH_HEIGHT);
+
+ this.addEventListener(Event.ENTER_FRAME, update);
+
+ }
+
+ private function destroy(e : Event) {
+
+ graphics.clear();
+
+ while(numChildren > 0)
+ removeChildAt(0);
+
+ graph.dispose();
+
+ removeEventListener(Event.ENTER_FRAME, update);
+
+ }
+
+ private function update(e : Event) {
+
+ timer = flash.Lib.getTimer();
+
+ //after a second has passed
+ if( timer - 1000 > ms_prev ) {
+
+ mem = System.totalMemory * 0.000000954;
+ mem_max = mem_max > mem ? mem_max : mem;
+
+ fps_graph = GRAPH_HEIGHT - Std.int( Math.min(GRAPH_HEIGHT, ( fps / _stage.frameRate ) * GRAPH_HEIGHT) );
+
+ mem_graph = GRAPH_HEIGHT - normalizeMem(mem);
+ mem_max_graph = GRAPH_HEIGHT - normalizeMem(mem_max);
+ //milliseconds since last frame -- this fluctuates quite a bit
+ ms_graph = Std.int( GRAPH_HEIGHT - ( ( timer - ms ) >> 1 ));
+ graph.scroll(-1, 0);
+
+ graph.fillRect(rectangle, Colors.bg);
+ graph.lock();
+ graph.setPixel(XPOS, fps_graph, Colors.fps);
+ graph.setPixel(XPOS, mem_graph, Colors.mem);
+ graph.setPixel(XPOS, mem_max_graph, Colors.memmax);
+ graph.setPixel(XPOS, ms_graph, Colors.ms);
+ graph.unlock();
+
+ xml.fps = "FPS: " + fps + " / " + stage.frameRate;
+ xml.mem = "MEM: " + mem;
+ xml.memMax = "MAX: " + mem_max;
+
+ //reset frame and time counters
+ fps = 0;
+ ms_prev = timer;
+
+ return;
+ }
+ //increment number of frames which have occurred in current second
+ fps++;
+
+ xml.ms = "MS: " + (timer - ms);
+ ms = timer;
+
+ text.htmlText = xml.toString();
+ }
+
+
+
+ function normalizeMem(_mem:Float):Int {
+ return Std.int( Math.min( GRAPH_HEIGHT, Math.sqrt(Math.sqrt(_mem * 5000)) ) - 2);
+ }
+
+}
+
+class Colors {
+
+ public static inline var bg : Int = 0x000033;
+ public static inline var fps : Int = 0xffff00;
+ public static inline var ms : Int = 0x00ff00;
+ public static inline var mem : Int = 0x00ffff;
+ public static inline var memmax : Int = 0xff0070;
+ public static inline var bgCSS : String = "#000033";
+ public static inline var fpsCSS : String = "#ffff00";
+ public static inline var msCSS : String = "#00ff00";
+ public static inline var memCSS : String = "#00ffff";
+ public static inline var memmaxCSS : String = "#ff0070";
+
+}