| Ultrashock Forums
• AS3 - Can you. trace a line # |
|||
![]() |
||||
| Search this Thread | Thread Tools | Display Modes |
|
|
|||||||||||||||||||||||||
![]() |
Ultrashock Member Comments:
|
2008-03-13
#2 |
||
|
Anyone know?
|
|
13 Creative Assets
|
2008-03-13
#3 |
||
|
That isn't possible in AS3 as far as I know. You shouldn't need that though if you use the debugger in Flash or Flex, both of those should show you any code that throws runtime errors.
|
|
|
2008-03-13
#4 |
||
|
Reason I ask, is because when I am writing m code and I get nto race conditions I like to make traces something like this. trace("line 136 " + variableName); than some where else would trace line 146 or whatever, just t make sure that my code s running in he order want t to run. I know php _line_ has helped me a lot. even tough it undercounts he lines by one. But thanks for your reply. |
|
|
|
2008-08-06
#5 |
||
|
Yes you can..
Last edited by suki_babee : 2008-08-21 at 09:21.
UPDATED: all you need to do is: var e:Error = new Error(); var s:String = e.getStackTrace(); trace(s); this only works with the debug flash player (s=null otherwise). It gives you a stack trace with line numbers (line numbers only if you have "Permit Debugging" enabled when your SWF is published). I wrote a class to do this elegantly and I added a bunch more features. 3 ways to use it: Trace.log(5, "this is a trace point"); // basic trace point Trace.codetrace(5, "how did this get called"); // more interesting called within a stack Trace.print_r(5, "this is my obj", obj); // traces out contents of obj or array (only public elements if instance) And you can turn the trace off when you want better performance for a published swf: Trace.set_trace_type(Trace.TYPE_NONE); Sample output. I prefix with "fa!" ('fa' for FlickAway.com - but you can change that) followed by level (1 char), followed by timestamp (min:sec:milli) [caller] <msg>. The prefix is so I can filter out other swf tracing from mine when testing in Firefox + FlashTrace: Code:
fa!5 49:19:375 [Image/load():38] this is a trace point fa!5 49:19:375 [Image/load():43] how did this get called? fa!5 +--[Image():28] fa!5 +--[HomePageImage():23] fa!5 +--[HomeDefault():67] fa!5 21:59:750 [FileInfo():39] this is my obj (print_r) com.flickaway::FileInfo => fa!5 [fver]:int => 0 fa!5 [caption]:String => "" fa!5 [fidp]:String => "0/0/7/a1_373lrkz9z" com/flickaway/Trace.as: Code:
/**
* This provides full, quick and no tracing capabilities (as much as ActionScript allows) via the exception
* mechanism, which I imagine could impede performance. It provides caller information.
*
* Use: set_trace_type with TYPE_NONE, TYPE_QUICK and TYPE_FULL + TYPE_REMOTE (new - to test with non-debug flash player)
*
* @author Glen
* @copyright 2006 flickaway.com
* @version $Id: Trace.as 1710 2008-08-21 16:51:03Z glen $
*/
package com.flickaway
{
import flash.events.StatusEvent;
import flash.net.LocalConnection;
import flash.utils.describeType;
public class Trace
{
static public const TYPE_NONE :uint = 0; // To turn off tracing (for production) and save cycles
static public const TYPE_QUICK :uint = 1; // To avoid generating and parsing stacktrace + using trace() for output
static public const TYPE_FULL :uint = 2; // The norm - Full tracing + using trace() for output
static public const TYPE_REMOTE :uint = 3; // Full tracing, but sending it to another swf via LocalConnection
static private var my_type:uint = TYPE_FULL; // defaults to FULL
static private var conn:LocalConnection;
static private var lc_name:String = '_flickaway_trace'; // Local connection name
static private var lc_func:String = 'log'; // Local connection function
static public function set_trace_type(type:uint):void
{
Trace.my_type = type;
if (type == Trace.TYPE_REMOTE)
{
Trace.conn = new LocalConnection();
Trace.conn.addEventListener(StatusEvent.STATUS, Trace.on_status_handler);
}
}
static public function on_status_handler(event:StatusEvent):void
{
switch (event.level)
{
case "status" : break; // succeeded
case "error" : trace("FA Trace: LocalConnection to " + Trace.lc_name + ":" + Trace.lc_func + " failed."); break;
}
}
static public function log(level:uint, msg:String):void
{
switch (Trace.my_type)
{
case TYPE_NONE: return;
case TYPE_FULL: // conditional logic inside
case TYPE_REMOTE: Trace.log_full(level, msg); break; // dito
case TYPE_QUICK: Trace.log_quick(level, msg); break;
default:
throw new Error("Cannot handle trace type of " + Trace.my_type);
}
}
static public function error(level:uint, msg:String):void
{
switch (Trace.my_type)
{
case TYPE_NONE: Trace.log_full(level, msg); break; // on production systems, we want to see these still
case TYPE_FULL: // conditional logic inside
case TYPE_REMOTE: Trace.log_full(level, msg); throw new Error(msg); break; // Log AND throw an exception
case TYPE_QUICK: Trace.log_full(level, msg); throw new Error(msg); break; // Log AND throw an exception
default:
throw new Error("Cannot handle trace type of " + Trace.my_type);
}
}
static public function codetrace(level:uint, msg:String):void
{
switch (Trace.my_type)
{
case TYPE_NONE: return;
case TYPE_FULL: // conditional logic inside
case TYPE_REMOTE: Trace.codetrace_full(level, msg); break; // dito
case TYPE_QUICK: Trace.log_quick(level, msg); break; // in quick mode - we cannot do the codetrace
default:
throw new Error("Cannot handle trace type of " + Trace.my_type);
}
}
static public function print_r(level:uint, msg:String, obj:*):void
{
switch (Trace.my_type)
{
case TYPE_NONE: return;
case TYPE_FULL: // conditional logic inside
case TYPE_REMOTE: Trace.print_r_full(level, msg, obj); break; // dito
case TYPE_QUICK: Trace.print_r_quick(level, msg, obj); break;
default:
throw new Error("Cannot handle trace type of " + Trace.my_type);
}
}
//==================================================================================================================================
//
// QUICK TRACE
//
//==================================================================================================================================
static private function log_quick(level:uint, line:String):void
{
var d:Date = new Date();
var m = d.getMinutes();
var s = d.getSeconds();
var ms = d.getMilliseconds();
Trace.write("fa!" + level + "-" + (m>=10?m:'0'+m) + ":" + (s>=10?s:'0'+s) + ":" + (ms>=100?ms:(ms>=10?'0'+ms:'00'+ms)) + " " + line);
}
static private function print_r_quick(level:uint, msg:String, obj:*):void
{
Trace.log(level, msg + " (print_r of <?something?>)");
}
//==================================================================================================================================
//
// FULL TRACE
//
//==================================================================================================================================
static private function log_full(level:uint, msg:String, snum:uint=3):void
{
// FROM:
// http://snippets.dzone.com/posts/show/3703
//----------------------------------------------------------------------------------------------------------------
// With debugging turned on, this is what we get:
//
// Error
// <tab>at com.flickaway::Trace$/log_full()[D:\web\flickaway_branch\flash\lib\com\flickaway\Trace.as:83]
// <tab>at com.flickaway::Trace$/print_r_full()[D:\web\flickaway_branch\flash\lib\com\flickaway\Trace.as:114]
// <tab>at com.flickaway::Trace$/print_r()[D:\web\flickaway_branch\flash\lib\com\flickaway\Trace.as:46]
// <tab>at com.flickaway::Params()[D:\web\flickaway_branch\flash\lib\com\flickaway\Params.as:36] <==== this line we want
// <tab>at com.flickaway::Params$/get_instance()[D:\web\flickaway_branch\flash\lib\com\flickaway\Params.as:27]
// <tab>at HomeDefault()[D:\web\flickaway_branch\flash\homepage\HomeDefault.as:57]
// <tab>at com.flickaway::Params()[D:\web\flickaway_branch\flash\lib\com\flickaway\Params.as:36])
//
// with debugging turned off:
//
// Error
// <tab>at com.flickaway::Trace$/log_full()
// <tab>at com.flickaway::Trace$/print_r_full()
// <tab>at com.flickaway::Trace$/print_r()
// <tab>at com.flickaway::Params()
// <tab>at com.flickaway::Params$/get_instance()
// <tab>at HomeDefault()
//----------------------------------------------------------------------------------------------------------------
var e = new Error();
var str:String = e.getStackTrace(); // get the full text str
//Trace.write("str.length=" + str);
if (str == null) // means we aren't on the Debug player
{
Trace.log_it(level, "(!debug) " + msg);
}
else
{
var stacks:Array = str.split("\n"); // split into each line
var caller:String = Trace.gimme_caller(stacks[snum]); // get the caller for just one specific line in the stack trace
Trace.log_it(level, caller + " " + msg);
}
}
static private function codetrace_full(level:uint, msg:String, snum:uint=3):void
{
var e:Error = new Error();
//----------------------------------------------------------------------------------------------------------------
// This is just like log_full() - except we print out all lines in the stack, starting at snum
//----------------------------------------------------------------------------------------------------------------
var str:String = e.getStackTrace(); // get the full text str
if (str == null) // means we aren't on the Debug player
{
Trace.log_it(level, "no_debug " + msg);
}
else
{
var stacks:Array = str.split("\n"); // split into each line
var caller:String = Trace.gimme_caller(stacks[snum]); // get the caller info for just one specific line in the stack trace
Trace.log_it(level, caller + " " + msg);
if (snum < stacks.length) // this means there's more in the stack to print out
{
for (var i = snum+1; i < stacks.length; i++)
{
caller = Trace.gimme_caller(stacks[i]);
Trace.write("fa!" + level + " +--" + caller);
}
}
}
}
/**
* Returns a string like "[HomeDefault():51]" - line number present only if "permit debugging" is turned on.
*/
static private function gimme_caller(line:String):String
{
//-------------------------------------------------------------------------------------------------
// the line can look like any of these (so we must be able to clean up all of them):
//
// <tab>at com.flickaway::Params()
// <tab>at com.flickaway::Params()[D:\web\flickaway_branch\flash\lib\com\flickaway\Params.as:36]
// <tab>at HomeDefault()
// <tab>at HomeDefault()[D:\web\flickaway_branch\flash\homepage\HomeDefault.as:57]
//-------------------------------------------------------------------------------------------------
var dom_pos:int = line.indexOf("::"); // find the '::' part
var caller:String;
if (dom_pos == -1)
{
caller = line.substr(4); // just remove '<tab>at ' beginning part (4 characters)
}
else
{
caller = line.substr(dom_pos+2); // remove '<tab>at com.flickaway::' beginning part
}
var lb_pos:int = caller.indexOf("["); // get position of the left bracket (lb)
if (lb_pos == -1) // if the lb doesn't exist (then we don't have "permit debugging" turned on)
{
return "[" + caller + "]";
}
else
{
var line_num:String = caller.substr(caller.lastIndexOf(":")); // find the line number
caller = caller.substr(0, lb_pos); // cut it out - it'll look like ":51]"
return "[" + caller + line_num; // line_num already has the trailing right bracket
}
}
static private function print_r_full(level:uint, msg:String, obj:*):void
{
Trace.log_full(level, msg + " (print_r) " + Trace.pr(level, obj), 4);
}
// FROM:
// http://blogs.grf-design.com/archives/2007/07/actionscript_3.html
static private function pr(level:uint, o:*, name:String = "", recur:int = 0):String
{
var result:String = "";
var type:String = typeof(o);
var desc:XML = describeType(o);
if (type == "function")
{
return result;
}
// meta data of object
if (recur != 0)
{
result += "\nfa!" + level + " ";
for (var i:int = 0; i < recur; ++i)
{
result += " ";
}
}
if (name)
{
result += '[' + name + ']:';
}
result += desc.@name + ' => ';
// content of object
switch (type)
{
case "boolean":
case "number":
result += String(o);
break;
case "string":
result += '"' + String(o) + '"';
break;
case "xml":
result += o.toXMLString();
break; 0
case "object":
if (desc.@name == "Object" || desc.@name == "Array")
{
for (var key:String in o)
{
//result += "\n";
result += pr(level, o[key], key, (recur + 1));
}
}
else
{
var prop:XML;
// -- properties
for each (prop in desc.variable)
{
result += pr(level, o[prop.@name], prop.@name, (recur + 1));
}
// -- methods
for each (prop in desc.method)
{
result += pr(level, o[prop.@name], prop.@name, (recur + 1));
}
}
break;
case "function": // I dont want to print out functions
result += String(o);
break;
default:
Trace.write("ERROR: not handling type: " + type);
}
return result;
}
static private function log_it(level:uint, line:String):void
{
var d:Date = new Date();
var m = d.getMinutes();
var s = d.getSeconds();
var ms = d.getMilliseconds();
Trace.write("fa!" + level + " " + (m>=10?m:'0' + m) + ":" + (s>=10?s:'0' + s) + ":" + (ms>=100?ms:(ms>=10?'0' + ms:'00' + ms)) + " " + line);
}
static private function write(str:String):void
{
if (Trace.my_type == Trace.TYPE_REMOTE)
{
Trace.conn.send(Trace.lc_name, Trace.lc_func, str);
}
else
{
trace(str);
}
}
}
}
|
|
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|


4 comments
| 1507 views



13 Creative Assets
Linear Mode