package org.andengine.util.debug; import java.util.ArrayList; import java.util.Arrays; import java.util.Stack; import org.andengine.util.debug.Debug.DebugLevel; /** * (c) Zynga 2011 * * @author Nicolas Gramlich <ngramlich@zynga.com> * @since 13:52:42 - 02.11.2011 */ public class DebugTimer { // =========================================================== // Constants // =========================================================== private static final String SPLIT_STRING = " Split: "; private static final int INDENT_SPACES = SPLIT_STRING.length(); // =========================================================== // Fields // =========================================================== private final Stack<DebugTime> mDebugTimes = new Stack<DebugTime>(); private final DebugLevel mDebugLevel; // =========================================================== // Constructors // =========================================================== public DebugTimer(final String pLabel) { this(DebugLevel.DEBUG, pLabel); } public DebugTimer(final DebugLevel pDebugLevel, final String pLabel) { this.mDebugLevel = pDebugLevel; this.init(pLabel); } // =========================================================== // Getter & Setter // =========================================================== // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== // =========================================================== // Methods // =========================================================== private void init(final String pLabel) { final long now = System.currentTimeMillis(); final DebugTime debugTime = new DebugTime(now, pLabel); this.mDebugTimes.add(debugTime); } public void begin(final String pLabel) { final long now = System.currentTimeMillis(); final DebugTime debugTime = new DebugTime(now, pLabel); this.mDebugTimes.peek().begin(debugTime); this.mDebugTimes.add(debugTime); } public void split(final String pLabel) { this.mDebugTimes.peek().split(pLabel); } public void end() { final long now = System.currentTimeMillis(); if(this.mDebugTimes.size() == 1) { throw new IllegalStateException("Cannot end the root of this " + this.getClass().getSimpleName()); } else { this.mDebugTimes.pop().end(now); } } public void dump() { this.dump(false); } public void dump(final boolean pClear) { final long now = System.currentTimeMillis(); if(this.mDebugTimes.size() > 1) { Debug.w(this.getClass().getSimpleName() + " not all ended!"); } final DebugTime root = this.mDebugTimes.firstElement(); root.end(now); root.dump(0); if(pClear) { this.clear(); } } public void clear() { final DebugTime root = this.mDebugTimes.firstElement(); this.mDebugTimes.clear(); this.init(root.mLabel); } // =========================================================== // Inner and Anonymous Classes // =========================================================== public class DebugTime { // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== private final long mStartTime; private final String mLabel; private final boolean mSplit; private long mEndTime; private ArrayList<DebugTime> mChildren; private DebugTime mLastSplit; // =========================================================== // Constructors // =========================================================== public DebugTime(final long pStartTime, final String pLabel) { this(pStartTime, pLabel, false); } protected DebugTime(final long pStartTime, final String pLabel, final boolean pSplit) { this.mStartTime = pStartTime; this.mLabel = pLabel; this.mSplit = pSplit; } // =========================================================== // Getter & Setter // =========================================================== // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== // =========================================================== // Methods // =========================================================== public void begin(final DebugTime pDebugTime) { this.ensureChildrenAllocated(); this.mChildren.add(pDebugTime); } public void split(final String pLabel) { final long now = System.currentTimeMillis(); final DebugTime split; if(this.mLastSplit == null) { split = new DebugTime(this.mStartTime, pLabel, true); } else { split = new DebugTime(this.mLastSplit.mEndTime, pLabel, true); } split.end(now); this.ensureChildrenAllocated(); this.mChildren.add(split); this.mLastSplit = split; } public void end(final long pEndTime) { this.mEndTime = pEndTime; } public void dump(final int pIndent) { this.dump(pIndent, ""); } public void dump(final int pIndent, final String pPostfix) { if(this.mSplit) { final char[] indent = new char[(pIndent - 1) * INDENT_SPACES]; Arrays.fill(indent, ' '); Debug.log(DebugTimer.this.mDebugLevel, new String(indent) + SPLIT_STRING + "'" + this.mLabel + "'" + " @( " + (this.mEndTime - this.mStartTime) + "ms )" + pPostfix); } else { final char[] indent = new char[pIndent * INDENT_SPACES]; Arrays.fill(indent, ' '); if(this.mChildren == null) { Debug.log(DebugTimer.this.mDebugLevel, new String(indent) + "'" + this.mLabel + "' @( " + (this.mEndTime - this.mStartTime) + "ms )" + pPostfix); } else { final ArrayList<DebugTime> children = this.mChildren; final int childCount = children.size(); Debug.log(DebugTimer.this.mDebugLevel, new String(indent) + "'" + this.mLabel + "' {"); for(int i = 0; i < childCount - 1; i++) { children.get(i).dump(pIndent + 1, ","); } children.get(childCount - 1).dump(pIndent + 1); Debug.log(DebugTimer.this.mDebugLevel, new String(indent) + "}@( " + (this.mEndTime - this.mStartTime) + "ms )" + pPostfix); } } } private void ensureChildrenAllocated() { if(this.mChildren == null) { this.mChildren = new ArrayList<DebugTime>(); } } // =========================================================== // Inner and Anonymous Classes // =========================================================== } }