« 桜 2008 | Home | Chinese MC Hammer. »

Apr 042008

img8.debug.Debugger

先日エントリーしたDebuggerをちょっと変えました。
基本FPS計測はOFF。でFPS表示の前のボタンをクリックして計測開始、再度クリックで計測中断。ただこれによって一度増えたメモリ消費が下がるのか?はまだ完全に検証できていません・・。(もともとがあまりに微小な値なのでかなり長時間回して検証しないと良く分からん)あとはグラフの幅だとか、レコードする個数とかプロパティを設定できるように。(普通はさわらないだろうけど)

で、Debuggerのコメントでちょっと思いついたShapeに対してEnterFrameを行えばメモリ消費は少なくなるか?という部分も一応実装してみましたが、大して変わりませんでした(涙

なんにしてもGCの中にたまっているであろうEventがいつの日かGCによって開放されるのをただただ祈るだけであります。

こゆのリポジトリとか晒して、最新のにSVNとかで同期させるのがいいのだろうけど、これどやって晒せばいいんですかね??(一応開発はSVNでやってるんだけど、色々他の案件のものとかもあって全部晒せない)なんかこんな手動同期での公開もイマイチ申し訳ないんですが、しばらくこれで・・。すいません。

これで色々試していると、GCが作動する瞬間がグラフ上でガクンと下がるのでなんか楽しいw ずーっと見ているとなんとなく、この状態の時に作動するんだな?ということが分かってきます。で、逆に言うと、その発動するタイミングを能動的にこちらから作ってやることで、なんとか任意のタイミングでGCを発動できんもんかと・・・思うわけです。(っつーかもう普通にgcメソッドを普通のプレイヤーにも入れてくれと・・)

package img8.debug {
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.system.System;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	public class Debugger extends Sprite{
		private var _tfTitle:TextField;
		private var _tfMem:TextField;
		private var _tfFPS:TextField;
		private var _timer:Timer;
		private var _count:uint = 0;
		private var _txf_default:TextFormat = new TextFormat("_sans", 10, 0xffffff, null, null, null, null, null, "right");
		private var _txf_red:TextFormat = new TextFormat("_sans", 10, 0xff0000);
		private var _txf_blue:TextFormat = new TextFormat("_sans", 10, 0x00ff00);
		private var _txf_tmp:TextFormat ;
		private var _interval:Number = 500;
		private var _time:int = 0;
		private var _timeTmp:int = 0;
		private var _memory:Number = 0;
		private var _memoryMin:Number = Math.round(System.totalMemory *0.001);
		private var _memoryMax:Number = 0;
		private var _memoryTmp:Number = 0;
		private var _fps:Number = 0;
		private var _fpsMax:Number = 0;
		private var _history:Array = [];
		private var _iHistory:Shape;
		private var _historyNum:uint = 100;
		private var _historyWidth:Number = 400;
		private var _isCheckFPS:Boolean = false;
		private var _iBody:Sprite;
		private var _btFPS:Sprite;
		private var _sEnterFrame:Shape;
		public function Debugger(target:DisplayObject,aInterval:Number=500) :void
		{
			_init(target, aInterval);
		}
		private function _init(target:DisplayObject,aInterval:Number):Boolean
		{
			if (!target.stage) {
				throw(new Error("this Object has not added yet. please addChild this displayObject"));
				return false;
			}
			var root = target.stage.root as DisplayObject;
			var mine = target.root.parent as DisplayObject;
			var flgIsRoot = (root == mine);
			if (flgIsRoot) 
			{
				interval = aInterval;
				_buildFace();
				_time = flash.utils.getTimer();
				_timer = new Timer(_interval);
				_timer.addEventListener(TimerEvent.TIMER, _onCheck);
				_timer.start();
			}
			return flgIsRoot;
		}
		private function _buildFace():void
		{
			//body
			_iBody = new Sprite();
			_iBody.buttonMode = true;
			_iBody.mouseEnabled = true;
			_iBody.doubleClickEnabled = true;
			_iBody.addEventListener(MouseEvent.MOUSE_DOWN, _onStartDrag);
			_iBody.addEventListener(MouseEvent.MOUSE_UP, _onStopDrag);
			_iBody.addEventListener(MouseEvent.DOUBLE_CLICK, _showHistory);
			addChild(_iBody);
			//title
			_tfTitle = new TextField();
			_tfTitle.mouseEnabled = false;
			_tfTitle.autoSize = TextFieldAutoSize.LEFT;
			_tfTitle.defaultTextFormat = _txf_default;
			_tfTitle.text = "img8.debugger";
			_tfTitle.selectable = false;
			addChild(_tfTitle);
			//memory
			_tfMem = new TextField();
			_tfMem.mouseEnabled = false;
			_tfMem.width = _tfTitle.width;
			_tfMem.autoSize = TextFieldAutoSize.RIGHT;
			_tfMem.defaultTextFormat = _txf_default;
			_tfMem.text = "used memory";
			_tfMem.selectable = false;
			_tfMem.y = _tfTitle.y + _tfTitle.height;
			addChild(_tfMem);
			//fps
			_tfFPS = new TextField();
			_tfFPS.mouseEnabled = false;
			_tfFPS.width =  _tfTitle.width;
			_tfFPS.autoSize = TextFieldAutoSize.RIGHT;
			_tfFPS.defaultTextFormat = _txf_default;
			_tfFPS.text = "framerate";
			_tfFPS.selectable = false;
			_tfFPS.y = _tfMem.y + _tfMem.height;
			addChild(_tfFPS);
			//toggle button FPS
			_btFPS = new Sprite();
			_btFPS.buttonMode = true;
			_btFPS.x = 3;
			_btFPS.y = _tfFPS.y + 3;
			_btFPS.graphics.beginFill(0xff0000);
			_btFPS.graphics.drawRect(0, 0, 10, 10);
			_btFPS.graphics.endFill();
			_btFPS.addEventListener(MouseEvent.CLICK, _toggleFPS);
			addChild(_btFPS);
			//header
			var bodyWidth:Number = _tfTitle.width + 10;
			_iBody.graphics.beginFill(0x000000);
			_iBody.graphics.drawRect(0, 0, bodyWidth, _tfTitle.y+_tfTitle.height);
			_iBody.graphics.endFill();
			//body
			_iBody.graphics.beginFill(0x333333);
			var titleHeight:Number = _tfTitle.y+_tfTitle.height
			_iBody.graphics.drawRect(0, titleHeight, bodyWidth, _tfFPS.y+_tfFPS.height-titleHeight);
			_iBody.graphics.endFill();
			//_sEnterFrame
			_sEnterFrame = new Shape();
		}
		private function _checkMem():void
		{
			_memoryTmp = Math.round(System.totalMemory *0.001);
			if (_memoryTmp > _memory) {
				_txf_tmp = _txf_red;
			}else if (_memoryTmp < _memory) {
				_txf_tmp = _txf_blue;
			}else {
				_txf_tmp = _txf_default;
			}
			_memory = _memoryTmp;
			_memoryMax = Math.max(_memory, _memoryMax);
			_tfMem.text = String( _memory) + "KB";
			_tfMem.setTextFormat(_txf_tmp);
		}
		private function _checkFPS() :void
		{
			_timeTmp = getTimer();
			_fps = Math.round(_count * 100000 / (_timeTmp - _time)) / 100;
			_fpsMax = Math.max(_fps, _fpsMax);
			_txf_tmp = _fps < stage.frameRate ? _txf_red : _txf_default;
			_tfFPS.text = String(_fps) + "FPS";
			_tfFPS.setTextFormat(_txf_tmp);
			_count = 0;
			_time = _timeTmp;
		}
		private function _doFrame(event:Event):void
		{
			++_count;
		}
		private function _onCheck(e:TimerEvent = null):void
		{
			_checkFPS();
			_checkMem();
			_storeHistory();
			if (_iHistory)_drawHistory();
		}
		private function _storeHistory():void
		{
			if (_history.push( { time:_time, fps:_fps, memory:_memory } ) > _historyNum)_history.splice(0, _history.length - _historyNum);
		}
		private function _onStartDrag(event:MouseEvent = null):void
		{
			startDrag(false);
		}
		private function _onStopDrag(event:MouseEvent = null):void
		{
			stopDrag();
		}
		private function _showHistory(event:MouseEvent = null):void
		{
			if (_iHistory) {
				removeChild(_iHistory);
				_iHistory = null;
			}else{
				_iHistory = new Shape();
				_iHistory.x = width + 10;
				_iHistory.y = 150;
				_drawHistory();
				addChild(_iHistory);
			}
		}
		private function _drawHistory():void
		{
			if (_iHistory) _iHistory.graphics.clear();
			var hisGra:Graphics = _iHistory.graphics;
			hisGra.beginFill(0x333333);
			hisGra.drawRect(0, 0, _historyWidth, -150);
			hisGra.endFill();
			//memory
			var memoryRange:Number = - 75 / (_memoryMax-_memoryMin);
			hisGra.lineStyle(0, 0xff0000);
			var i:uint = 0;
			var ratex:Number = _historyWidth / (_historyNum-1);
			hisGra.moveTo(0, (_history[i].memory-_memoryMin) * memoryRange);
			for (i = 1; i < _history.length; i++) hisGra.lineTo(i*ratex, (_history[i].memory-_memoryMin)*memoryRange);
			//fps
			var fpsRange:Number = - 100 / _fpsMax;
			hisGra.lineStyle(0, 0x00ff00);
			i = 0;
			hisGra.moveTo(0, _history[i].fps*fpsRange);
			for (i = 1; i < _history.length; i++) hisGra.lineTo(i*ratex, _history[i].fps*fpsRange);
		}
		private function _toggleFPS(e:MouseEvent=null):void
		{
			_isCheckFPS = !_isCheckFPS;
			if (_isCheckFPS) {
			_sEnterFrame.addEventListener(Event.ENTER_FRAME, _doFrame);
			_btFPS.graphics.beginFill(0x00ff00);
			_btFPS.graphics.drawRect(0, 0, 10, 10);
			_btFPS.graphics.endFill();
			}else {
			_sEnterFrame.removeEventListener(Event.ENTER_FRAME, _doFrame);
			_btFPS.graphics.beginFill(0xff0000);
			_btFPS.graphics.drawRect(0, 0, 10, 10);
			_btFPS.graphics.endFill();
			}
		}
		//properties 
		public function set historyWidth(n:Number) :void
		{
			_historyWidth = n;
		}
		public function get historyWidth() :Number
		{
			return _historyWidth;
		}
		public function set interval(aInterval:Number):void
		{
			_interval = aInterval;
			if(_timer)_timer.delay = _interval;
		}
		public function get interval():Number
		{
			return _timer.delay;
		}
		public function set recordNum(n:uint):void
		{
			_historyNum = n;
		}
		public function get recordNum():uint
		{
			return _historyNum;
		}
	}
	
}

Leave a comment

Search and Archives