Creating a custom trace() class in AS3

2019-03-30 19:31发布

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

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.

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.

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?

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

9条回答
Root(大扎)
2楼-- · 2019-03-30 20:11

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):

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.

查看更多
唯我独甜
3楼-- · 2019-03-30 20:17

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 ;)

function trace(... arguments){  
    yourfunction(arguments);
}
查看更多
女痞
4楼-- · 2019-03-30 20:19

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.

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

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.

Features:

  1. Calls built-in trace.
  2. Keeps a log of all your calls to Tracer.write as an array of strings.
  3. 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!
  4. 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.

-Tracer class definition

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

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 );
        }
    }
}
查看更多
登录 后发表回答