在AS3中创建自定义trace()类

时间:2022-09-24 22:51:33

I got this idea of expanding my trace() messages.

我有了扩展trace()消息的想法。

Why

trace() is all over my code, I want to turn them on/off by a simple command and maybe add some sort of priority functionality to the trace(), i.e.

trace()遍及我的代码,我想通过一个简单的命令打开/关闭它们,并且可能为trace()添加某种优先级功能,即

myTrace.TraceMsg("loosehere",debugme, 0);
myTrace.TraceMsg("winhere",debugme, 1);  

And when I run, only the one with the higher priority, "1" in this case, shows.

当我跑步时,只有优先级较高的那个,在这种情况下为“1”。

There is a lot more functionality I would like to add as well, like logging messages to file and so on.

我还想添加更多功能,比如将消息记录到文件等等。

Problem

How do trace() work? -Is it possible to overload trace() somehow? -How would I implement the custom TraceMsg(what code here?) method?

trace()如何工作? - 有可能以某种方式超载trace()吗? - 我如何实现自定义TraceMsg(这里有什么代码?)方法?

Having some serious problems finding info on this subject on our favourite search engine, so any help would be appreciated.

有一些严重的问题在我们最喜欢的搜索引擎上找到关于这个主题的信息,所以任何帮助将不胜感激。

9 个解决方案

#1


trace() itself is a top-level function, not a class, so unfortunately we cannot extend it. That being said, we can utilize it in a simple class to do just what it does normally, only in this case the trace is based on conditions (i.e. Boolean - true|false, etc). First we create the Trace class, which we wouldn't instantiate ourselves because we are utilizing a Factory design pattern through the class below, Tracer. Tracer is built around the singleton design pattern, yet utilizes the Factory pattern to instantiate instances of Trace, when the trace method of Tracer is called.

trace()本身是一个*函数,而不是一个类,所以很遗憾我们无法扩展它。话虽这么说,我们可以在一个简单的类中使用它来完成正常的操作,只有在这种情况下,跟踪基于条件(即布尔值 - 真|假等)。首先我们创建Trace类,我们不会自己实例化,因为我们通过下面的类,Tracer使用Factory设计模式。 Tracer是围绕单例设计模式构建的,但在调用Tracer的trace方法时,还使用Factory模式实例化Trace的实例。

//This class is handled by Tracer, which is right below it.
//You WILL NOT instantiate these, nor hold references.
package
{
    public class Trace
    {
        private function _value:*;
        private function _trace:Boolean;

        public function Trace(pValue:*, pTrace:Boolean):void
        {
          _value = pValue;
          _trace = pTrace;
        }
        public function get value():*
        {
           return _value;
        }
        public function get trace():Boolean
        {
           return _trace;
        }
    }
}
//This is the important class and the only one you will work with.
package
{
    /**
     *Utilizes Singleton and Factory design patterns.
     */
    public class Tracer
    {
        private var _traceArray:Array;
        private static var _instance:Tracer;

        public function Tracer(pvt:PrivateClass = null):void
        {
            if(pvt == null)
            {
                throw(new Error("You cannot instantiate this class directly, please use the static getInstance method."));
            }

            _init();
        }
        public static function getInstance():Tracer
        {
            if(Tracer._instance == null)
            {
                Tracer._instance = new Tracer(new PrivateClass());
            }
            return Tracer._instance;
        }
        public function trace(pValue:*, pTrace:Boolean):void
        {
           var trace:Trace = new Trace(pValue, pTrace);
           if(trace.pTrace)
           {
               trace(pValue);
           }
        }
        //Since we have the option for individual traces to be disabled
        //I provide this to get access to any and all later.
        public function traceAll():void
        {
            traceStr:String = _traceArray.toString();
        }
        public function get traceables():Array
        {
            return _traceArray;
        }
        //Here we provide a method to trace all, even if set to false in their constructor.
        private function _init():void
        {
            _traceArray = new Array();
        }
    }
}
//Here we create a class that is OUTSIDE of the package.
//It can only be accessed from within this class file.  We use this
//to make sure this class isn't instantiated directly.
class PrivateClass
{
    function PrivateClass():void
    {
        trace('can only be accessed from within this class file');
    }
}

