/src/com/matzmtok/demonsters/debugger/MonsterDebugger.hx
https://code.google.com/p/monsterdebugger4haxe/ · Haxe · 515 lines · 468 code · 38 blank · 9 comment · 78 complexity · e8cbbf9ccad1b84131d7fc9fabba9b39 MD5 · raw file
- package com.matzmtok.demonsters.debugger;
-
- import com.matzmtok.demonsters.debugger.Command;
- import com.matzmtok.demonsters.debugger.errors.ParserError;
- import com.matzmtok.demonsters.debugger.errors.ParserError;
- import com.matzmtok.demonsters.debugger.monitor.events.MonitorEvent;
- import com.matzmtok.demonsters.debugger.monitor.Monitor;
- import com.matzmtok.demonsters.debugger.parsers.DisplayObjectContainerParser;
- import com.matzmtok.demonsters.debugger.parsers.NumberParser;
- import com.matzmtok.demonsters.debugger.parsers.TypeParser;
- import com.matzmtok.demonsters.debugger.types.Type;
- import com.matzmtok.flash.Utils;
- import flash.display.BitmapData;
- import flash.display.DisplayObject;
- import flash.display.DisplayObjectContainer;
- import flash.display.Sprite;
- import flash.Error;
- import flash.events.AsyncErrorEvent;
- import flash.events.SecurityErrorEvent;
- import flash.events.StatusEvent;
- import flash.geom.Rectangle;
- import flash.net.LocalConnection;
- import flash.system.System;
- import flash.utils.ByteArray;
- import flash.utils.Timer;
- import flash.xml.XML;
- import flash.xml.XMLList;
- import flash.xml.XMLNode;
- import flash.xml.XMLNodeType;
-
- class MonsterDebugger {
- var logger : Dynamic;
- private var HIGHLIGHT_BORDER : Int;
- private var HIGHLIGHT_COLOR : UInt;
-
- static var COLOR_ERROR : UInt;
- static var COLOR_NORMAL : UInt;
- static var COLOR_WARNING : UInt;
-
- ////////////////////
- //
- // static constants
- //
- ////////////////////
-
- static var VERSION : Float;
- static var MAX_BUFFER_SIZE : Int = 500;
- static var MAX_PACKAGE_BYTES : Int = 40000;
- static var _enabled : Bool = true;
- static var LINE_OUT:String = "_debuggerRed";
- static var LINE_IN:String = "_debuggerBlue";
- static var ALLOWED_DOMAIN:String = "*";
-
- static var _instance:MonsterDebugger;
-
- var _buffer : Array<Dynamic>;
- var _root : Dynamic;
-
- var _connected:Bool;
-
- var _lineOut:LocalConnection;
- var _lineIn:LocalConnection;
- var _monitor:Monitor;
- var _highlight : Sprite;
-
- static public function enable():Bool {
- if (_instance != null) {
- _instance._monitor.enabled = true;
- }
- return _enabled = true;
- }
- static public function disable():Bool {
- if (_instance != null) {
- _instance._monitor.enabled = false;
- }
- return _enabled = false;
- }
- static public function isEnabled():Bool {
- return _enabled;
- }
- function new(target:Dynamic = null) {
- _buffer = [];
- _connected = false;
-
- if (_instance == null) {
- _instance = this;
- _lineIn = _createLConnection();
- _lineIn.allowDomain(ALLOWED_DOMAIN);
- _lineIn.client = this;
- _lineOut = _createLConnection();
-
- //monitor setup
-
- try {
- _lineIn.connect(LINE_IN);
- }catch (error:Error) {
- trace('Line in connection failed');
- }
- }
- _monitor = new Monitor();
- _monitor.addEventListener(MonitorEvent.MOINTOR_UPDATE, monitorUpdateHandler);
- _instance._root = target;
- _instance._send({text:Command.HELLO, version:VERSION});
- }
- function _createLConnection():LocalConnection {
- var lc:LocalConnection = new LocalConnection();
- lc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHanlder );
- lc.addEventListener(SecurityErrorEvent.SECURITY_ERROR , securityErrorHandler);
- lc.addEventListener(StatusEvent.STATUS, statusHandler);
- return lc;
- }
- function asyncErrorHanlder(event:AsyncErrorEvent):Void {
- _connected = false;
- }
- function securityErrorHandler(event:SecurityErrorEvent):Void {
- _connected = false;
- }
- function statusHandler(event:StatusEvent):Void {
- if (event.level == "error" ) {
- _connected = false;
- }
- }
-
- function monitorUpdateHandler(event:MonitorEvent):Void {
- var mon:Monitor = cast (event.target, Monitor);
- if (mon != null) {
- sendCommand({text:Command.MONITOR, memory:mon.memory, fps:mon.fps, time:mon.time, start:mon.monitorStart});
- }
- }
- static public function trace(target : Dynamic, object : Dynamic, ?color : UInt, ?functions : Bool, ?depth : Int) : Void {
- if ( !_enabled ) return ;
- if (_instance == null) {
- _instance = new MonsterDebugger(target);
- }
- if (_enabled ) {
- _instance.traceInternal(target, object, color, functions, depth);
- }
- }
- static public function inspect(target:Dynamic):Void {
- if (_instance != null && target != null) {
- _instance._root = target;
-
- var obj:Dynamic = _instance.getObject("", 0);
- if (obj != null) {
- var parser:TypeParser = TypeParser.getParser(Type.getTypeString(obj));
- parser.maxDepth = 2;
- var xml:XML = parser.parseToXML(obj, "", false);
- _instance.sendCommand( { text:Command.INSPECT, xml:xml } );
-
- if (_instance.isDisplayObject(obj)) {
- _instance._base(obj, false);
- }
- }
- }
- }
- static function snapshot(target:DisplayObject, ?color:UInt) : Void {
- if (_instance == null) {
- _instance = new MonsterDebugger(null);
- }
- if (MonsterDebugger._enabled) {
- _instance.snapshotInternal(target, color);
- }
- }
- function snapshotInternal(target:DisplayObject, ?color:UInt = 0x111111):Void {
- if (_enabled ) {
- var w:Int = Math.ceil(target.width);
- var h:Int = Math.ceil(target.height);
- var bitmapData = new BitmapData(w, h);
- bitmapData.draw(target);
-
- var bytes:ByteArray = bitmapData.getPixels(new Rectangle(0, 0, w, h));
-
- var memory:UInt = System.totalMemory;
-
- var obj:Dynamic = {
- text:Command.SNAPSHOT,
- date:Date.now(),
- target:target.toString(),
- bytes:bytes,
- width:w,
- height:h,
- color:color,
- memory:memory };
-
- sendCommand(obj);
-
- bitmapData.dispose();
- bytes = null;
- }
- }
- function traceInternal(target : Dynamic, object : Dynamic, ?color : UInt, ?functions : Bool, ?depth : Int) : Void {
- var parser:TypeParser = TypeParser.getParser(Type.getTypeString(object));
-
- var xml:XML = parser.parseToXML(object, "", functions);
- var memory:UInt = System.totalMemory;
- var date:Date = Date.now();
- var command:Dynamic = {
- text:Command.TRACE,
- date:date,
- target:target.toString(),
- xml:xml,
- color:color,
- memory:memory
- };
- sendCommand(command);
- }
- function sendCommand(data:Dynamic):Void {
- if (_connected) {
- _send(data);
- }else {
- _sendToBuffer(data);
- }
- }
-
- function _send(data:Dynamic):Void {
- var item:ByteArray = new ByteArray();
- item.writeObject(data);
- item.compress();
- var dataPackages:Array<Dynamic> = [];
- if (item.length > MAX_PACKAGE_BYTES ) {
- var bytesAvailable:Int = item.length;
- var offset:Int = 0;
- var total:Int = Math.ceil(item.length / MAX_PACKAGE_BYTES);
- for (i in 0...total) {
- var length:Int = bytesAvailable;
- if (length > MAX_PACKAGE_BYTES ) {
- length = MAX_PACKAGE_BYTES;
- }
-
- var tmp:ByteArray = new ByteArray();
- tmp.writeBytes(item, offset, length);
-
- dataPackages.push( { total:total, nr:(i + 1), bytes:tmp } );
- bytesAvailable -= length;
- offset += length;
- }
- }else {
- dataPackages.push({total:1, nr:1, bytes:item});
- }
- for (i in 0...dataPackages.length) {
- try {
- _lineOut.send(LINE_OUT, "onReceivedData", dataPackages[i]);
- }catch (error:Error) {
- trace('error occerd at send');
- break;
- }
- }
- }
- function _sendToBuffer(data:Dynamic):Void {
- _buffer.push(data);
- if (_buffer.length > MAX_BUFFER_SIZE ) {
- _buffer.shift();
- }
- }
- function _sendBuffer():Void {
- if (_buffer.length > 0) {
- while (_buffer.length > 0) {
- var msg:Dynamic = _buffer.shift();
- _send(msg);
- }
- }
- }
- static public function clearTraces():Void {
- if (_instance == null) {
- _instance = new MonsterDebugger(null);
- }
- if (MonsterDebugger._enabled) {
- _instance._clearTracesInternal();
- }
- }
- function _clearTracesInternal():Void {
- if (_enabled) {
- var command:Dynamic = { text:Command.CLEAR_TRACES };
- sendCommand(command);
- }
- }
-
- public function onReceivedData(data:ByteArray):Void {
- if (_enabled ) {
- data.uncompress();
-
- var command:Dynamic = data.readObject();
- switch(command.text) {
- case Command.HELLO:
- hello(command);
- case Command.HELLO_RESPONSE:
- helloResponse(command);
- case Command.ROOT:
- root(command);
- case Command.GET_OBJECT:
- get_object(command);
- case Command.GET_DISPLAYOBJECT:
- get_displayObject(command);
- case Command.GET_PROPERTIES:
- get_properties(command);
- case Command.GET_FUNCTIONS:
- get_functions(command);
- case Command.SET_PROPERTY:
- set_property(command);
- case Command.CALL_METHOD:
- call_method(command);
- case Command.SHOW_HIGHLIGHT:
- show_highlight(command);
- case Command.HIDE_HIGHLIGHT:
- hide_highlight(command);
- }
-
- }
- }
- function hello(command:Dynamic):Void {
- _connected = true;
- _send({text:Command.HELLO, version:VERSION});
- }
- function helloResponse(command:Dynamic):Void {
- _connected = true;
- _sendBuffer();
- }
-
- function root(command:Dynamic):Void {
- var obj:Dynamic = getObject("", 0);
- if (obj != null) {
- untyped{
- var parser:TypeParser = TypeParser.getParser (Type.getTypeString(obj));
- parser.maxDepth = 2;
- untyped{
- var xml:XML = parser.parseToXML(obj, "", command['functions']);
- _send( { text:Command.ROOT, xml:xml } );
- }
- //base(command);
- if (isDisplayObject(obj)) {
- base(command);
- }
- }
- }
- }
- function base(command:Dynamic):Void {
- var obj:Dynamic = getObject("", 0);
- if (obj != null) {
- _base(obj, command.functions);
- }
- }
- function _base(object:Dynamic, functions:Bool):Void {
- var p:DisplayObjectContainerParser = new DisplayObjectContainerParser();
- try {
- untyped {
- p.maxDepth = 2;
- var xml:XML = p.parseToXML(object, "", functions);
- _send( { text:Command.BASE, xml:xml } );
- }
- }catch (error:ParserError) {
- if (error.errorID == ParserError.NOT_FOUND ) {
- var msg:XMLNode = createWarningNode("Not found", "Not Found");
- sendCommand({text:Command.NOTFOUND, target:error.target, xml:new XML(msg.toString())});
- }
- throw error;
- }
- }
- function get_object(command:Dynamic):Void {
- untyped {
- var object:Dynamic = getObject(command.target, 0);
- if (object != null) {
-
- var parser:TypeParser = TypeParser.getParser(Type.getTypeString(object));
- var xml:XML = parser.parseToXML(object, command.target, command.functions);
- _send({text:Command.GET_OBJECT, xml:xml});
- }
-
- }
- }
-
- function get_displayObject(command:Dynamic):Void {
- var object:Dynamic = getObject(command.target, 0);
- if (object != null) {
- if (isDisplayObject(object)) {
- var parser:DisplayObjectContainerParser = new DisplayObjectContainerParser();
- parser.maxDepth = 2;
- var xml:XML = parser.parseToXML(object, command.target, command.functions);
- _send({text:Command.GET_DISPLAYOBJECT, xml:xml});
- }
- }
- }
- function get_properties(command:Dynamic):Void {
- var object:Dynamic = getObject(command.target, 0);
- if (object != null) {
- var parser:TypeParser = TypeParser.getParser(Type.getTypeString(object));
- parser.maxDepth = 4;
- var xml:XML = parser.parseToXML(object, command.target, false);
- _send({text:Command.GET_PROPERTIES, xml:xml});
- }
- }
- function get_functions(command:Dynamic):Void {
- var object:Dynamic = getObject(command.target, 0);
- if (object != null) {
- var parser:TypeParser = new TypeParser();
- try{
- var xml:XML = parser.getFunctions(object, command.target);
- _send({text:Command.GET_FUNCTIONS, xml:xml});
- }catch (error:ParserError) {
- var xml:XML = new XML('<root></root>');
- xml.appendChild( createWarningNode("Not found", "Not found"));
- sendCommand( { text:Command.NOTFOUND, target:command.target, xml:xml } );
- }
- }
- }
- function set_property(command:Dynamic):Void {
- var object:Dynamic = getObject(command.target, 1);
- if (object != null) {
- try {
- object[command.name] = command.value;
- _send({text:Command.SET_PROPERTY, value:object[command.name]});
- } catch (error:Error) {
- _send({text:Command.NOTFOUND, target:command.target});
- }
- }
- }
-
- function call_method(command:Dynamic):Void {
- var method:Dynamic = getObject(command.target, 0);
- if (method != null) {
- if (command.returnType == Type.TYPE_VOID) {
- method.apply(this, command.arguments);
- } else {
- var object:Dynamic = method.apply(this, command.arguments);
- var parser:TypeParser = TypeParser.getParser(Type.getTypeString(object));
- parser.maxDepth = 4;
- var xml:XML = parser.parseToXML(object, "", false);
- _send({text:Command.CALL_METHOD, id:command.id, xml:xml});
- }
- }
- }
-
- function show_highlight(command:Dynamic):Void {
- if (_highlight != null) {
- try {
- _highlight.parent.removeChild(_highlight);
- _highlight = null;
- } catch(error:Error) {
- //
- }
- }
- var object:Dynamic = getObject(command.target, 0);
- if (isDisplayObject(object) && isDisplayObject(object.parent)) {
- var bounds:Rectangle = object.getBounds(object.parent);
- _highlight = new Sprite();
- _highlight.x = 0;
- _highlight.y = 0;
- _highlight.graphics.beginFill(0, 0);
- _highlight.graphics.lineStyle(HIGHLIGHT_BORDER, HIGHLIGHT_COLOR);
- _highlight.graphics.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
- _highlight.graphics.endFill();
- _highlight.mouseChildren = false;
- _highlight.mouseEnabled = false;
- try {
- object.parent.addChild(_highlight);
- } catch(error:Error) {
- _highlight = null;
- }
- }
- }
-
- function hide_highlight(command:Dynamic):Void {
- if (_highlight != null) {
- try {
- _highlight.parent.removeChild(_highlight);
- _highlight = null;
- } catch(error:Error) {
- //
- }
- }
- }
-
- function getObject(target:String = "", parent:Int = 0):Dynamic{
- var obj:Dynamic = _instance._root;
-
- if (target != "") {
- var path:Array < String > = target.split(".");
- var len:Int = path.length - parent;
- for ( i in 0...len ) {
- if (path[i] != "") {
- try {
- if (path[i] == "children()") {
- obj = obj.children();
- }else if ( path[i].indexOf("getChildAt(") == 0) {
- var j:Int = Std.parseInt(path[i].substr(11, path[i].indexOf(")", 11 - 11)));
- obj = obj.getChildAt(j);
- }else {
- untyped {
- obj = obj[path[i]];
- }
- }
- }catch (error:ParserError) {
- if (error.errorID == ParserError.NOT_FOUND ) {
- var msg:XMLNode = new XMLNode(XMLNodeType.ELEMENT_NODE, "root");
- msg.appendChild(createWarningNode("Not found", "Not found"));
- sendCommand({text:Command.NOTFOUND, target:target, xml:new XML(msg.toString())});
- }
- }
- }
- }
- }
- return obj;
- }
-
- function isDisplayObject(obj:Dynamic):Bool {
- return Std.is(obj, DisplayObject);
- }
- function createWarningNode(label:String, name:String):XMLNode {
- var node:XMLNode = new XMLNode(XMLNodeType.ELEMENT_NODE, "node");
- node.attributes.icon = Icon.ICON_WARNING;
- node.attributes.type = Type.TYPE_WARNING;
- node.attributes.label = label;
- node.attributes.name = name;
- return node;
- }
- }