4

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

为什么

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

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

当我运行时,只有具有更高优先级的那个,在这种情况下为“1”,显示。

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

问题

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

在我们最喜欢的搜索引擎上查找有关此主题的信息时遇到一些严重问题,因此将不胜感激。

4

9 回答 9

5

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

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

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

这就是我所做的:在每节课上我都称之为

include "trace_implementation.as";

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

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

并且 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*/
    }
}

所以现在当我用“省略跟踪操作”编译时,我的整个调试都被忽略了,就像我简单地使用了 trace() 一样。

这里真正好的部分是您可以根据您在跟踪中提供的指令实施自定义操作,因此:

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

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

希望这有助于未来的示踪剂。

于 2009-08-23T16:46:23.720 回答
3

trace()它本身是一个顶级函数,而不是一个类,所以很遗憾我们不能扩展它。话虽如此,我们可以在一个简单的类中使用它来做它通常所做的事情,只有在这种情况下,跟踪是基于条件的(即布尔值 - 真|假等)。首先我们创建 Trace 类,我们不会自己实例化它,因为我们通过下面的类 Tracer 使用工厂设计模式。Tracer 是围绕单例设计模式构建的,当调用 Tracer 的 trace 方法时,它利用工厂模式来实例化 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
        }
    }
}

请记住,这是不切实际的,很可能有一两个错误,但想法就在那里;也就是说,这没有经过测试,只是为了让您了解如何实现它。

我希望这有帮助。

于 2009-04-03T22:41:45.730 回答
2

查看 Flex日志记录API,尤其是部分:使用日志记录 API 实现自定义记录器

也查一下TraceTarget班级。

于 2009-04-03T21:21:04.757 回答
2

你不能重写trace它自己,但为了便于输入,我喜欢创建一个名为 'tr' 的全局函数。一个鲜为人知的事实是您可以在 AS3 中创建全局函数,但这很容易。

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

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

如果您需要有很多逻辑或静态存储变量等,最好创建一个单独的静态类,并调用全局 tr 函数,例如:

package {
  import org.code.MyTracer;
  public function tr(msg:String, ...):void {
    MyTracer.tr(msg); // all the tracing logic is inside the MyTracer class
  }
}
于 2009-11-03T00:25:35.360 回答
1

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

公共静态函数 myTrace(... vars) :void {

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

}

于 2009-07-18T06:12:21.903 回答
1

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

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

于 2009-08-23T17:19:00.223 回答
1

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

下面是一个顶级“Tracer”类的示例,您可以在没有 import 语句的情况下使用它来代替 trace。

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

特征:

  1. 调用内置跟踪。
  2. 将您对 Tracer.write 的所有调用记录为字符串数组。
  3. 调用日志可通过 getText 作为字符串访问,它将数组中的所有元素与换行符连接起来,并且可以选择添加行号!
  4. 当新行添加到日志时触发事件,因此如果您有某种日志显示窗口,则显示窗口可以侦听 Tracer 事件,以便在事件发生时实时更新日志显示。这对于在 Web 浏览器或独立播放器中运行时显示跟踪事件非常有用。

-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 类定义

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 );
        }
    }
}
于 2010-12-15T19:11:35.143 回答
1

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

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

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

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

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

package {
    var logEnabled:Boolean = true;
}

主文件

package {

    import flash.display.MovieClip;

    public class Main extends MovieClip {

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

回复

Custom logging FTW!
Testing
Custom logging FTW!
于 2011-02-10T22:16:41.810 回答
0

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

function trace(... arguments){  
    yourfunction(arguments);
}
于 2011-02-03T18:01:46.283 回答