//Now for use in doc class
package
{
    import flash.display.Sprite;
    import flash.events.Event;

    //No need to import Tracer and Trace, they are also in the
    //unnamed package.

    public class DocumentClass extends Sprite
    {
        private var _tracer:Tracer;

        public function DocumentClass():void
        {
            if(stage) _init();
            else addEventListener(Event.ADDED_TO_STAGE, _init);
        }
        private function _init(e:Event = null):void
        {
            _tracer = Tracer.getInstance();
            _tracer.trace(10*20, false);
            _tracer.trace(10*20, 0); //SAME AS ABOVE
            _tracer.trace("I love AS3", true); //traces
            _tracer.traceAll(); //Would trace: 200, 200, I love AS3
        }
    }
}

Keep in mind this is off the hip and very well could have a bug or two, but the idea is there; That is to say that this is not tested, it is merely to give you an idea of how you might implement this.

请记住,这是不合时宜的,很可能会有一两个错误,但这个想法是存在的;也就是说,这没有经过测试,只是为了让您了解如何实现这一点。

I hope this helps.

我希望这有帮助。

#2


I have come up with a rather efficient, yet tedious way of using my own trace() function in Flash only projects, but calling it simply with

我想出了一种在Flash专用项目中使用我自己的trace()函数的一种相当有效但又乏味的方法,但是只需用它来调用它

trace("this", "that", "and that too");

I basically implement one trace() method in every class of my project, that calls a public function (so that i can call the real trace() function from there.

我基本上在我的项目的每个类中实现一个trace()方法,它调用一个公共函数(这样我就可以从那里调用真正的trace()函数。

here is what I do : in every class I call this

这就是我所做的:在每个班级我称之为

include "trace_implementation.as";

in the .as file comes a simple method implementation (it could be a static method too).

在.as文件中有一个简单的方法实现(它也可以是一个静态方法)。

public function trace(... arguments){
    for(var i in arguments){
        myTrace(arguments[i]);
    }
}

and the myTrace function is defined in its own myTrace.as file

myTrace函数在其自己的myTrace.as文件中定义

package pt.utils{
    import flash.external.ExternalInterface

    public function myTrace(_s:String):void{
        trace(_s);// this will call the original flash trace() function
        ExternalInterface.call("console.log", _s);// to get traces outside of flash IDE
            /*implement what you want here*/
    }
}

so now when I compile with "omit trace actions", my whole debugging is ignored as if I used trace() simply.

所以现在当我用“省略跟踪动作”编译时,我的整个调试被忽略,好像我只是简单地使用了trace()。

the really good part here is that you could implement custom actions depending on instructions you give in the trace, so :

这里真正好的部分是你可以根据你在跟踪中给出的指令实现自定义操作,所以:

trace(Debug.DEBUG_MESSAGE, "message to output in debug");
trace(Profile.START_PROFILING, this, 'name');
/*do heavy code*/
trace(Profile.STOP_PROFILING, this);

then dispatch it from myTrace, or a Tracer class or anything :)

然后从myTrace或Tracer类或任何东西发送它:)

Hope this helps future tracers.

希望这有助于未来的追踪者。

#3


Look at the Flex logging API, particularly the section: Implementing a custom logger with the logging API.

查看Flex日志记录API,特别是以下部分:使用日志记录API实现自定义记录器。

Look up the TraceTarget class as well.

查找TraceTarget类。

#4


You can't override trace itself, but for ease of typing I like to create a global function called 'tr'. It's a little known fact that you can create global functions in AS3, but it's easy.

你不能覆盖跟踪本身,但为了便于输入,我喜欢创建一个名为'tr'的全局函数。一个鲜为人知的事实是你可以在AS3中创建全局函数,但它很容易。

Create a file called tr.as inside you main source directory (not in a subdirectory or package), with the contents:

在主源目录(不在子目录或包中)中创建一个名为tr.as的文件,其内容为:

package {
  public function tr(msg:String, ...):void {
    // add custom trace logic here
    trace("tr message: "+msg);
  }
}

If you need to have a lot of logic or static storage variables etc, it might be better to make a separate static class, and have the global tr function call out to that, such as:

如果你需要有很多逻辑或静态存储变量等,那么创建一个单独的静态类可能会更好,并且让全局tr函数调用它,例如:

package {
  import org.code.MyTracer;
  public function tr(msg:String, ...):void {
    MyTracer.tr(msg); // all the tracing logic is inside the MyTracer class
  }
}

#5


Here is a super simple custom trace function I use. debugFlag can be set to true/false elsewhere in the package.

这是我使用的超级简单的自定义跟踪功能。 debugFlag可以在包中的其他位置设置为true / false。

