文档章节

Unity定时器堆栈显示

梦想游戏人
 梦想游戏人
发布于 2017/09/04 16:36
字数 510
阅读 12
收藏 0

一般定时器是一个匿名函数,callback,在函数执行错误的话,很难查找到错误信息。

在这里可以利用添加定时器的时候 对调用栈进行一个快照,当发生错误时输出即可,这样调试起来方便多了。

 

AddTimer中栈 信息的一个快照为string 作为Timer对象的成员,release发行时可以去掉这种辅助机制

/*
* Author:  caoshanshan
* Email:   me@dreamyouxi.com
code copy from https://git.oschina.net/dreamyouxi/XYGame;
 */
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using ExtBase;

public sealed class TimerQueue : Singleton<TimerQueue>
{

    /// <summary>
    /// 添加一个真实时间定时器,返回函数调用即可 打断定时任务
    /// </summary>
    /// <param name="time_delay"></param>
    /// <param name="cb"></param>
    /// <param name="repeat_times">  <0 will be run forever</param>
    public VoidFuncVoid AddTimer(float time_delay, VoidFuncNN cb, int repeat_times = 1, params object[] objs)
    {
        return this.AddTimer(time_delay, () => { cb(objs); }, repeat_times);
    }
    /// <summary>
    /// 添加一个真实时间定时器,返回函数调用即可 打断定时任务
    /// </summary>
    /// <param name="time_delay"></param>
    /// <param name="cb"></param>
    /// <param name="repeat_times">  <0 will be run forever</param>
    public VoidFuncVoid AddTimer(float time_delay, VoidFuncVoid cb, int repeat_times = 1)
    {
        if (repeat_times == 0) return null;// () => { };
        Timer time = new Timer();
        time.delay = time_delay;
        time.cb = cb;
        time.repeat_times = repeat_times;
        //记录定时器添加的时候的快照栈信息,以 提供错误时 更多调试信息
        System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(true);

        string ss = "\n";
        for (int i = 0; i < st.FrameCount; i++)
        {
            var f = st.GetFrame(i);
            string name = f.GetFileName();
            if (name.Length > Application.dataPath.Length)
            {
                name = name.Substring(Application.dataPath.Length, name.Length - Application.dataPath.Length);
            }
            ss += "   " + f.GetMethod().ToString() + " at " + name + " (" + f.GetFileLineNumber() + ") \n";
        }
        time.stackInfo = ss;
        time.Init();
        list.Add(time);
        return () =>
        {
            if (time != null && this.list.Contains(time))
                time.SetInValid();
        };
    }

    /// <summary>
    /// unity engine tick
    /// </summary>
    public void Tick()
    {
        this.Tick(ref list);
    }
    private void Tick(ref List<TimerBase> list)
    {
        if (list.Count < 1)
            return;

        for (int i = 0; i < list.Count; i++)
        {
            if (list[i] == null)
                continue;

            TimerBase timer = list[i] as TimerBase;
            timer.Tick();
        }

        for (int i = 0; i < list.Count; )
        {
            TimerBase b = list[i] as TimerBase;
            if (b.IsInValid())
            {
                list.Remove(b);
            }
            else
            {
                ++i;
            }
        }
    }
    public void Clear()
    {
        this.list_ms.Clear();
        this.list.Clear();
    }
    List<TimerBase> list_ms = new List<TimerBase>();
    List<TimerBase> list = new List<TimerBase>();

}


class TimerBase : GAObject
{
    public string stackInfo = "";
    public virtual void Tick()
    {

    }

    public VoidFuncVoid cb = null;
    public int repeat_times = 1;
    protected int repeat_times_current = 0;
}

sealed class Timer : TimerBase
{
    public override void Tick()
    {
        if (this.IsInValid()) return;

        if (current < delay)
        {
            current += Time.deltaTime;
            return;
        }
        if (cb != null)
        {
            try
            {
                cb();
            }
            catch (System.Exception e)
            {
                Debug.LogError(e.Message);
                Debug.LogError("add timer stackTrace:" + this.stackInfo);
                Debug.LogError("call stackTrace:" + e.StackTrace);
            }
            cb = null;
        }
        current = 0.0f;
        if (++repeat_times_current >= repeat_times && repeat_times >= 0)
        {
            this.SetInValid();
        }
    }

    public override bool Init()
    {
        return true;
    }
    float current = 0.0f;
    public float delay = 0.0f;

}

 

© 著作权归作者所有

共有 人打赏支持
梦想游戏人
粉丝 36
博文 429
码字总数 122400
作品 0
成都
学习Mono与Unity3D关系的笔记

Xamarin公司开发的跨平台 .NET运行环境,是.NET框架的另一种实现。区别在于,它可以跨平台。(Unity的跨平台特性依赖于Mono) Mono的组成。 1.C#编译器。 最新的Momo版本(5.0+)c#编译器完全...

lishengxu159
05/05
0
0
unity3D -Mac- 破解

3.用root用户给破解文件权限 shell命令:sudo su 然后输入密码(密码为当前用户密码) 接着更改破解文件Unity的所属用户,以及给Unityv4.x.ulf文件执行权限 shell命令:chown root:admin Un...

MrLovelyCbb
2015/04/27
0
0
unity pro 2017 Mac(游戏开发制作工具)详细破解教程!

Unity 2017 for Mac的优点在于它可以让您创建可在所有主流桌面和移动操作系统上播放的游戏,而不会影响游戏体验和性能。如果你需要一个高端和基于GUI的游戏开发工具附带一个非常强大的引擎,...

无言苍白
08/22
0
0
【Untiy3D 游戏开发之一】Unity3D For Mac最新3.4.1版本破解教程分享并将Unity3D项目在iphone上运行;

声明:本破解教程为学习其他别人文章进行的,如有侵犯等请通知我,我删除对应段落; Himi 原创, 欢迎转载,转载请在明显处注明! 谢谢。 原文地址:http://blog.csdn.net/xiaominghimi/art...

迷途d书童
2012/03/19
0
0
UnityShader源码2017---学习笔记与自我拓展006

源自CubeBlend 首先映入眼帘的是 稍微解释一下[NoScaleOffset]吧,就是在material的面板上没有tilling和offset控制部分的GUI显示。 然后我看到了 这个应该是unity声明的吧,比如想MainTexST...

u012871784
05/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

区块链入门教程以太坊源码分析ethdb源码分析

兄弟连区块链入门教程以太坊源码分析ethdb源码分析,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。但事实上,正是初期泡沫的渐退...

兄弟连区块链入门教程
31分钟前
1
0
Eclipse下忽略掉node_modules目录相关配置

https://blog.csdn.net/yzf913214/article/details/72872523

张宏亮1982
32分钟前
2
0
在Python-dataframe中如何把出生日期转化为年龄?

我们在做数据挖掘项目或大数据竞赛时,如果个体是人的时候,获得的数据中可能有出生日期的Series,举个简单例子,比如这样的一些数: # -*- coding: utf-8 -*- import pandas as pd from ...

Mr_zebra
34分钟前
5
0
Android入门—activity生命周期

activity生命周期如下所示: onCreate()方法 创建activity时使用onStart()方法 当activity界面变为用户可见时调用onResume()方法 当activity界面获取到焦点时调用(界面按钮可点击,...

haoyuehong
36分钟前
1
0
使用C++ Builder 6编译产生错误

错误提示: [C++ Error] E2075 Incorrect project override option: Files\Borland\CBuilder6\lib\vcl60.csm[C++ Error] E2075 Incorrect project override option: Files\Borland\CBuilde......

simpower
39分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部