PageRenderTime 103ms CodeModel.GetById 58ms RepoModel.GetById 0ms app.codeStats 0ms

/!src/com/luaye/console/Console.as

https://github.com/tluczyns/tluczyns-as3-base
ActionScript | 795 lines | 684 code | 9 blank | 102 comment | 121 complexity | 88a32cff7f1339761afc37b6f8e48f8c MD5 | raw file
  1. /*
  2. *
  3. * Copyright (c) 2008-2009 Lu Aye Oo
  4. *
  5. * @author Lu Aye Oo
  6. *
  7. * http://code.google.com/p/flash-console/
  8. *
  9. *
  10. * This software is provided 'as-is', without any express or implied
  11. * warranty. In no event will the authors be held liable for any damages
  12. * arising from the use of this software.
  13. * Permission is granted to anyone to use this software for any purpose,
  14. * including commercial applications, and to alter it and redistribute it
  15. * freely, subject to the following restrictions:
  16. * 1. The origin of this software must not be misrepresented; you must not
  17. * claim that you wrote the original software. If you use this software
  18. * in a product, an acknowledgment in the product documentation would be
  19. * appreciated but is not required.
  20. * 2. Altered source versions must be plainly marked as such, and must not be
  21. * misrepresented as being the original software.
  22. * 3. This notice may not be removed or altered from any source distribution.
  23. *
  24. */
  25. package com.luaye.console {
  26. import com.luaye.console.view.MainPanel;
  27. import com.luaye.console.core.CommandLine;
  28. import com.luaye.console.core.Log;
  29. import com.luaye.console.core.Logs;
  30. import com.luaye.console.core.MemoryMonitor;
  31. import com.luaye.console.core.Remoting;
  32. import com.luaye.console.core.UserData;
  33. import com.luaye.console.utils.Utils;
  34. import com.luaye.console.view.ChannelsPanel;
  35. import com.luaye.console.view.FPSPanel;
  36. import com.luaye.console.view.PanelsManager;
  37. import com.luaye.console.view.RollerPanel;
  38. import flash.display.DisplayObjectContainer;
  39. import flash.display.Sprite;
  40. import flash.events.Event;
  41. import flash.events.KeyboardEvent;
  42. import flash.geom.Rectangle;
  43. import flash.net.LocalConnection;
  44. import flash.system.System;
  45. import flash.text.StyleSheet;
  46. import flash.utils.getQualifiedClassName;
  47. import flash.utils.getTimer;
  48. /**
  49. * Console is the main class.
  50. * Please see com.luaye.console.C for documentation as it shares the same properties and methods structure.
  51. * @see http://code.google.com/p/flash-console/
  52. * @see com.luaye.console.C
  53. */
  54. public class Console extends Sprite {
  55. public static const VERSION:Number = 2.35;
  56. public static const VERSION_STAGE:String = "";
  57. //
  58. public static const NAME:String = "Console";
  59. public static const PANEL_MAIN:String = "mainPanel";
  60. public static const PANEL_CHANNELS:String = "channelsPanel";
  61. public static const PANEL_FPS:String = "fpsPanel";
  62. public static const PANEL_MEMORY:String = "memoryPanel";
  63. public static const PANEL_ROLLER:String = "rollerPanel";
  64. //
  65. public static const GLOBAL_CHANNEL:String = " * ";
  66. public static const CONSOLE_CHANNEL:String = "C";
  67. public static const FILTERED_CHANNEL:String = "~";
  68. public static const DEFAULT_CHANNEL:String = "-";
  69. //
  70. public static const LOG_LEVEL:uint = 1;
  71. public static const INFO_LEVEL:uint = 3;
  72. public static const DEBUG_LEVEL:uint = 5;
  73. public static const WARN_LEVEL:uint = 7;
  74. public static const ERROR_LEVEL:uint = 9;
  75. public static const FATAL_LEVEL:uint = 10;
  76. //
  77. public static const FPS_MAX_LAG_FRAMES:uint = 25;
  78. public static const MAPPING_SPLITTER:String = "|";
  79. //
  80. // You can change this if you don't want to use default channel
  81. // Other remotes with different remoting channel won't be able to connect your flash.
  82. // Start with _ to work in any domain + platform (air/swf - local / network)
  83. // Change BEFORE starting remote / remoting
  84. public static var RemotingConnectionName:String = "_Console";
  85. // You can change this if you want to use different Shared data. set to null to avoid using.
  86. // Change BEFORE starting console.
  87. public static var SharedObjectName:String = "com/luaye/Console/UserData";
  88. //
  89. public var style:ConsoleStyle;
  90. public var css:StyleSheet;
  91. public var panels:PanelsManager;
  92. public var cl:CommandLine;
  93. public var ud:UserData;
  94. private var _mm:MemoryMonitor;
  95. private var _remoter:Remoting;
  96. //
  97. public var quiet:Boolean;
  98. public var maxLines:int = 1000;
  99. public var prefixChannelNames:Boolean = true;
  100. public var alwaysOnTop:Boolean = true;
  101. public var moveTopAttempts:int = 50;
  102. public var maxRepeats:Number = 75;
  103. public var remoteDelay:int = 20;
  104. public var tracingPriority:int = 0;
  105. public var rulerHidesMouse:Boolean = true;
  106. //
  107. private var _isPaused:Boolean;
  108. private var _password:String;
  109. private var _passwordIndex:int;
  110. private var _tracing:Boolean = false;
  111. private var _filterText:String;
  112. private var _filterRegExp:RegExp;
  113. private var _keyBinds:Object = {};
  114. private var _mspf:Number;
  115. private var _previousTime:Number;
  116. private var _traceCall:Function = trace;
  117. private var _rollerCaptureKey:String;
  118. private var _commandLineAllowed:Boolean = true;
  119. private var _channels:Array = [GLOBAL_CHANNEL, DEFAULT_CHANNEL];
  120. private var _viewingChannels:Array = [GLOBAL_CHANNEL];
  121. private var _tracingChannels:Array = [];
  122. private var _isRepeating:Boolean;
  123. private var _priority:int;
  124. private var _repeated:int;
  125. private var _lines:Logs;
  126. private var _lineAdded:Boolean;
  127. /**
  128. * Console is the main class. However please use C for singleton Console adapter.
  129. * Using Console through C will also make sure you can remove console in a later date
  130. * by simply removing C.start() or C.startOnStage()
  131. *
  132. *
  133. * @see com.luaye.console.C
  134. * @see http://code.google.com/p/flash-console/
  135. */
  136. public function Console(pass:String = "", skin:ConsoleStyle = null) {
  137. name = NAME;
  138. if(pass == null) pass = "";
  139. tabChildren = false; // Tabbing is not supported
  140. _password = pass;
  141. //
  142. _lines = new Logs();
  143. ud = new UserData(SharedObjectName,"/");
  144. cl = new CommandLine(this);
  145. _remoter = new Remoting(this, remoteLogSend, pass);
  146. //
  147. // VIEW setup
  148. style = skin?skin:new ConsoleStyle();
  149. generateCSS();
  150. var mainPanel:MainPanel = new MainPanel(this, _lines, _channels, _viewingChannels);
  151. mainPanel.addEventListener(Event.CONNECT, onMainPanelConnectRequest, false, 0, true);
  152. panels = new PanelsManager(this, mainPanel, _channels);
  153. //
  154. report("<b>Console v"+VERSION+(VERSION_STAGE?(" "+VERSION_STAGE):"")+", Happy coding!</b>", -2);
  155. addEventListener(Event.ADDED_TO_STAGE, stageAddedHandle);
  156. if(_password) visible = false;
  157. }
  158. private function stageAddedHandle(e:Event=null):void{
  159. if(cl.base == null) cl.base = parent;
  160. removeEventListener(Event.ADDED_TO_STAGE, stageAddedHandle);
  161. addEventListener(Event.REMOVED_FROM_STAGE, stageRemovedHandle);
  162. //
  163. addEventListener(Event.ENTER_FRAME, _onEnterFrame);
  164. stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave, false, 0, true);
  165. stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler, false, 0, true);
  166. }
  167. private function stageRemovedHandle(e:Event=null):void{
  168. if(cl.base == parent) cl.base = null;
  169. removeEventListener(Event.REMOVED_FROM_STAGE, stageRemovedHandle);
  170. addEventListener(Event.ADDED_TO_STAGE, stageAddedHandle);
  171. //
  172. removeEventListener(Event.ENTER_FRAME, _onEnterFrame);
  173. stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
  174. stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
  175. }
  176. private function onStageMouseLeave(e:Event):void{
  177. panels.tooltip(null);
  178. }
  179. private function keyDownHandler(e:KeyboardEvent):void{
  180. var char:String = String.fromCharCode(e.charCode);
  181. if(!char) return;
  182. if(char == _password.substring(_passwordIndex,_passwordIndex+1)){
  183. _passwordIndex++;
  184. if(_passwordIndex >= _password.length){
  185. _passwordIndex = 0;
  186. if(visible && !panels.mainPanel.visible){
  187. panels.mainPanel.visible = true;
  188. }else visible = !visible;
  189. }
  190. }else{
  191. _passwordIndex = 0;
  192. var key:String = char.toLowerCase()+(e.ctrlKey?"1":"0")+(e.altKey?"1":"0")+(e.shiftKey?"1":"0");
  193. if(_keyBinds[key]){
  194. var bind:Array = _keyBinds[key];
  195. (bind[0] as Function).apply(this, bind[1]);
  196. }
  197. }
  198. }
  199. public function destroy():void{
  200. _remoter.close();
  201. removeEventListener(Event.ENTER_FRAME, _onEnterFrame);
  202. removeEventListener(Event.REMOVED_FROM_STAGE, stageRemovedHandle);
  203. removeEventListener(Event.ADDED_TO_STAGE, stageAddedHandle);
  204. cl.destory();
  205. }
  206. private function generateCSS():void{
  207. css = new StyleSheet();
  208. with(style){
  209. css.setStyle("r",{textAlign:'right', display:'inline'});
  210. css.setStyle("w",{color:hesh(highColor), fontFamily:menuFont, fontSize:menuFontSize, display:'inline'});
  211. css.setStyle("s",{color:hesh(lowColor), fontFamily:menuFont, fontSize:menuFontSize-2, display:'inline'});
  212. css.setStyle("hi",{color:hesh(menuHighlightColor), display:'inline'});
  213. css.setStyle("menu",{color:hesh(menuColor), display:'inline'});
  214. css.setStyle("chs",{color:hesh(channelsColor), fontSize:menuFontSize, leading:'2', display:'inline'});
  215. css.setStyle("ch",{color:hesh(channelColor), display:'inline'});
  216. css.setStyle("tooltip",{color:hesh(tooltipColor),fontFamily:menuFont,fontSize:menuFontSize, textAlign:'center'});
  217. css.setStyle("p",{fontFamily:traceFont, fontSize:traceFontSize});
  218. css.setStyle("p0",{color:hesh(priority0), display:'inline'});
  219. css.setStyle("p1",{color:hesh(priority1), display:'inline'});
  220. css.setStyle("p2",{color:hesh(priority2), display:'inline'});
  221. css.setStyle("p3",{color:hesh(priority3), display:'inline'});
  222. css.setStyle("p4",{color:hesh(priority4), display:'inline'});
  223. css.setStyle("p5",{color:hesh(priority5), display:'inline'});
  224. css.setStyle("p6",{color:hesh(priority6), display:'inline'});
  225. css.setStyle("p7",{color:hesh(priority7), display:'inline'});
  226. css.setStyle("p8",{color:hesh(priority8), display:'inline'});
  227. css.setStyle("p9",{color:hesh(priority9), display:'inline'});
  228. css.setStyle("p10",{color:hesh(priority10), fontWeight:'bold', display:'inline'});
  229. css.setStyle("p-1",{color:hesh(priorityC1), display:'inline'});
  230. css.setStyle("p-2",{color:hesh(priorityC2), display:'inline'});
  231. }
  232. }
  233. private function hesh(n:Number):String{return "#"+n.toString(16);}
  234. public function addGraph(n:String, obj:Object, prop:String, col:Number = -1, key:String = null, rect:Rectangle = null, inverse:Boolean = false):void{
  235. if(obj == null) {
  236. report("ERROR: Graph ["+n+"] received a null object to graph property ["+prop+"].", 10);
  237. return;
  238. }
  239. panels.addGraph(n,obj,prop,col,key,rect,inverse);
  240. }
  241. public function fixGraphRange(n:String, min:Number = NaN, max:Number = NaN):void{
  242. panels.fixGraphRange(n, min, max);
  243. }
  244. public function removeGraph(n:String, obj:Object = null, prop:String = null):void{
  245. panels.removeGraph(n, obj, prop);
  246. }
  247. //
  248. // WARNING: key binding hard references the function.
  249. // This should only be used for development purposes only.
  250. //
  251. public function bindKey(char:String, ctrl:Boolean, alt:Boolean, shift:Boolean, fun:Function ,args:Array = null):void{
  252. if(!char || char.length!=1){
  253. report("Binding key must be a single character. You gave ["+char+"]", 10);
  254. return;
  255. }
  256. bindByKey(getKey(char, ctrl, alt, shift), fun, args);
  257. if(!quiet){
  258. report((fun is Function?"Bined":"Unbined")+" key <b>"+ char.toUpperCase() +"</b>"+ (ctrl?"+ctrl":"")+(alt?"+alt":"")+(shift?"+shift":"")+".",-1);
  259. }
  260. }
  261. private function bindByKey(key:String, fun:Function ,args:Array = null):void{
  262. if(fun==null){
  263. delete _keyBinds[key];
  264. }else{
  265. _keyBinds[key] = [fun,args];
  266. }
  267. }
  268. private function getKey(char:String, ctrl:Boolean = false, alt:Boolean = false, shift:Boolean = false):String{
  269. return char.toLowerCase()+(ctrl?"1":"0")+(alt?"1":"0")+(shift?"1":"0");
  270. }
  271. //
  272. // Panel settings
  273. // basically passing through to panels manager to save lines
  274. //
  275. public function setPanelArea(panelname:String, rect:Rectangle):void{
  276. panels.setPanelArea(panelname, rect);
  277. }
  278. public function get channelsPanel():Boolean{
  279. return panels.channelsPanel;
  280. }
  281. public function set channelsPanel(b:Boolean):void{
  282. panels.channelsPanel = b;
  283. }
  284. //
  285. public function get displayRoller():Boolean{
  286. return panels.displayRoller;
  287. }
  288. public function set displayRoller(b:Boolean):void{
  289. panels.displayRoller = b;
  290. }
  291. public function setRollerCaptureKey(char:String, ctrl:Boolean = false, alt:Boolean = false, shift:Boolean = false):void{
  292. if(_rollerCaptureKey){
  293. bindByKey(_rollerCaptureKey, null);
  294. _rollerCaptureKey = null;
  295. }
  296. if(char && char.length==1){
  297. _rollerCaptureKey = getKey(char.toLowerCase(), ctrl, alt, shift);
  298. bindByKey(_rollerCaptureKey, onRollerCaptureKey);
  299. }
  300. }
  301. public function get rollerCaptureKey():String{
  302. return _rollerCaptureKey;
  303. }
  304. private function onRollerCaptureKey():void{
  305. if(displayRoller){
  306. report("Display Roller Capture:<br/>"+RollerPanel(panels.getPanel(PANEL_ROLLER)).capture(), -1);
  307. }
  308. }
  309. //
  310. public function get fpsMonitor():Boolean{
  311. return panels.fpsMonitor;
  312. }
  313. public function set fpsMonitor(b:Boolean):void{
  314. panels.fpsMonitor = b;
  315. }
  316. //
  317. public function get memoryMonitor():Boolean{
  318. return panels.memoryMonitor;
  319. }
  320. public function set memoryMonitor(b:Boolean):void{
  321. panels.memoryMonitor = b;
  322. }
  323. //
  324. public function watch(o:Object,n:String = null):String{
  325. var className:String = getQualifiedClassName(o);
  326. if(!n) n = className+"@"+getTimer();
  327. if(!_mm) _mm = new MemoryMonitor();
  328. var nn:String = _mm.watch(o,n);
  329. if(!quiet) report("Watching <b>"+className+"</b> as <p5>"+ nn +"</p5>.",-1);
  330. return nn;
  331. }
  332. public function unwatch(n:String):void{
  333. if(_mm) _mm.unwatch(n);
  334. }
  335. public function gc():void{
  336. if(remote){
  337. try{
  338. report("Sending garbage collection request to client",-1);
  339. _remoter.send("gc");
  340. }catch(e:Error){
  341. report(e,10);
  342. }
  343. }else{
  344. var ok:Boolean = MemoryMonitor.Gc();
  345. var str:String = "Manual garbage collection "+(ok?"successful.":"FAILED. You need debugger version of flash player.");
  346. report(str,(ok?-1:10));
  347. }
  348. }
  349. public function store(n:String, obj:Object, strong:Boolean = false):void{
  350. cl.store(n, obj, strong);
  351. }
  352. public function map(base:DisplayObjectContainer, maxstep:uint = 0):void{
  353. cl.map(base, maxstep);
  354. }
  355. public function inspect(obj:Object, detail:Boolean = true):void{
  356. cl.inspect(obj,detail);
  357. }
  358. public function get paused():Boolean{
  359. return _isPaused;
  360. }
  361. public function set paused(newV:Boolean):void{
  362. if(_isPaused == newV) return;
  363. if(newV) report("Paused", 10);
  364. else report("Resumed", -1);
  365. _isPaused = newV;
  366. panels.mainPanel.setPaused(newV);
  367. }
  368. //
  369. //
  370. //
  371. override public function get width():Number{
  372. return panels.mainPanel.width;
  373. }
  374. override public function set width(newW:Number):void{
  375. panels.mainPanel.width = newW;
  376. }
  377. override public function set height(newW:Number):void{
  378. panels.mainPanel.height = newW;
  379. }
  380. override public function get height():Number{
  381. return panels.mainPanel.height;
  382. }
  383. override public function get x():Number{
  384. return panels.mainPanel.x;
  385. }
  386. override public function set x(newW:Number):void{
  387. panels.mainPanel.x = newW;
  388. }
  389. override public function set y(newW:Number):void{
  390. panels.mainPanel.y = newW;
  391. }
  392. override public function get y():Number{
  393. return panels.mainPanel.y;
  394. }
  395. //
  396. //
  397. //
  398. private function _onEnterFrame(e:Event):void{
  399. var time:int = getTimer();
  400. _mspf = time-_previousTime;
  401. _previousTime = time;
  402. if(alwaysOnTop && parent && parent.getChildAt(parent.numChildren-1) != this && moveTopAttempts>0){
  403. moveTopAttempts--;
  404. parent.addChild(this);
  405. if(!quiet){
  406. report("Moved console on top (alwaysOnTop enabled), "+moveTopAttempts+" attempts left.",-1);
  407. }
  408. }
  409. if( _isRepeating ){
  410. _repeated++;
  411. if(_repeated > maxRepeats && maxRepeats >= 0){
  412. _isRepeating = false;
  413. }
  414. }
  415. if(!_isPaused && _mm!=null){
  416. var arr:Array = _mm.update();
  417. if(arr.length>0){
  418. report("<b>GARBAGE COLLECTED "+arr.length+" item(s): </b>"+arr.join(", "),-2);
  419. if(!_mm.haveItemsWatching) _mm = null;
  420. }
  421. }
  422. if(visible){
  423. panels.mainPanel.update(!_isPaused && _lineAdded);
  424. if(_lineAdded) {
  425. var chPanel:ChannelsPanel = panels.getPanel(PANEL_CHANNELS) as ChannelsPanel;
  426. if(chPanel) chPanel.update();
  427. _lineAdded = false;
  428. }
  429. }
  430. if(_remoter.remoting){
  431. _remoter.update(_mspf, stage?stage.frameRate:0);
  432. }
  433. }
  434. public function get fps():Number{
  435. return 1000/_mspf;
  436. }
  437. public function get mspf():Number{
  438. return _mspf;
  439. }
  440. public function get currentMemory():uint {
  441. return _remoter.isRemote?_remoter.remoteMem:System.totalMemory;
  442. }
  443. //
  444. // REMOTING
  445. //
  446. public function get remoting():Boolean{
  447. return _remoter.remoting;
  448. }
  449. public function set remoting(newV:Boolean):void{
  450. _remoter.remoting = newV;
  451. }
  452. public function get remote():Boolean{
  453. return _remoter.isRemote;
  454. }
  455. public function set remote(newV:Boolean):void{
  456. _remoter.isRemote = newV;
  457. panels.updateMenu();
  458. }
  459. public function set remotingPassword(str:String):void{
  460. _remoter.remotingPassword = str;
  461. }
  462. private function onMainPanelConnectRequest(e:Event) : void {
  463. _remoter.login(MainPanel(e.currentTarget).commandLineText);
  464. }
  465. //
  466. // this is sent from client for remote...
  467. // obj[0] = array of log lines (text, priority, channel, repeating, safeHTML)
  468. // obj[1] = array of 'milliseconds per frame' since previous logsend - for FPS display
  469. // obj[2] = client's current memory usage
  470. // obj[3] = client's command line scope - string
  471. private function remoteLogSend(obj:Array):void{
  472. if(!_remoter.isRemote || !obj) return;
  473. var lines:Array = obj[0];
  474. for each( var line:Object in lines){
  475. if(line){
  476. addLine(line.text,line.p,line.c,line.r,line.s);
  477. }
  478. }
  479. var remoteMSPFs:Array = obj[1];
  480. if(remoteMSPFs){
  481. var fpsp:FPSPanel = panels.getPanel(PANEL_FPS) as FPSPanel;
  482. if(fpsp){
  483. // the first value is stage.FrameRate
  484. var highest:Number = remoteMSPFs[0];
  485. fpsp.highest = highest;
  486. fpsp.averaging = highest;
  487. var len:int = remoteMSPFs.length;
  488. for(var i:int = 1; i<len;i++){
  489. var fps:Number = 1000/remoteMSPFs[i];
  490. if(fps > highest) fps = highest;
  491. fpsp.addCurrent(fps);
  492. }
  493. fpsp.updateKeyText();
  494. fpsp.drawGraph();
  495. }
  496. }
  497. _remoter.remoteMem = obj[2];
  498. if(obj[3]){
  499. // older clients don't send CL scope
  500. panels.mainPanel.updateCLScope(obj[3]);
  501. }
  502. }
  503. //
  504. //
  505. //
  506. public function get viewingChannels():Array{
  507. return _viewingChannels.concat();
  508. }
  509. public function set viewingChannels(a:Array):void{
  510. _viewingChannels.splice(0);
  511. if(a && a.length) {
  512. if(a.indexOf(GLOBAL_CHANNEL)>=0) a = [GLOBAL_CHANNEL];
  513. for each(var item:Object in a) _viewingChannels.push(item is Ch?(Ch(item).name):String(item));
  514. } else _viewingChannels.push(GLOBAL_CHANNEL);
  515. panels.mainPanel.updateToBottom();
  516. panels.updateMenu();
  517. }
  518. public function set tracingChannels(a:Array):void{
  519. _tracingChannels.splice(0);
  520. if(a){
  521. for each(var item:Object in a) _tracingChannels.push(item is Ch?(Ch(item).name):String(item));
  522. }
  523. }
  524. public function get tracingChannels():Array{
  525. return _tracingChannels.concat();
  526. }
  527. //
  528. public function get tracing():Boolean{
  529. return _tracing;
  530. }
  531. public function set tracing(b:Boolean):void{
  532. _tracing = b;
  533. panels.mainPanel.updateMenu();
  534. }
  535. public function set traceCall (f:Function):void{
  536. if(f==null){
  537. report("C.traceCall function setter can not be null.", 10);
  538. }else{
  539. _traceCall = f;
  540. }
  541. }
  542. public function get traceCall ():Function{
  543. return _traceCall;
  544. }
  545. public function report(obj:*,priority:Number = 0, skipSafe:Boolean = true):void{
  546. addLine(obj, priority, CONSOLE_CHANNEL, false, skipSafe);
  547. }
  548. private function addLine(obj:*,priority:Number = 0,channel:String = null,isRepeating:Boolean = false, skipSafe:Boolean = false):void{
  549. var isRepeat:Boolean = (isRepeating && _isRepeating);
  550. var txt:String = (obj is XML || obj is XMLList)?obj.toXMLString():String(obj);
  551. if(!channel || channel == GLOBAL_CHANNEL){
  552. channel = DEFAULT_CHANNEL;
  553. }
  554. if( _tracing && !isRepeat && (_tracingChannels.length==0 || _tracingChannels.indexOf(channel)>=0) ){
  555. if(tracingPriority <= priority || tracingPriority <= 0){
  556. _traceCall("["+channel+"] "+txt);
  557. }
  558. }
  559. if(!skipSafe){
  560. txt = txt.replace(/</gim, "&lt;");
  561. txt = txt.replace(/>/gim, "&gt;");
  562. }
  563. if(_channels.indexOf(channel) < 0){
  564. _channels.push(channel);
  565. }
  566. var line:Log = new Log(txt,channel,priority, isRepeating, skipSafe);
  567. if(isRepeat){
  568. _lines.pop();
  569. _lines.push(line);
  570. }else{
  571. _repeated = 0;
  572. _lines.push(line);
  573. if(maxLines > 0 ){
  574. var off:int = _lines.length - maxLines;
  575. if(off > 0){
  576. _lines.shift(off);
  577. }
  578. }
  579. }
  580. _lineAdded = true;
  581. _isRepeating = isRepeating;
  582. if(_remoter.remoting){
  583. _remoter.addLineQueue(line);
  584. }
  585. }
  586. public function lineShouldShow(line:Log):Boolean{
  587. return (
  588. (
  589. _viewingChannels[0] == Console.GLOBAL_CHANNEL
  590. || _viewingChannels.indexOf(line.c)>=0
  591. || (_filterText && _viewingChannels.indexOf(Console.FILTERED_CHANNEL)>=0 && line.text.toLowerCase().indexOf(_filterText.toLowerCase())>=0 )
  592. || (_filterRegExp && _viewingChannels.indexOf(Console.FILTERED_CHANNEL)>=0 && line.text.search(_filterRegExp)>=0 )
  593. )
  594. && ( _priority <= 0 || line.p >= _priority)
  595. );
  596. }
  597. public function set priority (i:int):void{
  598. _priority = i;
  599. panels.mainPanel.updateToBottom();
  600. panels.updateMenu();
  601. }
  602. public function get priority ():int{
  603. return _priority;
  604. }
  605. //
  606. // COMMAND LINE
  607. //
  608. public function set commandLine (newB:Boolean):void{
  609. if(newB && !_commandLineAllowed){
  610. panels.updateMenu();
  611. report("CommandLine is disabled. Set commandLineAllowed from source code to allow.");
  612. }else{
  613. panels.mainPanel.commandLine = newB;
  614. }
  615. }
  616. public function get commandLine ():Boolean{
  617. return panels.mainPanel.commandLine;
  618. }
  619. public function set commandLineAllowed (v:Boolean):void{
  620. _commandLineAllowed = v;
  621. if(!v && commandLine){
  622. commandLine = false;
  623. }
  624. }
  625. public function get commandLineAllowed ():Boolean{
  626. return _commandLineAllowed;
  627. }
  628. public function set commandBase (v:Object):void{
  629. if(v) cl.base = v;
  630. }
  631. public function get commandBase ():Object{
  632. return cl.base;
  633. }
  634. public function runCommand(line:String):*{
  635. if(_remoter.isRemote){
  636. report("Run command at remote: "+line,-2);
  637. try{
  638. _remoter.send("runCommand", line);
  639. }catch(err:Error){
  640. report("Command could not be sent to client: " + err, 10);
  641. }
  642. }else{
  643. return cl.run(line);
  644. }
  645. return null;
  646. }
  647. //
  648. // LOGGING
  649. //
  650. public function ch(channel:*, newLine:*, priority:Number = 2, isRepeating:Boolean = false):void{
  651. var chn:String;
  652. if(channel is String){
  653. chn = channel as String;
  654. }else if(channel){
  655. chn = Utils.shortClassName(channel);
  656. }else{
  657. chn = DEFAULT_CHANNEL;
  658. }
  659. addLine(newLine,priority,chn, isRepeating);
  660. }
  661. public function add(newLine:*, priority:Number = 2, isRepeating:Boolean = false):void{
  662. addLine(newLine,priority, DEFAULT_CHANNEL, isRepeating);
  663. }
  664. public function log(...args):void{
  665. addLine(joinArgs(args), LOG_LEVEL);
  666. }
  667. public function info(...args):void{
  668. addLine(joinArgs(args), INFO_LEVEL);
  669. }
  670. public function debug(...args):void{
  671. addLine(joinArgs(args), DEBUG_LEVEL);
  672. }
  673. public function warn(...args):void{
  674. addLine(joinArgs(args), WARN_LEVEL);
  675. }
  676. public function error(...args):void{
  677. addLine(joinArgs(args), ERROR_LEVEL);
  678. }
  679. public function fatal(...args):void{
  680. addLine(joinArgs(args), FATAL_LEVEL);
  681. }
  682. public function logch(channel:*, ...args):void{
  683. ch(channel, joinArgs(args), LOG_LEVEL);
  684. }
  685. public function infoch(channel:*, ...args):void{
  686. ch(channel, joinArgs(args), INFO_LEVEL);
  687. }
  688. public function debugch(channel:*, ...args):void{
  689. ch(channel, joinArgs(args), DEBUG_LEVEL);
  690. }
  691. public function warnch(channel:*, ...args):void{
  692. ch(channel, joinArgs(args), WARN_LEVEL);
  693. }
  694. public function errorch(channel:*, ...args):void{
  695. ch(channel, joinArgs(args), ERROR_LEVEL);
  696. }
  697. public function fatalch(channel:*, ...args):void{
  698. ch(channel, joinArgs(args), FATAL_LEVEL);
  699. }
  700. public function joinArgs(args:Array):String{
  701. for(var X:String in args){
  702. // XML.toString() doesn't print all if its single node. Therefore need to convert them with toXMLString().
  703. if(args[X] is XML || args[X] is XMLList) args[X] = args[X].toXMLString();
  704. }
  705. return args.join(" ");
  706. }
  707. //
  708. public function set filterText(str:String):void{
  709. _filterText = str;
  710. if(str){
  711. _filterRegExp = null;
  712. clear(FILTERED_CHANNEL);
  713. _channels.splice(1,0,FILTERED_CHANNEL);
  714. addLine("Filtering ["+str+"]", 10,FILTERED_CHANNEL);
  715. viewingChannels = [FILTERED_CHANNEL];
  716. }else if(_viewingChannels.length == 1 && _viewingChannels[0] == FILTERED_CHANNEL){
  717. viewingChannels = [GLOBAL_CHANNEL];
  718. }
  719. }
  720. public function get filterText():String{
  721. return _filterText?_filterText:(_filterRegExp?String(_filterRegExp):null);
  722. }
  723. //
  724. public function set filterRegExp(exp:RegExp):void{
  725. _filterRegExp = exp;
  726. if(exp){
  727. _filterText = null;
  728. clear(FILTERED_CHANNEL);
  729. _channels.splice(1,0,FILTERED_CHANNEL);
  730. addLine("Filtering RegExp ["+exp+"]", 10,FILTERED_CHANNEL);
  731. viewingChannels = [FILTERED_CHANNEL];
  732. }else if(_viewingChannels.length == 1 && _viewingChannels[0] == FILTERED_CHANNEL){
  733. viewingChannels = [GLOBAL_CHANNEL];
  734. }
  735. }
  736. //
  737. public function clear(channel:String = null):void{
  738. if(channel){
  739. var line:Log = _lines.first;
  740. while(line){
  741. if(line.c == channel){
  742. _lines.remove(line);
  743. }
  744. line = line.next;
  745. }
  746. var ind:int = _channels.indexOf(channel);
  747. if(ind>=0) _channels.splice(ind,1);
  748. }else{
  749. _lines.clear();
  750. _channels.splice(0);
  751. _channels.push(GLOBAL_CHANNEL, DEFAULT_CHANNEL);
  752. }
  753. if(!_isPaused) panels.mainPanel.updateToBottom();
  754. panels.updateMenu();
  755. }
  756. public function getLogsAsObjects():Array{
  757. var a:Array = [];
  758. var line:Log = _lines.first;
  759. while(line){
  760. a.push(line.toObject());
  761. line = line.next;
  762. }
  763. return a;
  764. }
  765. public function getAllLog(splitter:String = "\n"):String{
  766. var str:String = "";
  767. var line:Log = _lines.first;
  768. while(line){
  769. str += (line.toString()+(line.next?splitter:""));
  770. line = line.next;
  771. }
  772. return str;
  773. }
  774. public static function get remoteIsRunning():Boolean{
  775. var sCon:LocalConnection = new LocalConnection();
  776. try{
  777. sCon.allowInsecureDomain("*");
  778. sCon.connect(RemotingConnectionName+Remoting.REMOTE_PREFIX);
  779. }catch(error:Error){
  780. return true;
  781. }
  782. sCon.close();
  783. return false;
  784. }
  785. }
  786. }