public static function myTrace(... vars) :void {

public static function myTrace(... vars):void {

if (debugFlag) {
    var output:Array = new Array;
    for each (var arg in vars) {
             output.push(arg);
     }
    trace(output);
} 

}

#6


In AS2, it was possible to override the global trace function by doing something like this (taken from memory, might be a bit wrong but the gist of it is there):

在AS2中,可以通过执行类似这样的操作来覆盖全局跟踪功能(从内存中取出,可能有点不对,但它的要点就在那里):

public static var realTrace:Function = _global["trace"];

// This is put in some init code somewhere
_global["trace"] = myTrace;

public static function myTrace(... args):void
{
    // Do whatever you want with args here, build a nice formatted string or whatever
    // before passing to realTrace. Using with MTASC one could add line numbers, class
    // names and all sorts of nice meta data. Or just return should you want to turn
    // tracing off.
    realTrace.apply(args);
}

Unfortunately I haven't found a way to do the same in AS3. Yet.

不幸的是,我还没有找到在AS3中做同样事情的方法。然而。

#7


Trace is a top-level function, so you can't override it, and as far as I know, it does not fire any events. Since it's a top-level function (not contained in any named package), you can use it without import statements.

Trace是一个*函数,所以你不能覆盖它,据我所知,它不会触发任何事件。由于它是*函数(未包含在任何命名包中),因此可以在没有import语句的情况下使用它。

Here is an example of a top-level "Tracer" class that you can use in place of trace without import statements.

下面是一个*“Tracer”类的示例,您可以使用它来代替没有import语句的跟踪。

Just call "Tracer.write" or "Tracer.writeError" for tracing Error objects. "Tracer.write" accepts a variable number of arguments, just like the built-in trace function. "Tracer.writeError" is a helper method that allows you to easily trace Error objects.

只需调用“Tracer.write”或“Tracer.writeError”来跟踪Error对象。 “Tracer.write”接受可变数量的参数,就像内置跟踪函数一样。 “Tracer.writeError”是一种帮助方法,可以让您轻松跟踪Error对象。

Features:

  1. Calls built-in trace.
  2. 调用内置跟踪。

  3. Keeps a log of all your calls to Tracer.write as an array of strings.
  4. 将所有对Tracer.write的调用记录为一个字符串数组。

  5. The call log is accessible as a string through getText, which joins all elements in the array with a newline character and will optionally tack on line numbers!
  6. 可以通过getText将调用日志作为字符串访问,该文件使用换行符连接数组中的所有元素,并可选择添加行号!

  7. Fires events when new lines are added to the log, so if you have some kind of display window for the log, the display window can listen for Tracer events to update the log display in real-time as the events occur. This is great for displaying trace events when running inside a web browser or stand-alone player.
  8. 将新行添加到日志时触发事件,因此如果您具有某种日志显示窗口,则显示窗口可以侦听Tracer事件,以便在事件发生时实时更新日志显示。这非常适合在Web浏览器或独立播放器中运行时显示跟踪事件。

-Tracer class definition

-Tracer类定义

package
{
    import flash.events.EventDispatcher;

    public class Tracer extends EventDispatcher
    {
        private static var traced_text:Array = new Array( "--Start of Trace Log--" );
        public static var enabled:Boolean = true;
        private static var suspended:Boolean = false;
        public static var instance:Tracer = new Tracer();
        public static const newline:String = "\n"; //workaround for TextField.appendText bug.. use "\n" instead of "\r".  See note and link to bug post in getText method

        public function Tracer()
        {
        }

        static public function write( ...args ):void
        {
            if (enabled && !suspended)
            {
                trace.apply( null, args );
                var text:String = args.join( newline );
                var next_index:int = traced_text.length;
                traced_text.push( text );
                suspended = true; //prevent recursive calls from TracerEvent handler
                instance.dispatchEvent( new TracerEvent( text, next_index ) );
                suspended = false;
            }
        }

        static public function writeError( e:Error ):void
        {
            write( "errorID: " + e.errorID, "errorName: " + e.name, "errorMessage: " + e.message, "stackTrace: " + e.getStackTrace() );
        }

        static public function getText( include_line_numbers:Boolean ):String
        {
            var line_count:int = traced_text.length;
            var lines:Array = traced_text; //store pointer to traced_text; pointer may be changed to reference an altered array that includes line numbers
            if (include_line_numbers) //create temporary trace log copy with altered lines; allows quick call to join at end
            {
                var new_lines:Array = new Array();
                for (var i:int = 0; i < line_count; i++)
                    new_lines.push( i.toString() + ": " + lines[i] );
                lines = new_lines;
            }
            return lines.join( newline ); //do not include last newline character (workaround for bug in appendText method (https://bugs.adobe.com/jira/browse/FP-1982); I have to call appendText with newline character first, otherwise it has issues like not acknoledging the newline thats already there at the end).
        }

        static public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void 
        {
             instance.addEventListener(type, listener, useCapture, priority, useWeakReference);
        }

        static public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void 
        {
            instance.removeEventListener(type, listener, useCapture);
        }

        static public function willTrigger(type:String):Boolean 
        {
            return instance.willTrigger(type);
        }

        static public function hasEventListener(type:String):Boolean 
        {
            return instance.hasEventListener(type);
        }
    }
}

-TracerEvent class definition

-TracerEvent类定义

package
{
    import flash.events.Event;

    public class TracerEvent extends Event
    {
        public static const WRITE:String = "te_write";

        public var text:String;
        public var index:int; //index of newly traced text in the traced_text array (trace log)

        public function TracerEvent( text:String, index:int ) 
        {
            super( WRITE, false, false );
            this.text = text;
            this.index = index;
        }

        override public function clone():Event 
        {
            return new TracerEvent( text, index );
        }
    }
}

#8


As mentioned below, there is no way to override trace (at least not if you want your traces to reach the output stream), but it's actually very easy to create your own universally accessable logging function. Plus, you can even define a universally accessable boolean to turn logging on or off:

如下所述,没有办法覆盖跟踪(至少不希望你的跟踪到达输出流),但实际上很容易创建自己的通用可访问日志记录功能。此外,您甚至可以定义一个普遍可访问的布尔值来打开或关闭日志记录:

log.as (note that the filename must reflect the name of the function)

log.as(注意文件名必须反映函数的名称)

package {
    function log(... arguments):void {

        trace("Custom logging FTW!");
        if (logEnabled)
            trace(arguments);
    }
}

logEnabled.as (note that the filename must reflect the name of the variable)

logEnabled.as(注意文件名必须反映变量的名称)

package {
    var logEnabled:Boolean = true;
}

Main.as

package {

    import flash.display.MovieClip;

    public class Main extends MovieClip {

        public function Main() {
            log("Testing");
            logEnabled = false;
            log("Testing2");
        }
    }
}

Response

Custom logging FTW!
Testing
Custom logging FTW!

#9


you dont need to override it , just create a function in your project and call it trace then any trace call will point to this.trace ;)

