// jave.lin 2023/04/21 带 timespan 的日志 (不帶 log hierarchy 结构要求,即: 不带 stack 要求)
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
public class TSLog
{
// ts == time span
public class WithTimeSpanLogData
{
public int idx;
public string tag;
public TimeSpan timeSpan; // (DateTime)start - (DateTime)end
public string startDesc;
public string endDesc;
public DateTime startDateTime;
public DateTime endDateTime;
public string classNameStart;
public int lineStart;
public string classNameEnd;
public int lineEnd;
public static string GetCSVTitle()
{
return $"编号, 标记, 耗时, 开始描述, 结束描述, 开始时间, 结束时间, 开始文件, 开始行, 结束文件, 结束行\n";
}
public override string ToString()
{
return $"{idx}, {tag}, {timeSpan}, {startDesc}, {endDesc}, {startDateTime}, {endDateTime}, {classNameStart}, {lineStart}, {classNameEnd}, {lineEnd}";
}
}
// clog == custom log
public static void CLog(string content)
{
Debug.Log($"[{DateTime.Now}] {content}");
}
private static void GetCodeLineNum(out string fileName, out int lineNum)
{
System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(0, true);
System.Diagnostics.StackFrame frame = st.GetFrame(st.FrameCount - 1);
fileName = frame.GetFileName();
lineNum = frame.GetFileLineNumber();
}
//=== DEMO START ======================
private static void Test()
{
System.Threading.Thread.Sleep(2000);
CLog("Test Func Testing with date time Log");
}
private static void Test2()
{
System.Threading.Thread.Sleep(1000);
CLog("Test2 Func Testing with date time Log");
}
[MenuItem("实用工具/测试/测试TSLog并写日志结果")]
private static void Usage()
{
var tslog = new TSLog();
tslog.Clear();
tslog.BeginTag("Test", "开始Test函数,并标记");
Test();
tslog.EndTag("Test", "结束Test函数,并统计消耗");
tslog.BeginTag("Test2", "开始Test2函数,并标记");
Test2();
tslog.EndTag("Test2", "结束Test2函数,并统计耗时");
tslog.WriteTagLogs();
/*
测试输出:
编号, 标记, 耗时, 开始描述, 结束描述, 开始时间, 结束时间, 开始文件, 开始行, 结束文件, 结束行
0, Test, 00:00:02.0112773, 开始Test函数,并标记, 结束Test函数,并统计消耗, 2023/4/21 15:36:10, 2023/4/21 15:36:12, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 73, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 75
1, Test2, 00:00:01.0104517, 开始Test2函数,并标记, 结束Test2函数,并统计耗时, 2023/4/21 15:36:12, 2023/4/21 15:36:13, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 77, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 79
* */
}
//=== DEMO END ======================
// WTSL ==> With TimeSpan Log
private int WTSLDataIDXCounter = 0;
private List<WithTimeSpanLogData> logTag_List = new List<WithTimeSpanLogData>();
private Dictionary<string, WithTimeSpanLogData> logTag_Dict = new Dictionary<string, WithTimeSpanLogData>();
public void Clear()
{
WTSLDataIDXCounter = 0;
logTag_List.Clear();
logTag_Dict.Clear();
}
public void BeginTag(string tag, string description = null)
{
tag = tag.Replace(",", "_");
if (description != null)
description = description.Replace(",", "_");
var alreadyBeginTag = logTag_Dict.TryGetValue(tag, out var data);
var nowDateTime = DateTime.Now;
if (alreadyBeginTag)
{
Debug.LogWarning($"[{nowDateTime}] W BeginTag : {tag}, but alreadyBeginTag at time : {data}");
}
else
{
GetCodeLineNum(out string fileName, out int lineNum);
Debug.Log($"[{nowDateTime}] D BeginTag : {tag}");
logTag_Dict[tag] = new WithTimeSpanLogData
{
idx = WTSLDataIDXCounter++,
tag = tag,
startDesc = description,
startDateTime = nowDateTime,
classNameStart = fileName,
lineStart = lineNum,
};
}
}
public void EndTag(string tag, string description = null)
{
tag = tag.Replace(",", "_");
if (description != null)
description = description.Replace(",", "_");
var hasBeginTag = logTag_Dict.TryGetValue(tag, out var data);
var nowDateTime = DateTime.Now;
if (hasBeginTag)
{
var ts = nowDateTime - data.startDateTime;
Debug.Log($"[{nowDateTime}] D EndTag : {tag}, Timespan : {ts}");
logTag_Dict.Remove(tag);
GetCodeLineNum(out string fileName, out int lineNum);
data.endDesc = description;
data.endDateTime = nowDateTime;
data.classNameEnd = fileName;
data.lineEnd = lineNum;
data.timeSpan = ts;
logTag_List.Add(data);
}
else
{
Debug.LogWarning($"[{nowDateTime}] W EndTag : {tag}, have no Timespan");
}
}
public bool WriteTagLogs()
{
var ret = false;
var error = string.Empty;
try
{
using (var streamWriter = new StreamWriter("BuildingTagLogs.csv", false))
{
// 标题
streamWriter.Write(WithTimeSpanLogData.GetCSVTitle());
// 内容
var list = logTag_List;
list.Sort((a, b) => a.idx - b.idx);
foreach (var data in list)
{
streamWriter.Write($"{data}\n");
}
streamWriter.Close();
}
Debug.Log("WriteTagLogs : BuildingTagLogs.csv Successfully!");
ret = true;
error = string.Empty;
}
catch (System.Exception er)
{
ret = false;
error = er.ToString();
}
finally
{
if (!ret)
{
Debug.LogError($"WriteTagLogs : BuildingTagLogs.csv Failured, error : {error}");
}
}
return ret;
}
}
编号, 标记, 耗时, 开始描述, 结束描述, 开始时间, 结束时间, 开始文件, 开始行, 结束文件, 结束行
0, Test, 00:00:02.0112773, 开始Test函数,并标记, 结束Test函数,并统计消耗, 2023/4/21 15:36:10, 2023/4/21 15:36:12, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 73, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 75
1, Test2, 00:00:01.0104517, 开始Test2函数,并标记, 结束Test2函数,并统计耗时, 2023/4/21 15:36:12, 2023/4/21 15:36:13, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 77, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 79

在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里编辑 3.解析依赖到项目中
Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u
我想在heroku.com上查看我的应用程序日志的内容,所以我关注了thisexcellentadvice并拥有我所有的日志内容。但是我现在很想知道我的日志文件实际在哪里,因为“log/production.log”似乎是空的:C:\>herokuconsoleRubyconsoleforajpbrevx.heroku.com>>files=Dir.glob("*")=>["public","tmp","spec","Rakefile","doc","config.ru","app","config","lib","README","Gemfile.lock","vendor","sc
我从我的一个Controller类中收到一个错误,我不知道为什么。错误是:SyntaxErrorinTermsController#show,syntaxerror,unexpected$end,expectingkeyword_end这是terms_controller.rb:classTermsController我的展示页面目前只包含:这可能是我遗漏的一些小东西-感谢您的帮助! 最佳答案 问题是end关键字不够,它在它之前找到了$end(代表文件结尾的标记)可以找到它要找的东西——另一个end。(end关键字的解析器标记是“k
我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭11年前。Ruby是一种美丽的语言,但有一个我讨厌写很多次的关键词“结束”。有什么方法可以写出简洁的代码而不用每次都写“end”吗?