乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Unity日志工具

       kiki的號 2017-03-20

      Unity日志工具——封裝,跳轉(zhuǎn)

       

      By D.S.Qiu

      尊重他人的勞動,支持原創(chuàng),轉(zhuǎn)載請注明出處:http://dsqiu.

             

              好久沒有寫博客分享了,主要有三個原因:1.iteye博客不支持公式等高級特性的支持(不知道iteye的產(chǎn)品經(jīng)理是怎么想的),就一直想自己搭建一個類似stackedit.io編輯器的博客站點,一直沒有憋出來就一直沒繼續(xù)寫了;2.自己想做的事情太多了(比如像寫一個Visual Studio MFC的那種界面一樣的Unity UGUI編輯工具,寫博客花了太多時間了,可是還是沒有憋出來(憂傷?。?.之前寫的大部分就沒有什么含量,當然是作為自己學習的一個途徑吧,所以還是需要大量的積累先!

             

              應該所有的團隊都會自己封裝日志工具,除非引擎已經(jīng)集成了,在Unity也不例外,當時之前的同事封裝了一個有一個很大不爽的地方是:從Unity ConsoleWindow 雙擊日志跳轉(zhuǎn)到代碼總是跳轉(zhuǎn)到封裝類中的函數(shù),而不能直接跳轉(zhuǎn)到調(diào)用封裝類被調(diào)用的地方。

       

             切好在準備新項目,我把原來不夠優(yōu)良的地方都進行了改進直至盡可能的完美。之前一直就知道1.利用反射可以獲取Unity的private FieldInfo和 MethodInfo 可以做很多事情,2.可以利用Unity提供的api調(diào)整到指定的代碼中去,3.Unity提供跳轉(zhuǎn)回調(diào)的機制。算是理論只是具備了,今天來公司就把這個給寫出來了,當然還對LogLevel和StackFrame信息進行了優(yōu)化(之前的有點丑,是13年一個前前同事寫的)。

       

      其實是很簡單的,直接說下思路吧(Unity5.3):

             1.記錄通過封裝日志工具的函數(shù)調(diào)用棧信息 StackFrame。

             2.添加UnityEditor.Callbacks.OnOpenAssetAttribute(0)的回調(diào)方法,處理從ConsoleWindow雙擊跳轉(zhuǎn)

             3.利用反射獲取ConsoleWindow 的 ListeViewState 的 row(當前雙擊的行)和總行數(shù)

             4.利用3得到行數(shù)反射獲取LogEntry信息進行匹配獲得對應StackFrame

             5.調(diào)用AssetDatabase.OpenAsset()即可。

       

       更新到Unity5.3發(fā)現(xiàn),他提供Logger這個類,本來還以為可以實現(xiàn)這些功能,不過簡單測試下來發(fā)現(xiàn)是不行的,我就還不清楚Unity構(gòu)造一個Logger類是干嘛的,搞得我把下面的類名改成LoggerUtility。

       

      貼下完整的代碼:

      C#代碼 復制代碼 收藏代碼
      1. /* 
      2.  * File: Assets/Scripts/Game/Utility/LoggerUtility.cs 
      3.  * Project: **** 
      4.  * Company: Lucky 
      5.  * Code Porter: D.S.Qiu  
      6.  * Create Date: 10/9/2015 10:11:53 PM 
      7.  */  
      8.   
      9. using System;  
      10. using System.Collections.Generic;  
      11. using System.Diagnostics;  
      12. using System.IO;  
      13. using System.Text;  
      14. #if UNITY_EDITOR  
      15. using System.Reflection;  
      16. using UnityEditor;  
      17. using UnityEditor.Callbacks;  
      18. #endif  
      19. using UnityEngine;  
      20. using Debug = UnityEngine.Debug;  
      21.   
      22. namespace Utility  
      23. {  
      24.     public class LogUtility  
      25.     {  
      26.         public enum LogLevel : byte  
      27.         {  
      28.             None = 0,  
      29.             Exception = 1,  
      30.             Error = 2,  
      31.             Warning = 3,  
      32.             Info = 4,  
      33.         }  
      34.   
      35.         public static LogLevel logLevel = LogLevel.Info;  
      36.         public static string infoColor = "#909090";  
      37.         public static string warningColor = "orange";  
      38.         public static string errorColor = "red";  
      39.   
      40.         public static void LogBreak(object message, UnityEngine.Object sender = null)  
      41.         {  
      42.             LogInfo(message, sender);  
      43.             Debug.Break();  
      44.         }  
      45.   
      46.         public static void LogFormat(string format, UnityEngine.Object sender, params object[] message)  
      47.         {  
      48.             if (logLevel >= LogLevel.Info)  
      49.                 LogLevelFormat(LogLevel.Info, string.Format(format, message), sender);  
      50.         }  
      51.   
      52.         public static void LogFormat(string format, params object[] message)  
      53.         {  
      54.             if (logLevel >= LogLevel.Info)  
      55.                 LogLevelFormat(LogLevel.Info, string.Format(format, message), null);  
      56.         }  
      57.   
      58.         public static void LogInfo(object message, UnityEngine.Object sender = null)  
      59.         {  
      60.             if(logLevel >= LogLevel.Info)  
      61.                 LogLevelFormat(LogLevel.Info,message,sender);  
      62.         }  
      63.   
      64.         public static void LogWarning(object message, UnityEngine.Object sender = null)  
      65.         {  
      66.             if (logLevel >= LogLevel.Warning)  
      67.                 LogLevelFormat(LogLevel.Warning, message,  sender);  
      68.         }  
      69.   
      70.         public static void LogError(object message, UnityEngine.Object sender = null)  
      71.         {  
      72.             if (logLevel >= LogLevel.Error)  
      73.             {  
      74.                 LogLevelFormat(LogLevel.Error, message, sender);  
      75.             }  
      76.         }  
      77.   
      78.         public static void LogException(Exception exption, UnityEngine.Object sender = null)  
      79.         {  
      80.             if (logLevel >= LogLevel.Exception)  
      81.             {  
      82.                 LogLevelFormat(LogLevel.Exception, exption, sender);  
      83.             }  
      84.         }  
      85.   
      86.         private static void LogLevelFormat(LogLevel level, object message, UnityEngine.Object sender)  
      87.         {  
      88.             string levelFormat =  level.ToString().ToUpper();  
      89.             StackTrace stackTrace = new StackTrace(true);  
      90.             var stackFrame = stackTrace.GetFrame(2);  
      91. #if UNITY_EDITOR  
      92.             s_LogStackFrameList.Add(stackFrame);  
      93. #endif  
      94.             string stackMessageFormat = Path.GetFileName(stackFrame.GetFileName()) + ":" + stackFrame.GetMethod().Name + "():at line " + stackFrame.GetFileLineNumber();  
      95.             string timeFormat = "Frame:" + Time.frameCount + "," + DateTime.Now.Millisecond + "ms";  
      96.             string objectName = string.Empty;  
      97.             string colorFormat = infoColor;  
      98.             if (level == LogLevel.Warning)  
      99.                 colorFormat = warningColor;  
      100.             else if (level == LogLevel.Error)  
      101.                 colorFormat = errorColor;  
      102.             StringBuilder sb = new StringBuilder();  
      103.             sb.AppendFormat("<color={3}>[{0}][{4}][{1}]{2}</color>", levelFormat, timeFormat, message, colorFormat, stackMessageFormat);  
      104.             Debug.Log(sb,sender);  
      105.         }  
      106.  
      107. #if UNITY_EDITOR  
      108.         private static int s_InstanceID;  
      109.         private static int s_Line = 104;  
      110.         private static List<StackFrame> s_LogStackFrameList = new List<StackFrame>();  
      111.         //ConsoleWindow  
      112.         private static object s_ConsoleWindow;  
      113.         private static object s_LogListView;  
      114.         private static FieldInfo s_LogListViewTotalRows;  
      115.         private static FieldInfo s_LogListViewCurrentRow;  
      116.         //LogEntry  
      117.         private static MethodInfo s_LogEntriesGetEntry;  
      118.         private static object s_LogEntry;  
      119.         //instanceId 非UnityEngine.Object的運行時 InstanceID 為零所以只能用 LogEntry.Condition 判斷  
      120.         private static FieldInfo s_LogEntryInstanceId;  
      121.         private static FieldInfo s_LogEntryLine;  
      122.         private static FieldInfo s_LogEntryCondition;  
      123.         static LogUtility()  
      124.         {  
      125.             s_InstanceID = AssetDatabase.LoadAssetAtPath<MonoScript>("Assets/Scripts/Game/Utility/LoggerUtility.cs").GetInstanceID();  
      126.             s_LogStackFrameList.Clear();  
      127.   
      128.             GetConsoleWindowListView();  
      129.         }  
      130.   
      131.         private static void GetConsoleWindowListView()  
      132.         {  
      133.             if (s_LogListView == null)  
      134.             {  
      135.                 Assembly unityEditorAssembly = Assembly.GetAssembly(typeof(EditorWindow));  
      136.                 Type consoleWindowType = unityEditorAssembly.GetType("UnityEditor.ConsoleWindow");  
      137.                 FieldInfo fieldInfo = consoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);  
      138.                 s_ConsoleWindow = fieldInfo.GetValue(null);  
      139.                 FieldInfo listViewFieldInfo = consoleWindowType.GetField("m_ListView", BindingFlags.Instance | BindingFlags.NonPublic);  
      140.                 s_LogListView = listViewFieldInfo.GetValue(s_ConsoleWindow);  
      141.                 s_LogListViewTotalRows = listViewFieldInfo.FieldType.GetField("totalRows", BindingFlags.Instance | BindingFlags.Public);  
      142.                 s_LogListViewCurrentRow = listViewFieldInfo.FieldType.GetField("row", BindingFlags.Instance | BindingFlags.Public);  
      143.                 //LogEntries  
      144.                 Type logEntriesType = unityEditorAssembly.GetType("UnityEditorInternal.LogEntries");  
      145.                 s_LogEntriesGetEntry = logEntriesType.GetMethod("GetEntryInternal", BindingFlags.Static | BindingFlags.Public);  
      146.                 Type logEntryType = unityEditorAssembly.GetType("UnityEditorInternal.LogEntry");  
      147.                 s_LogEntry = Activator.CreateInstance(logEntryType);  
      148.                 s_LogEntryInstanceId = logEntryType.GetField("instanceID", BindingFlags.Instance | BindingFlags.Public);  
      149.                 s_LogEntryLine = logEntryType.GetField("line", BindingFlags.Instance | BindingFlags.Public);  
      150.                 s_LogEntryCondition = logEntryType.GetField("condition", BindingFlags.Instance | BindingFlags.Public);  
      151.             }  
      152.         }  
      153.         private static StackFrame GetListViewRowCount()  
      154.         {  
      155.             GetConsoleWindowListView();  
      156.             if (s_LogListView == null)  
      157.                 return null;  
      158.             else  
      159.             {  
      160.                 int totalRows = (int)s_LogListViewTotalRows.GetValue(s_LogListView);  
      161.                 int row = (int)s_LogListViewCurrentRow.GetValue(s_LogListView);  
      162.                 int logByThisClassCount = 0;  
      163.                 for (int i = totalRows - 1; i >= row; i--)  
      164.                 {  
      165.                     s_LogEntriesGetEntry.Invoke(nullnew object[] { i, s_LogEntry });  
      166.                     string condition = s_LogEntryCondition.GetValue(s_LogEntry) as string;  
      167.                     //判斷是否是由LoggerUtility打印的日志  
      168.                     if (condition.Contains("][") && condition.Contains("Frame"))  
      169.                         logByThisClassCount++;  
      170.                 }  
      171.   
      172.                 //同步日志列表,ConsoleWindow 點擊Clear 會清理  
      173.                 while (s_LogStackFrameList.Count > totalRows)  
      174.                     s_LogStackFrameList.RemoveAt(0);  
      175.                 if (s_LogStackFrameList.Count >= logByThisClassCount)  
      176.                     return s_LogStackFrameList[s_LogStackFrameList.Count - logByThisClassCount];  
      177.                 return null;  
      178.             }  
      179.         }  
      180.   
      181.         [UnityEditor.Callbacks.OnOpenAssetAttribute(0)]  
      182.         public static bool OnOpenAsset(int instanceID, int line)  
      183.         {  
      184.             if (instanceID == s_InstanceID && s_Line == line)  
      185.             {  
      186.                 var stackFrame = GetListViewRowCount();  
      187.                 if (stackFrame != null)  
      188.                 {  
      189.                     string fileName = stackFrame.GetFileName();  
      190.                     string fileAssetPath = fileName.Substring(fileName.IndexOf("Assets"));  
      191.                     AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath<MonoScript>(fileAssetPath), stackFrame.GetFileLineNumber());  
      192.                     return true;  
      193.                 }  
      194.             }  
      195.              
      196.             return false;  
      197.         }  
      198. #endif  
      199.     }  
      200.   
      201. }  

       

       小結(jié):

              其實都沒有什么小結(jié)的,多說幾句:對于這個日志工具我還會進一步增加兩個優(yōu)化:遠程日志和通過字符串反射查詢運行時的值(前端調(diào)試還是沒有后端的來的方便,打斷點太低效了)。雨松MOMO最近分享了很多Editor的小trick,可以去他的博客和微博上找下,這里分享一個他反編譯Unity5.3的Bitbucket代碼 ,不過還不夠完美,反編譯的看不到private的 FieldInfo 和 MethdInfo ,這個也很有用。

       

             歡迎各種不爽,各種噴,寫這個純屬個人愛好,秉持”分享“之德!

       

             如果您對D.S.Qiu有任何建議或意見可以在文章后面評論,或者發(fā)郵件(gd.s.qiu@gmail.com)交流,您的鼓勵和支持是我前進的動力,希望能有更多更好的分享。

             轉(zhuǎn)載請在文首注明出處:http://dsqiu./blog/2263664

      更多精彩請關注D.S.Qiu的博客和微博(ID:靜水逐風)

            

       

       

       

       

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多