你不需要覆盖它,只需在项目中创建一个函数并调用它跟踪,然后任何跟踪调用将指向this.trace;)

function trace(... arguments){  
    yourfunction(arguments);
}

#1


trace() itself is a top-level function, not a class, so unfortunately we cannot extend it. That being said, we can utilize it in a simple class to do just what it does normally, only in this case the trace is based on conditions (i.e. Boolean - true|false, etc). First we create the Trace class, which we wouldn't instantiate ourselves because we are utilizing a Factory design pattern through the class below, Tracer. Tracer is built around the singleton design pattern, yet utilizes the Factory pattern to instantiate instances of Trace, when the trace method of Tracer is called.

trace()本身是一个*函数,而不是一个类,所以很遗憾我们无法扩展它。话虽这么说,我们可以在一个简单的类中使用它来完成正常的操作,只有在这种情况下,跟踪基于条件(即布尔值 - 真|假等)。首先我们创建Trace类,我们不会自己实例化,因为我们通过下面的类,Tracer使用Factory设计模式。 Tracer是围绕单例设计模式构建的,但在调用Tracer的trace方法时,还使用Factory模式实例化Trace的实例。

//This class is handled by Tracer, which is right below it.
//You WILL NOT instantiate these, nor hold references.
package
{
    public class Trace
    {
        private function _value:*;
        private function _trace:Boolean;

        public function Trace(pValue:*, pTrace:Boolean):void
        {
          _value = pValue;
          _trace = pTrace;
        }
        public function get value():*
        {
           return _value;
        }
        public function get trace():Boolean
        {
           return _trace;
        }
    }
}
//This is the important class and the only one you will work with.
package
{
    /**
     *Utilizes Singleton and Factory design patterns.
     */
    public class Tracer
    {
        private var _traceArray:Array;
        private static var _instance:Tracer;

        public function Tracer(pvt:PrivateClass = null):void
        {
            if(pvt == null)
            {
                throw(new Error("You cannot instantiate this class directly, please use the static getInstance method."));
            }

            _init();
        }
        public static function getInstance():Tracer
        {
            if(Tracer._instance == null)
            {
                Tracer._instance = new Tracer(new PrivateClass());
            }
            return Tracer._instance;
        }
        public function trace(pValue:*, pTrace:Boolean):void
        {
           var trace:Trace = new Trace(pValue, pTrace);
           if(trace.pTrace)
           {
               trace(pValue);
           }
        }
        //Since we have the option for individual traces to be disabled
        //I provide this to get access to any and all later.
        public function traceAll():void
        {
            traceStr:String = _traceArray.toString();
        }
        public function get traceables():Array
        {
            return _traceArray;
        }
        //Here we provide a method to trace all, even if set to false in their constructor.
        private function _init():void
        {
            _traceArray = new Array();
        }
    }
}
//Here we create a class that is OUTSIDE of the package.
//It can only be accessed from within this class file.  We use this
//to make sure this class isn't instantiated directly.
class PrivateClass
{
    function PrivateClass():void
    {
        trace('can only be accessed from within this class file');
    }
}

