PageRenderTime 56ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/pgr/gconsole/GConsole.hx

http://github.com/cambiata/cx
Haxe | 396 lines | 295 code | 65 blank | 36 comment | 61 complexity | 66818da597b8a8776aedfc1ee92e42de MD5 | raw file
  1. package pgr.gconsole;
  2. import flash.display.Sprite;
  3. import flash.events.Event;
  4. import flash.events.KeyboardEvent;
  5. import flash.Lib;
  6. /**
  7. * GConsole is the main class of this lib, it should be instantiated only once
  8. * and then use its instance to control the console.
  9. *
  10. * Its recomended to use GameConsole class as API for this lib.
  11. *
  12. * @author TiagoLr ( ~~~ProG4mr~~~ )
  13. */
  14. class GConsole extends Sprite
  15. {
  16. inline static private var GC_TRC_ERR = "gc_error: ";
  17. /** Aligns console to bottom */
  18. static public var ALIGN_DOWN:String = "DOWN";
  19. /** Aligns console to top */
  20. static public var ALIGN_UP:String = "UP";
  21. private var _firstLine:Bool;
  22. private var _historyArray:Array<String>;
  23. private var _historyIndex:Int;
  24. private var _historyMaxSz:Int;
  25. public var _interface:GCInterface;
  26. private var _elapsedFrames:Int;
  27. private var _monitorRate:Int;
  28. private var _consoleScKey:Int;
  29. private var _isMonitorOn:Bool;
  30. private var _isConsoleOn:Bool;
  31. public static var instance:GConsole;
  32. public function new(height:Float = 0.33, align:String = "DOWN", theme:GCThemes.Theme = null, monitorRate:Int = 10)
  33. {
  34. super();
  35. if (height > 1) height = 1;
  36. if (height < 0.1) height = 0.1;
  37. _interface = new GCInterface(height,align,theme);
  38. addChild(_interface);
  39. _monitorRate = monitorRate;
  40. _consoleScKey = 9;
  41. _historyArray = new Array();
  42. _historyIndex = -1;
  43. _historyMaxSz = 100;
  44. _firstLine = true;
  45. enable();
  46. hideConsole();
  47. hideMonitor();
  48. instance = this;
  49. GameConsole.log("~~~~~~~~~~ GAME CONSOLE ~~~~~~~~~~");
  50. }
  51. public function setConsoleFont(font:String = null, embed:Bool = true, size:Int = 14, bold:Bool = false, italic:Bool = false, underline:Bool = false )
  52. {
  53. _interface.setConsoleFont(font, embed, size, bold, italic, underline);
  54. }
  55. public function setPromptFont(font:String = null, embed:Bool = true, size:Int = 16, yOffset:Int = 22, bold:Bool = false, ?italic:Bool = false, underline:Bool = false )
  56. {
  57. _interface.setPromptFont(font, embed, size, yOffset, bold, italic, underline);
  58. }
  59. public function setMonitorFont(font:String = null, embed:Bool = true, size:Int = 14, bold:Bool = false, ?italic:Bool = false, underline:Bool = false )
  60. {
  61. _interface.setMonitorFont(font, embed, size, bold, italic, underline);
  62. }
  63. public function showConsole()
  64. {
  65. if (!this.visible) return;
  66. Lib.current.stage.focus = _interface.txtPrompt;
  67. _isConsoleOn = true;
  68. _interface.toggleConsoleOn(true);
  69. }
  70. public function hideConsole()
  71. {
  72. if (!this.visible) return;
  73. _isConsoleOn = false;
  74. _interface.toggleConsoleOn(false);
  75. }
  76. public function showMonitor()
  77. {
  78. _isMonitorOn = true;
  79. _interface.toggleMonitor(true);
  80. addEventListener(Event.ENTER_FRAME, updateMonitor);
  81. _elapsedFrames = _monitorRate + 1;
  82. updateMonitor(null); // renders first frame.
  83. }
  84. public function hideMonitor()
  85. {
  86. _isMonitorOn = false;
  87. _interface.toggleMonitor(false);
  88. removeEventListener(Event.ENTER_FRAME, updateMonitor);
  89. }
  90. public function enable()
  91. {
  92. visible = true;
  93. Lib.current.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp, false);
  94. Lib.current.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, false);
  95. }
  96. public function disable()
  97. {
  98. if (_isMonitorOn) hideMonitor();
  99. if (_isConsoleOn) hideConsole();
  100. Lib.current.stage.removeEventListener(KeyboardEvent.KEY_UP, onKeyUp, false);
  101. Lib.current.stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, false);
  102. visible = false;
  103. }
  104. public function setShortcutKeyCode(key:Int)
  105. {
  106. _consoleScKey = key;
  107. }
  108. public function log(data:Dynamic)
  109. {
  110. if (data == "") return;
  111. _firstLine ?
  112. _firstLine = false :
  113. _interface.txtConsole.text += '\n'; //add new line if console text was not clear.
  114. _interface.txtConsole.text += data.toString();
  115. _interface.txtConsole.scrollV = _interface.txtConsole.maxScrollV;
  116. }
  117. public function registerVariable(object:Dynamic, name:String, alias:String, monitor:Bool=false)
  118. {
  119. if (!Reflect.isObject(object)) {
  120. trace(GC_TRC_ERR + "dynamic passed with the field: " + name + " is not an object.");
  121. return;
  122. }
  123. #if !(cpp || neko)
  124. if (!Reflect.hasField(object, name))
  125. #else
  126. if (Reflect.getProperty(object, name) == null)
  127. #end
  128. {
  129. trace (GC_TRC_ERR + name + " field was not found in object passed.");
  130. return;
  131. }
  132. log(GCCommands.registerVariable(object, name, alias, monitor));
  133. }
  134. public function unregisterVariable(alias:String)
  135. {
  136. if (GCCommands.unregisterVariable(alias)) {
  137. log("variable " + alias + " unregistered.");
  138. } else {
  139. log("variable " + alias + " not found.");
  140. }
  141. }
  142. public function registerFunction(object:Dynamic, name:String, alias:String, ?monitor:Bool = false)
  143. {
  144. #if !(cpp || neko)
  145. if (!Reflect.hasField(object, name))
  146. #else
  147. if (Reflect.getProperty(object, name) == null)
  148. #end
  149. {
  150. trace (GC_TRC_ERR + name + " field was not found in object passed.");
  151. return;
  152. }
  153. if (!Reflect.isFunction(Reflect.field(object, name))) {
  154. trace(GC_TRC_ERR + "could not find function: " + name + " in object passed.");
  155. return;
  156. }
  157. log(GCCommands.registerFunction(object, name, alias, monitor));
  158. }
  159. public function unregisterFunction(alias:String)
  160. {
  161. if (GCCommands.unregisterFunction(alias)) {
  162. log("function " + alias + " unregistered.");
  163. } else {
  164. log("function " + alias + " not found.");
  165. }
  166. }
  167. public function clearConsole()
  168. {
  169. _interface.txtConsole.text = '';
  170. _firstLine = true;
  171. }
  172. public function clearRegistry()
  173. {
  174. GCCommands.clearRegistry();
  175. }
  176. // INPUT HANDLING ------------------------------------------------------
  177. private function onKeyDown(e:KeyboardEvent):Void
  178. {
  179. #if !(cpp || neko) // BUGFIX
  180. if (_isConsoleOn)
  181. e.stopImmediatePropagation();
  182. #end
  183. }
  184. private function onKeyUp(e:KeyboardEvent):Void
  185. {
  186. if (e.ctrlKey && cast(e.keyCode,Int) == _consoleScKey ) {
  187. _isMonitorOn ? hideMonitor() : showMonitor();
  188. return;
  189. }
  190. if (cast(e.keyCode,Int) == _consoleScKey) {
  191. _isConsoleOn ? hideConsole() : showConsole();
  192. return;
  193. }
  194. // Read the following input if console is showing.
  195. if (!_isConsoleOn)
  196. return;
  197. // Changed switch to if-else to avoid strande exception in haxe 3 regarding int and uint.
  198. if (e.keyCode == 13)
  199. {
  200. processInputLine();
  201. }
  202. else
  203. if (e.keyCode == 33)
  204. {
  205. _interface.txtConsole.scrollV -= _interface.txtConsole.bottomScrollV - _interface.txtConsole.scrollV +1;
  206. if (_interface.txtConsole.scrollV < 0)
  207. _interface.txtConsole.scrollV = 0;
  208. }
  209. else
  210. if (e.keyCode == 34)
  211. {
  212. _interface.txtConsole.scrollV += _interface.txtConsole.bottomScrollV - _interface.txtConsole.scrollV +1;
  213. if (_interface.txtConsole.scrollV > _interface.txtConsole.maxScrollV)
  214. _interface.txtConsole.scrollV = _interface.txtConsole.maxScrollV;
  215. }
  216. else
  217. if (e.keyCode == 38)
  218. {
  219. nextHistory();
  220. }
  221. else
  222. if (e.keyCode == 40)
  223. {
  224. prevHistory();
  225. }
  226. else
  227. {
  228. _historyIndex = -1;
  229. }
  230. /*
  231. }
  232. switch (e.keyCode) {
  233. // ENTER
  234. case 13 : processInputLine();
  235. // PAGEUP
  236. case 33 : _interface.txtConsole.scrollV -= _interface.txtConsole.bottomScrollV - _interface.txtConsole.scrollV +1;
  237. if (_interface.txtConsole.scrollV < 0)
  238. _interface.txtConsole.scrollV = 0;
  239. // PAGEDOWN
  240. case 34 : _interface.txtConsole.scrollV += _interface.txtConsole.bottomScrollV - _interface.txtConsole.scrollV +1;
  241. if (_interface.txtConsole.scrollV > _interface.txtConsole.maxScrollV)
  242. _interface.txtConsole.scrollV = _interface.txtConsole.maxScrollV;
  243. // UP
  244. case 38 : nextHistory();
  245. // DOWN
  246. case 40 : prevHistory();
  247. default : _historyIndex = -1;
  248. }
  249. */
  250. #if !(cpp || neko) // BUGFIX
  251. e.stopImmediatePropagation(); // BUG - cpp issues.
  252. #end
  253. }
  254. private function prevHistory()
  255. {
  256. _historyIndex--;
  257. if (_historyIndex < 0 ) _historyIndex = 0;
  258. if (_historyIndex > _historyArray.length - 1) return;
  259. _interface.txtPrompt.text = _historyArray[_historyIndex];
  260. #if !(cpp || neko)
  261. _interface.txtPrompt.setSelection(_interface.txtPrompt.length, _interface.txtPrompt.length);
  262. #end
  263. }
  264. private function nextHistory()
  265. {
  266. if (_historyIndex + 1 > _historyArray.length - 1) return;
  267. _historyIndex++;
  268. _interface.txtPrompt.text = _historyArray[_historyIndex];
  269. #if !(cpp || neko)
  270. _interface.txtPrompt.setSelection(_interface.txtPrompt.length, _interface.txtPrompt.length);
  271. #end
  272. }
  273. // INPUT PARSE ----------------------------------------------------
  274. private function processInputLine()
  275. {
  276. if (_interface.txtPrompt.text == '')
  277. return;
  278. var temp:String = _interface.txtPrompt.text;
  279. _historyArray.insert(0, _interface.txtPrompt.text);
  280. _historyIndex = -1;
  281. if (_historyArray.length > _historyMaxSz)
  282. _historyArray.splice(_historyArray.length - 1, 1);
  283. log(": " + _interface.txtPrompt.text);
  284. _interface.txtPrompt.text = '';
  285. parseInput(temp);
  286. }
  287. private function parseInput(input:String)
  288. {
  289. var args:Array<String> = input.split(' ');
  290. var argsLC:Array<String> = input.toLowerCase().split(' ');
  291. switch (argsLC[0]) {
  292. case "clear" : clearConsole();
  293. case "monitor" : _isMonitorOn ? hideMonitor() : showMonitor();
  294. case "help" : log(GCCommands.showHelp());
  295. case "commands" : log(GCCommands.showCommands());
  296. case "vars" : log(GCCommands.listVars());
  297. case "fcns" : log(GCCommands.listFunctions());
  298. case "set" : log(GCCommands.setVar(args));
  299. case "call" : log(GCCommands.callFunction(args));
  300. }
  301. }
  302. // MONITOR --------------------------------------------------------
  303. private function updateMonitor(e:Event):Void
  304. {
  305. _elapsedFrames++;
  306. if (_elapsedFrames > _monitorRate) {
  307. processMonitorOutput(GCCommands.getMonitorOutput());
  308. _elapsedFrames = 0;
  309. }
  310. }
  311. private function processMonitorOutput(input:String)
  312. {
  313. if (input.length == 0) return;
  314. var str1:String;
  315. var str2:String;
  316. var splitPoint:Int = Std.int(input.length / 2) - 1;
  317. while (splitPoint < input.length) {
  318. if (input.charAt(splitPoint) == "\n")
  319. break;
  320. splitPoint++;
  321. }
  322. _interface.txtMonitorLeft.text = input.substr(0, splitPoint);
  323. _interface.txtMonitorRight.text = input.substr(splitPoint + 1);
  324. }
  325. // GETTERS AND SETTERS ------------------------------------------------
  326. private function set_historyMaxSz(value:Int):Int
  327. {
  328. return _historyMaxSz = value;
  329. }
  330. public var historyMaxSz(null, set_historyMaxSz):Int;
  331. }