PageRenderTime 94ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/!src/de/mightypirates/utils/Console.as

https://github.com/tluczyns/tluczyns-as3-base
ActionScript | 433 lines | 187 code | 57 blank | 189 comment | 30 complexity | 0093ae64305f0a381c8432a60ea66736 MD5 | raw file
  1. /*
  2. * Console - A very simplistic and flexible console class.
  3. * Copyright (C) 2007-2009 Florian Nuecke
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. * SOFTWARE.
  22. */
  23. package de.mightypirates.utils {
  24. import flash.display.Sprite;
  25. import flash.events.Event;
  26. import flash.events.KeyboardEvent;
  27. import flash.events.TimerEvent;
  28. import flash.geom.Point;
  29. import flash.system.Capabilities;
  30. import flash.system.System;
  31. import flash.text.TextField;
  32. import flash.text.TextFieldType;
  33. import flash.text.TextFormat;
  34. import flash.ui.Keyboard;
  35. import flash.utils.Timer;
  36. /**
  37. * Simple console class allowing for output by either simply appending text, or appending
  38. * text and adding a newline after it.
  39. * Input is redirected to a method passed to the constructor which must handle input
  40. * appropriately.
  41. * Note that a top left aligned stage is required for proper displaying!
  42. *
  43. * @author fnuecke
  44. * @version 1.17
  45. */
  46. public class Console extends Sprite {
  47. // ---------------------------------------------------------------------- //
  48. // Constants
  49. // ---------------------------------------------------------------------- //
  50. /** Hotkey that opens the console */
  51. private static const _hotKey:String = "#";
  52. // ---------------------------------------------------------------------- //
  53. // Variables
  54. // ---------------------------------------------------------------------- //
  55. /** The background for the console */
  56. private var background:Sprite;
  57. /** Last entered commands */
  58. private var commands:Array;
  59. /** Current index in the command history */
  60. private var current:int = 0;
  61. /** The input text */
  62. private var input:TextField;
  63. /** The function that will handle the user input */
  64. private var inputHandler:Function;
  65. /** The output text */
  66. private var output:TextField;
  67. // ---------------------------------------------------------------------- //
  68. // Constructor
  69. // ---------------------------------------------------------------------- //
  70. /**
  71. * Constructor.
  72. *
  73. * @param inputHandler
  74. * a function that handles text input, must take a string with the
  75. * input text and return a string with the system's response
  76. * message.
  77. * @param baseWidth
  78. * the basic width of the stage. If not given it is assumed the
  79. * stage is at its basic width on instantiation of this object.
  80. * @param baseHeight
  81. * the basic height of the stage. If not given it is assumed the
  82. * stage is at its basic width on instantiation of this object.
  83. */
  84. /*
  85. Basic example for an inputHandler function,
  86. assuming the Console object is named "console":
  87. function handleInput(input:String):String
  88. {
  89. var args:Array = input.split(" ");
  90. var msg:String = "";
  91. switch (args[0])
  92. {
  93. case "list":
  94. case "cmdlist":
  95. case "listcmds":
  96. case "help":
  97. case "?":
  98. msg += "The following commands are available:\n";
  99. msg += "cls - Clears the console of all messages\n";
  100. msg += "exit - Closes the console (# to open it again)\n";
  101. msg += "help - Displays this listing\n";
  102. msg += "End of listing";
  103. break;
  104. case "cls":
  105. setTimeout(console.clear, 10);
  106. msg += "Clearing screen...";
  107. break;
  108. case "exit":
  109. case "quit":
  110. console.hide();
  111. break;
  112. default:
  113. msg += "Unknown command";
  114. }
  115. return msg;
  116. }
  117. */
  118. public function Console(inputHandler:Function) {
  119. // Initialize command history array
  120. commands = new Array();
  121. commands.push("");
  122. // Remember the handler function
  123. this.inputHandler = inputHandler;
  124. // Create the background
  125. background = new Sprite();
  126. background.graphics.beginFill(0x333333, 0.8);
  127. background.graphics.drawRect(0, 0, 200, 100);
  128. background.graphics.endFill();
  129. addChild(background);
  130. // Create the output
  131. output = new TextField();
  132. output.defaultTextFormat = new TextFormat("Lucida Console", "11", "0xEEEEEE");
  133. output.multiline = true;
  134. output.wordWrap = true;
  135. output.selectable = true;
  136. output.width = 200;
  137. output.height = 100;
  138. addChild(output);
  139. // Create the input
  140. input = new TextField();
  141. input.type = TextFieldType.INPUT;
  142. input.defaultTextFormat = new TextFormat("Lucida Console", "11");
  143. input.background = true;
  144. input.border = true;
  145. input.x = 3;
  146. input.width = 200;
  147. input.height = 16;
  148. addChild(input);
  149. // Event listener for final initialization (when added to stage)
  150. addEventListener(Event.ADDED_TO_STAGE, init);
  151. // Input handling
  152. input.addEventListener(KeyboardEvent.KEY_DOWN, handleInput);
  153. input.addEventListener(Event.CHANGE, handleInputChange);
  154. // Clear the screen
  155. clear();
  156. // Hide self initially
  157. hide();
  158. }
  159. private function handleInputChange(e:Event):void {
  160. commands[current] = input.text;
  161. }
  162. // ---------------------------------------------------------------------- //
  163. // Initialization
  164. // ---------------------------------------------------------------------- //
  165. /**
  166. * Finalizes initialisation of the console.
  167. *
  168. * @param e
  169. * unused.
  170. */
  171. private function init(e:Event):void {
  172. // Only fire once
  173. removeEventListener(Event.ADDED_TO_STAGE, init);
  174. // Add event listener, to resize the console if the stage is resized
  175. stage.addEventListener(Event.RESIZE, redraw);
  176. // Add an event listener for showing / hiding the console
  177. stage.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
  178. // Do a first redraw to set sizes and such
  179. redraw();
  180. }
  181. private function handleKeyDown(e:KeyboardEvent):void {
  182. if (e.charCode == _hotKey.charCodeAt() && !visible) {
  183. show();
  184. // Set focus with a slight delay, otherwise the hotkey will
  185. // be added to the input...
  186. oneShotTimer(focus, 10);
  187. } else if (e.keyCode == Keyboard.ESCAPE && visible) {
  188. hide();
  189. }
  190. }
  191. // ---------------------------------------------------------------------- //
  192. // Methods
  193. // ---------------------------------------------------------------------- //
  194. /**
  195. * Remove all messages from the display.
  196. */
  197. public function clear():void {
  198. output.text = "";
  199. writeln("Very Simple Console [Version 1.12]\n"
  200. + "(C) Copyright 2007-2009 Florian Nuecke.\n"
  201. + "\n"
  202. + "Type \"help\" for command listing.\n");
  203. }
  204. /**
  205. * Sets focus to the console's input.
  206. */
  207. public function focus():void {
  208. stage.focus = input;
  209. }
  210. /**
  211. * Handle keyboard events (key presses).
  212. *
  213. * @param e
  214. * used to get the pressed key.
  215. */
  216. private function handleInput(e:KeyboardEvent):void {
  217. if (e.keyCode == Keyboard.ENTER && input.text != "") {
  218. // Update the actual current entry and clear the input text
  219. commands[0] = input.text;
  220. input.text = "";
  221. // Call the input handler
  222. writeln("> " + commands[0] + "\n" + inputHandler(commands[0]));
  223. // Add a new empty entry (next command)
  224. commands.unshift("");
  225. current = 0;
  226. } else if (e.keyCode == Keyboard.UP) {
  227. // Backwards, increase and ensure limits, then override display
  228. current++;
  229. current = current < commands.length ? current
  230. : commands.length - 1;
  231. input.text = commands[current];
  232. } else if (e.keyCode == Keyboard.DOWN) {
  233. // Forwards, decrease and ensure limits, then override display
  234. current--;
  235. current = current < 0 ? 0 : current;
  236. input.text = commands[current];
  237. }
  238. }
  239. /**
  240. * Hide the console. Plain and simple for now...
  241. */
  242. public function hide():void {
  243. this.visible = false;
  244. input.text = "";
  245. }
  246. /**
  247. * Update sizes of the elements.
  248. *
  249. * @param e
  250. * unused.
  251. */
  252. private function redraw(e:Event = null):void {
  253. var newPos:Point = parent.globalToLocal(new Point(0, 0));
  254. x = newPos.x;
  255. y = newPos.y;
  256. background.width = stage.stageWidth;
  257. background.height = stage.stageHeight * 0.5;
  258. output.width = stage.stageWidth;
  259. output.height = stage.stageHeight * 0.5 - input.height - 8;
  260. input.width = stage.stageWidth - 7;
  261. input.y = output.height + 4;
  262. }
  263. /**
  264. * Show the console.
  265. */
  266. public function show():void {
  267. output.scrollV = output.maxScrollV;
  268. this.visible = true;
  269. }
  270. /**
  271. * Add a message to the console output.
  272. *
  273. * @param msg
  274. * the message to add.
  275. */
  276. public function write(... msg:Array):void {
  277. var p:Object;
  278. for each (var o:Object in msg) {
  279. if (p != null) {
  280. output.appendText(" ");
  281. }
  282. if (o != null) {
  283. output.appendText(String(o));
  284. }
  285. p = o;
  286. }
  287. output.scrollV = output.maxScrollV;
  288. }
  289. /**
  290. * Add a message to the console output and insert a new line at the end.
  291. *
  292. * @param msg
  293. * the message to add.
  294. */
  295. public function writeln(... msg:Array):void {
  296. var p:Object;
  297. for each (var o:Object in msg) {
  298. if (p != null) {
  299. output.appendText(" ");
  300. }
  301. if (o != null) {
  302. output.appendText(String(o));
  303. }
  304. p = o;
  305. }
  306. output.appendText("\n");
  307. output.scrollV = output.maxScrollV;
  308. }
  309. // ---------------------------------------------------------------------- //
  310. // Miscellaneous
  311. // ---------------------------------------------------------------------- //
  312. /**
  313. * Helper function, like setTimeout but using a <code>Timer</code>.
  314. *
  315. * @param calls
  316. * the function to call.
  317. * @param after
  318. * the delay in ms.
  319. */
  320. private function oneShotTimer(calls:Function, after:Number):void {
  321. var t:Timer = new Timer(after, 1);
  322. t.addEventListener(TimerEvent.TIMER, function(e:TimerEvent):void {
  323. calls();
  324. });
  325. t.start();
  326. }
  327. /**
  328. * Get some environment info.
  329. */
  330. public function sysinfo():String {
  331. var msg:String = "";
  332. if (stage != null) {
  333. msg += "Stage: ";
  334. msg += "width=" + stage.stageWidth;
  335. msg += "; height=" + stage.stageHeight;
  336. msg += "; framerate=" + stage.frameRate;
  337. msg += "\n";
  338. }
  339. msg += "Movie: ";
  340. msg += "asVersion=";
  341. try {
  342. msg += root.loaderInfo.actionScriptVersion;
  343. } catch (e:Error) {
  344. msg += "N/A";
  345. }
  346. msg += "; swfVersion=";
  347. try {
  348. msg += root.loaderInfo.swfVersion;
  349. } catch (e:Error) {
  350. msg += "N/A";
  351. }
  352. msg += "; url=" + stage.loaderInfo.url;
  353. msg += "\n";
  354. msg += "Memory Used: ";
  355. try {
  356. msg += System.totalMemory + " (~" + Math.round(System.totalMemory / 1024 / 1024) + "mb)";
  357. } catch (e:Error) {
  358. msg += "N/A";
  359. }
  360. msg += "\n";
  361. msg += "System: " + "os=" + Capabilities.os + "; language=" + Capabilities.language + "; codepage=" + (System.useCodePage != false ? System.useCodePage : "Unicode") + "; time=" + new Date().toString() + "; playerVersion=" + Capabilities.version + "; playerIsDebugger=" + Capabilities.isDebugger;
  362. return msg;
  363. }
  364. }
  365. } // end package