//Now for use in doc class
package
{
    import flash.display.Sprite;
    import flash.events.Event;

    //No need to import Tracer and Trace, they are also in the
    //unnamed package.

    public class DocumentClass extends Sprite
    {
        private var _tracer:Tracer;

        public function DocumentClass():void
        {
            if(stage) _init();
            else addEventListener(Event.ADDED_TO_STAGE, _init);
        }
        private function _init(e:Event = null):void
        {
            _tracer = Tracer.getInstance();
            _tracer.trace(10*20, false);
            _tracer.trace(10*20, 0); //SAME AS ABOVE
            _tracer.trace("I love AS3", true); //traces
            _tracer.traceAll(); //Would trace: 200, 200, I love AS3
        }
    }
}

Keep in mind this is off the hip and very well could have a bug or two, but the idea is there; That is to say that this is not tested, it is merely to give you an idea of how you might implement this.

请记住,这是不合时宜的,很可能会有一两个错误,但这个想法是存在的;也就是说,这没有经过测试,只是为了让您了解如何实现这一点。

I hope this helps.

我希望这有帮助。

#2


I have come up with a rather efficient, yet tedious way of using my own trace() function in Flash only projects, but calling it simply with

我想出了一种在Flash专用项目中使用我自己的trace()函数的一种相当有效但又乏味的方法,但是只需用它来调用它

trace("this", "that", "and that too");

I basically implement one trace() method in every class of my project, that calls a public function (so that i can call the real trace() function from there.

我基本上在我的项目的每个类中实现一个trace()方法,它调用一个公共函数(这样我就可以从那里调用真正的trace()函数。

here is what I do : in every class I call this

这就是我所做的:在每个班级我称之为

include "trace_implementation.as";

in the .as file comes a simple method implementation (it could be a static method too).

在.as文件中有一个简单的方法实现(它也可以是一个静态方法)。

public function trace(... arguments){
    for(var i in arguments){
        myTrace(arguments[i]);
    }
}

and the myTrace function is defined in its own myTrace.as file

myTrace函数在其自己的myTrace.as文件中定义

package pt.utils{
    import flash.external.ExternalInterface

    public function myTrace(_s:String):void{
        trace(_s);// this will call the original flash trace() function
        ExternalInterface.call("console.log", _s);// to get traces outside of flash IDE
            /*implement what you want here*/
    }
}

so now when I compile with "omit trace actions", my whole debugging is ignored as if I used trace() simply.

所以现在当我用“省略跟踪动作”编译时,我的整个调试被忽略,好像我只是简单地使用了trace()。

the really good part here is that you could implement custom actions depending on instructions you give in the trace, so :

这里真正好的部分是你可以根据你在跟踪中给出的指令实现自定义操作,所以:

trace(Debug.DEBUG_MESSAGE, "message to output in debug");
trace(Profile.START_PROFILING, this, 'name');
/*do heavy code*/
trace(Profile.STOP_PROFILING, this);

then dispatch it from myTrace, or a Tracer class or anything :)

然后从myTrace或Tracer类或任何东西发送它:)

