Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a custom trace() class in AS3

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.

like image 497
Daniel Magnusson Avatar asked Dec 06 '22 06:12

Daniel Magnusson


2 Answers

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

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.

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

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

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

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.

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

Hope this helps future tracers.

like image 108
Boris Avatar answered Dec 31 '22 08:12

Boris


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.

//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.

like image 30
Brian Hodge Avatar answered Dec 31 '22 06:12

Brian Hodge