Hope this helps future tracers.

希望这有助于未来的追踪者。

#3


Look at the Flex logging API, particularly the section: Implementing a custom logger with the logging API.

查看Flex日志记录API,特别是以下部分:使用日志记录API实现自定义记录器。

Look up the TraceTarget class as well.

查找TraceTarget类。

#4


You can't override trace itself, but for ease of typing I like to create a global function called 'tr'. It's a little known fact that you can create global functions in AS3, but it's easy.

你不能覆盖跟踪本身,但为了便于输入,我喜欢创建一个名为'tr'的全局函数。一个鲜为人知的事实是你可以在AS3中创建全局函数,但它很容易。

Create a file called tr.as inside you main source directory (not in a subdirectory or package), with the contents:

在主源目录(不在子目录或包中)中创建一个名为tr.as的文件,其内容为:

package {
  public function tr(msg:String, ...):void {
    // add custom trace logic here
    trace("tr message: "+msg);
  }
}

If you need to have a lot of logic or static storage variables etc, it might be better to make a separate static class, and have the global tr function call out to that, such as:

如果你需要有很多逻辑或静态存储变量等,那么创建一个单独的静态类可能会更好,并且让全局tr函数调用它,例如:

package {
  import org.code.MyTracer;
  public function tr(msg:String, ...):void {
    MyTracer.tr(msg); // all the tracing logic is inside the MyTracer class
  }
}

#5


Here is a super simple custom trace function I use. debugFlag can be set to true/false elsewhere in the package.

这是我使用的超级简单的自定义跟踪功能。 debugFlag可以在包中的其他位置设置为true / false。

public static function myTrace(... vars) :void {

public static function myTrace(... vars):void {

if (debugFlag) {
    var output:Array = new Array;
    for each (var arg in vars) {
             output.push(arg);
     }
    trace(output);
} 

}

#6


In AS2, it was possible to override the global trace function by doing something like this (taken from memory, might be a bit wrong but the gist of it is there):

在AS2中,可以通过执行类似这样的操作来覆盖全局跟踪功能(从内存中取出,可能有点不对,但它的要点就在那里):

public static var realTrace:Function = _global["trace"];

// This is put in some init code somewhere
_global["trace"] = myTrace;

public static function myTrace(... args):void
{
    // Do whatever you want with args here, build a nice formatted string or whatever
    // before passing to realTrace. Using with MTASC one could add line numbers, class
    // names and all sorts of nice meta data. Or just return should you want to turn
    // tracing off.
    realTrace.apply(args);
}

Unfortunately I haven't found a way to do the same in AS3. Yet.

不幸的是,我还没有找到在AS3中做同样事情的方法。然而。

#7


Trace is a top-level function, so you can't override it, and as far as I know, it does not fire any events. Since it's a top-level function (not contained in any named package), you can use it without import statements.

Trace是一个*函数,所以你不能覆盖它,据我所知,它不会触发任何事件。由于它是*函数(未包含在任何命名包中),因此可以在没有import语句的情况下使用它。

Here is an example of a top-level "Tracer" class that you can use in place of trace without import statements.

下面是一个*“Tracer”类的示例,您可以使用它来代替没有import语句的跟踪。

Just call "Tracer.write" or "Tracer.writeError" for tracing Error objects. "Tracer.write" accepts a variable number of arguments, just like the built-in trace function. "Tracer.writeError" is a helper method that allows you to easily trace Error objects.

只需调用“Tracer.write”或“Tracer.writeError”来跟踪Error对象。 “Tracer.write”接受可变数量的参数,就像内置跟踪函数一样。 “Tracer.writeError”是一种帮助方法,可以让您轻松跟踪Error对象。

Features:

  1. Calls built-in trace.
  2. 调用内置跟踪。

  3. Keeps a log of all your calls to Tracer.write as an array of strings.
  4. 将所有对Tracer.write的调用记录为一个字符串数组。

  5. The call log is accessible as a string through getText, which joins all elements in the array with a newline character and will optionally tack on line numbers!
  6. 可以通过getText将调用日志作为字符串访问,该文件使用换行符连接数组中的所有元素,并可选择添加行号!

  7. Fires events when new lines are added to the log, so if you have some kind of display window for the log, the display window can listen for Tracer events to update the log display in real-time as the events occur. This is great for displaying trace events when running inside a web browser or stand-alone player.
  8. 将新行添加到日志时触发事件,因此如果您具有某种日志显示窗口,则显示窗口可以侦听Tracer事件,以便在事件发生时实时更新日志显示。这非常适合在Web浏览器或独立播放器中运行时显示跟踪事件。

-Tracer class definition

-Tracer类定义

package
{
    import flash.events.EventDispatcher;

    public class Tracer extends EventDispatcher
    {
        private static var traced_text:Array = new Array( "--Start of Trace Log--" );
        public static var enabled:Boolean = true;
        private static var suspended:Boolean = false;
        public static var instance:Tracer = new Tracer();
        public static const newline:String = "\n"; //workaround for TextField.appendText bug.. use "\n" instead of "\r".  See note and link to bug post in getText method

        public function Tracer()
        {
        }

        static public function write( ...args ):void
        {
            if (enabled && !suspended)
            {
                trace.apply( null, args );
                var text:String = args.join( newline );
                var next_index:int = traced_text.length;
                traced_text.push( text );
                suspended = true; //prevent recursive calls from TracerEvent handler
                instance.dispatchEvent( new TracerEvent( text, next_index ) );
                suspended = false;
            }
        }

        static public function writeError( e:Error ):void
        {
            write( "errorID: " + e.errorID, "errorName: " + e.name, "errorMessage: " + e.message, "stackTrace: " + e.getStackTrace() );
        }

        static public function getText( include_line_numbers:Boolean ):String
        {
            var line_count:int = traced_text.length;
            var lines:Array = traced_text; //store pointer to traced_text; pointer may be changed to reference an altered array that includes line numbers
            if (include_line_numbers) //create temporary trace log copy with altered lines; allows quick call to join at end
            {
                var new_lines:Array = new Array();
                for (var i:int = 0; i < line_count; i++)
                    new_lines.push( i.toString() + ": " + lines[i] );
                lines = new_lines;
            }
            return lines.join( newline ); //do not include last newline character (workaround for bug in appendText method (https://bugs.adobe.com/jira/browse/FP-1982); I have to call appendText with newline character first, otherwise it has issues like not acknoledging the newline thats already there at the end).
        }

        static public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void 
        {
             instance.addEventListener(type, listener, useCapture, priority, useWeakReference);
        }

        static public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void 
        {
            instance.removeEventListener(type, listener, useCapture);
        }

        static public function willTrigger(type:String):Boolean 
        {
            return instance.willTrigger(type);
        }

        static public function hasEventListener(type:String):Boolean 
        {
            return instance.hasEventListener(type);
        }
    }
}

-TracerEvent class definition

-TracerEvent类定义

package
{
    import flash.events.Event;

    public class TracerEvent extends Event
    {
        public static const WRITE:String = "te_write";

        public var text:String;
        public var index:int; //index of newly traced text in the traced_text array (trace log)

        public function TracerEvent( text:String, index:int ) 
        {
            super( WRITE, false, false );
            this.text = text;
            this.index = index;
        }

        override public function clone():Event 
        {
            return new TracerEvent( text, index );
        }
    }
}

#8


As mentioned below, there is no way to override trace (at least not if you want your traces to reach the output stream), but it's actually very easy to create your own universally accessable logging function. Plus, you can even define a universally accessable boolean to turn logging on or off:

如下所述,没有办法覆盖跟踪(至少不希望你的跟踪到达输出流),但实际上很容易创建自己的通用可访问日志记录功能。此外,您甚至可以定义一个普遍可访问的布尔值来打开或关闭日志记录:

log.as (note that the filename must reflect the name of the function)

log.as(注意文件名必须反映函数的名称)

package {
    function log(... arguments):void {

        trace("Custom logging FTW!");
        if (logEnabled)
            trace(arguments);
    }
}

logEnabled.as (note that the filename must reflect the name of the variable)

logEnabled.as(注意文件名必须反映变量的名称)

package {
    var logEnabled:Boolean = true;
}

Main.as

package {

    import flash.display.MovieClip;

    public class Main extends MovieClip {

        public function Main() {
            log("Testing");
            logEnabled = false;
            log("Testing2");
        }
    }
}

Response

Custom logging FTW!
Testing
Custom logging FTW!

#9


you dont need to override it , just create a function in your project and call it trace then any trace call will point to this.trace ;)

你不需要覆盖它,只需在项目中创建一个函数并调用它跟踪,然后任何跟踪调用将指向this.trace;)

function trace(... arguments){  
    yourfunction(arguments);
}