public static bool GetAssetType(string assetPath, out Type type, out TypeSource source)
        {
            var ext = Path.GetExtension(assetPath);

            if (!string.IsNullOrEmpty(ext))
            {
                if (_knownTypes.TryGetValue(ext.ToLower(), out type))
                {
                    source = TypeSource.FileName;
                    return(true);
                }
            }

            if (AssetTypeCache.GetAssetType(assetPath, out type))
            {
                source = TypeSource.Cache;
                return(true);
            }

            source = TypeSource.Unity;
            var asset = AssetDatabase.LoadMainAssetAtPath(assetPath);

            if (asset == null)
            {
                TSLog.LogWarning(LogCategory.Trace, string.Format("Failed loading asset at path [{0}].", assetPath));
                type = null;
                return(false);
            }

            type = asset.GetType();
            AssetTypeCache.PostAssetType(assetPath, type);

            return(true);
        }
Beispiel #2
0
        public TypeSafeDataUnit GetTypeSafeDataUnit()
        {
            var data = new List <TypeSafeDataEntry>();

            data.Add(new TypeSafeDataEntry("All", new object[] { int.MaxValue }, true));
            data.Add(new TypeSafeDataEntry("None", new object[] { 0 }, true));

            var layers = InternalEditorUtility.layers;

            foreach (var layer in layers)
            {
                var ignore = string.IsNullOrEmpty(layer) || layer.Trim().Length == 0;
                var num    = LayerMask.NameToLayer(layer);

                TSLog.Log(LogCategory.Scanner, string.Format("Layer: {0}, (index: {1},ignore={2})", layer, num, ignore));

                if (!ignore)
                {
                    data.Add(new TypeSafeDataEntry(layer, new object[] { 1 << num }));
                }
            }

            return(new TypeSafeDataUnit(TypeSafeUtil.GetFinalClassName(Strings.LayerMaskTypeName), typeof(int), data,
                                        false, "LayerMask"));
        }
        private void ValidateFolder(ResourceFolder folder)
        {
            // Search for resources with the same name as a folder in the same directory
            for (var i = 0; i < folder.Resources.Count; i++)
            {
                var r = folder.Resources[i];

                if (folder.Folders.Any(p => p.Name == r.Name))
                {
                    TSLog.LogWarning(LogCategory.Compile,
                                     string.Format("Name for resource at [{0}] conflicts with a folder of the same name.", r.FullPath),
                                     AssetDatabase.LoadAssetAtPath(r.FullPath, typeof(Object)));

                    // Remove existing resource
                    if (!Remove(r))
                    {
                        throw new Exception("Fatal error, failed removing resource from ResourceDatabase. ");
                    }

                    // Add again with new name
                    folder.Resources.Add(new ResourceDefinition("_" + r.Name, r.Path, r.FullPath, r.Type));
                }
            }

            foreach (var resourceFolder in folder.Folders)
            {
                ValidateFolder(resourceFolder);
            }
        }
Beispiel #4
0
        /// <summary>
        /// 获取系统日志
        /// </summary>
        /// <param name="logId">日志编号</param>
        /// <returns>系统日志对象</returns>
        public virtual TSLog Get(long logId)
        {
            TSLog tsLog = null;

            try
            {
                string strSQL = "select * from TSLog where logId=@logId";
                Param  param  = new Param();
                param.Clear();
                param.Add("@logId", logId);
                db.Open();
                ComDataReader dr = db.ExecuteReader(CommandType.Text, strSQL, param);
                if (dr.Read())
                {
                    tsLog = ReadData(dr);
                }
                dr.Close();
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                db.Close();
            }
            return(tsLog);
        }
        private ResourceFolder GetFolderForPath(string path)
        {
            var components = path.Split('/');

            var f = RootFolder;

            for (var i = 0; i < components.Length - 1; i++)
            {
                var c = CompilerUtil.GetSafeName(components[i], true);

                var isDuplicate = f.Name == c;
                var folderName  = isDuplicate ? "_" + c : c;

                var folder = f.Folders.FirstOrDefault(p => p.Name == folderName);

                if (folder == null)
                {
                    var folderPath = components.Take(i).ToArray();

                    // Post warning the first time this folder is encountered
                    if (isDuplicate)
                    {
                        TSLog.LogWarning(LogCategory.Compile,
                                         string.Format(Strings.Warning_FolderNameCannotBeSameAsParent, string.Join("/", folderPath)));
                    }

                    folder = new ResourceFolder(folderName, string.Join("/", folderPath));
                    f.Folders.Add(folder);
                }

                f = folder;
            }

            return(f);
        }
        public void Add(ResourceDefinition definition)
        {
            var folder = GetFolderForPath(definition.Path);

            if (definition.Name == folder.Name)
            {
                TSLog.LogWarning(LogCategory.Compile, Strings.Warning_ResourceNameCannotBeSameAsParent,
                                 AssetDatabase.LoadAssetAtPath(definition.FullPath, typeof(Object)));

                definition = new ResourceDefinition("_" + definition.Name, definition.Path, definition.FullPath,
                                                    definition.Type);
            }

            foreach (var p in folder.Resources)
            {
                if (p.Name == definition.Name)
                {
                    TSLog.LogError(LogCategory.Compile,
                                   string.Format("Name for resource at [{0}] conflicts with another resource.", definition.FullPath),
                                   AssetDatabase.LoadAssetAtPath(definition.FullPath, typeof(Object)));

                    TSLog.LogError(LogCategory.Compile, string.Format("  \\_ Other Resource: {0}", p.FullPath),
                                   AssetDatabase.LoadAssetAtPath(p.FullPath, typeof(Object)));

                    return;
                }
            }

            folder.Resources.Add(definition);
        }
        private static void PopulateClass(TypeSafeDataUnit dataUnit, CodeTypeDeclaration container)
        {
            foreach (var nestedUnit in dataUnit.NestedUnits)
            {
                string className;

                if (!CompilerUtil.GetSafeNameAndVerifyNotDuplicate(nestedUnit.ClassName, container, out className))
                {
                    continue;
                }

                if (className == container.Name)
                {
                    TSLog.LogWarning(LogCategory.Compile, Strings.Warning_NameCannotBeSameAsParent);
                    className = "_" + className;

                    // Check for duplicates again after having added the '_'
                    if (!CompilerUtil.GetSafeNameAndVerifyNotDuplicate(className, container, out className))
                    {
                        continue;
                    }
                }

                var nestedContainer = CompilerUtil.CreateStaticType(className);
                PopulateClass(nestedUnit, nestedContainer);

                container.Members.Add(nestedContainer);
            }

            PopulateClassMembers(dataUnit, container);
        }
        public CodeCompileUnit Compile(TypeSafeDataUnit dataUnit)
        {
            var compileUnit = new CodeCompileUnit();

            compileUnit.UserData.Add(Strings.CompileUnitUserDataKey, dataUnit.FileName);

            CompilerUtil.WriteHeader(compileUnit);

            var ns = new CodeNamespace(Namespace);

            compileUnit.Namespaces.Add(ns);

            var className = CompilerUtil.GetSafeName(dataUnit.ClassName, false, false);

            if (className != dataUnit.ClassName)
            {
                TSLog.LogWarning(LogCategory.Compile,
                                 string.Format("Class name was modified to conform to C# standards ({0} -> {1})", dataUnit.ClassName, className));
            }

            var container = CompilerUtil.CreateStaticType(className);

            CompilerUtil.AddTypeSafeTag(container);

            PopulateClass(dataUnit, container);

            ns.Types.Add(container);
            return(compileUnit);
        }
Beispiel #9
0
        public static void DrawLogo(Texture2D logo)
        {
            if (logo == null)
            {
                TSLog.LogWarning(LogCategory.Trace, "Logo is null");
                return;
            }

            var rect = EditorGUILayout.BeginVertical();

            GUILayout.Space(20);

            EditorGUILayout.BeginHorizontal();

            GUILayout.FlexibleSpace();

            GUI.DrawTexture(
                GUILayoutUtility.GetRect(logo.width, logo.width, logo.height, logo.height, GUILayout.ExpandHeight(false),
                                         GUILayout.ExpandWidth(false)),
                logo);

            GUILayout.FlexibleSpace();

            EditorGUILayout.EndHorizontal();

            GUILayout.Space(15);

            EditorGUILayout.EndVertical();

            var size = EditorStyles.miniLabel.CalcSize(new GUIContent(Strings.Version));

            GUI.Label(new Rect(rect.xMax - size.x, rect.yMax - size.y, size.x, size.y), Strings.Version,
                      EditorStyles.miniLabel);
        }
Beispiel #10
0
 void Run()
 {
     Singletons.Add <PlayerManager>().Initialize();
     Singletons.Add <SyncManager>().Initialize();
     StartNetwork();
     TSLog.Info("Server Started!");
 }
        public TypeSafeDataUnit GetTypeSafeDataUnit()
        {
            TSLog.Log(LogCategory.Scanner, "Beginning Sorting Layer Scan");

            var layerNames = InternalEditorUtilityWrapper.sortingLayerNames;
            var layerIds   = InternalEditorUtilityWrapper.sortingLayerUniqueIDs;

            if (layerNames.Length != layerIds.Length)
            {
                throw new Exception("Sorting layer name and id array lengths do not match.");
            }

            var data = new List <TypeSafeDataEntry>();

            for (var i = 0; i < layerNames.Length; i++)
            {
                var name = layerNames[i];
                var id   = layerIds[i];

                TSLog.Log(LogCategory.Scanner, string.Format("Sorting Layer {0}: name={1}, unique_id={2}", i, name, id));

                data.Add(new TypeSafeDataEntry(name, new object[] { name, id }));
            }

            TSLog.Log(LogCategory.Scanner, "Sorting Layer Scan Completed");

            return(new TypeSafeDataUnit(TypeSafeUtil.GetFinalClassName(Strings.SortingLayersTypeName),
                                        typeof(SortingLayer), data, true, "SortingLayers"));
        }
Beispiel #12
0
 public void Initialize()
 {
     tickrate            = AppConfig.Instance.tickrate;
     updaterate          = AppConfig.Instance.updaterate;
     inputchoke          = Mathf.Max(1, Mathf.CeilToInt(AppConfig.Instance.cmdrate / tickrate));
     mSnapshotOverTick   = (uint)Mathf.FloorToInt(updaterate / tickrate);
     Time.fixedDeltaTime = tickrate;
     TSLog.InfoFormat("tickrate:{0}, updaterate:{1}, ss/t:{2}", tickrate, updaterate, mSnapshotOverTick);
 }
Beispiel #13
0
 public void OnNewConnection(NetConnection connection)
 {
     mAuthingConnections.Add(new AuthingConnection()
     {
         timer      = authTimeout,
         connection = connection,
     });
     TSLog.InfoFormat("incoming connection:{0}", connection.RemoteEndPoint);
 }
Beispiel #14
0
        private void Apply()
        {
            TSLog.Log(LogCategory.Info, "Clearing current output directory.");
            TypeSafeUtil.Clean();

            Settings.Instance.OutputDirectory = _newPath;
            Settings.Instance.Save();

            TSLog.Log(LogCategory.Info, "Queuing scan.");
            TypeSafeApi.QueueRefresh();
        }
        public TypeSafeDataUnit GetTypeSafeDataUnit()
        {
            var data = new List <TypeSafeDataEntry>();

            TSLog.Log(LogCategory.Scanner, "Beginning Scene Scan");

            var i = 0;

            var scenes = new List <string>();

            foreach (var scene in EditorBuildSettings.scenes)
            {
                if (!Settings.Instance.IncludeNonActiveScenes && !scene.enabled)
                {
                    continue;
                }

                if (scenes.Any(p => p == scene.path))
                {
                    TSLog.Log(LogCategory.Scanner, string.Format("Duplicate Scene: {0}, {1}", i, scene.path));
                    continue;
                }

                var name = Path.GetFileNameWithoutExtension(scene.path);

                TSLog.Log(LogCategory.Scanner, string.Format("Scene: {0} (name={1}, isEnabled: {2})", scene.path, name, scene.enabled));

                if (string.IsNullOrEmpty(name))
                {
                    TSLog.LogWarning(LogCategory.Scanner, "Scene name is empty, skipping.");
                    continue;
                }

                scenes.Add(scene.path);

                var warning = scene.enabled ? null : Strings.Warning_NonActiveScene;

                data.Add(new TypeSafeDataEntry(name, new object[] { name, scene.enabled ? i : -1 },
                                               obsoleteWarning: warning));

                if (scene.enabled)
                {
                    i++;
                }
            }

            TSLog.Log(LogCategory.Scanner, "Scene Scan Complete");

            return(new TypeSafeDataUnit(TypeSafeUtil.GetFinalClassName(Strings.ScenesTypeName), typeof(Scene), data,
                                        true,
                                        "Scenes"));
        }
        public static void ClearCache()
        {
            TSLog.Log(LogCategory.Trace, "[AssetTypeCache] Clearing Asset Type Cache");
            if (_typeCache != null)
            {
                _typeCache.Clear();
            }

            if (TypeCache.Instance != null)
            {
                TypeCache.Instance.Contents = new TypeCacheEntry[0];
                TypeCache.Instance.Save();
            }
        }
Beispiel #17
0
        /// <summary>
        /// 增加系统日志
        /// <param name="data">数据库连接</param>
        /// <param name="tsLog">系统日志</param>
        /// </summary>
        public override void Add(DataAccess data, TSLog tsLog)
        {
            string strSQL = "insert into TSLog (logId,userId,userName,deptId,deptName,moduleName,userEvent) values (@logId,@userId,@userName,@deptId,@deptName,@moduleName,@userEvent)";
            Param  param  = new Param();

            param.Clear();
            param.Add("@logId", tsLog.logId);           //日志编号{【修改】数据库序列号}
            param.Add("@userId", tsLog.userId);         //用户编号
            param.Add("@userName", tsLog.userName);     //用户姓名
            param.Add("@deptId", tsLog.deptId);         //部门编号
            param.Add("@deptName", tsLog.deptName);     //部门名称
            param.Add("@moduleName", tsLog.moduleName); //模块名称
            param.Add("@userEvent", tsLog.userEvent);   //操作事件
            //param.Add("@createDate", tsLog.createDate);//操作时间{【修改】数据库系统时间}
            data.ExecuteNonQuery(CommandType.Text, strSQL, param);
        }
Beispiel #18
0
 /// <summary>
 /// 修改系统日志
 /// </summary>
 /// <param name="tsLog">系统日志</param>
 public virtual void Edit(TSLog tsLog)
 {
     try
     {
         db.Open();
         Edit(db, tsLog);
     }
     catch (Exception e)
     {
         throw e;
     }
     finally
     {
         db.Close();
     }
 }
Beispiel #19
0
        /// <summary>
        /// 修改系统日志
        /// </summary>
        /// <param name="data">数据库连接</param>
        /// <param name="tsLog">系统日志</param>
        public virtual void Edit(DataAccess data, TSLog tsLog)
        {
            string strSQL = "update TSLog set userId=@userId,userName=@userName,deptId=@deptId,deptName=@deptName,moduleName=@moduleName,userEvent=@userEvent,createDate=To_date(@createDate,'yyyy-mm-dd hh24:mi:ss') where logId=@logId";
            Param  param  = new Param();

            param.Clear();
            param.Add("@userId", tsLog.userId);         //用户编号
            param.Add("@userName", tsLog.userName);     //用户姓名
            param.Add("@deptId", tsLog.deptId);         //部门编号
            param.Add("@deptName", tsLog.deptName);     //部门名称
            param.Add("@moduleName", tsLog.moduleName); //模块名称
            param.Add("@userEvent", tsLog.userEvent);   //操作事件
            param.Add("@createDate", tsLog.createDate); //操作时间
            param.Add("@logId", tsLog.logId);           //日志编号
            data.ExecuteNonQuery(CommandType.Text, strSQL, param);
        }
 private static void Init()
 {
     try
     {
         _sortingLayerNamesProperty = typeof(InternalEditorUtility).GetProperty("sortingLayerNames",
                                                                                BindingFlags.Static | BindingFlags.NonPublic);
         _sortingLayerUniqueIdsProperty = typeof(InternalEditorUtility).GetProperty("sortingLayerUniqueIDs",
                                                                                    BindingFlags.Static | BindingFlags.NonPublic);
     }
     catch (Exception e)
     {
         TSLog.LogError(LogCategory.Info,
                        "Error accessing sorting layers. See TypeSafe.log for more information.");
         TSLog.LogError(LogCategory.Trace, e.ToString());
     }
 }
Beispiel #21
0
        protected DataAccess db = new DataAccess(DataAccess.DBConn);//数据库连接

        #region 代码生成器自动生成


        /// <summary>
        /// 增加系统日志
        /// </summary>
        /// <param name="data">数据库连接</param>
        /// <param name="tsLog">系统日志</param>
        public virtual void Add(DataAccess data, TSLog tsLog)
        {
            string strSQL = "insert into TSLog (logId,userId,userName,deptId,deptName,moduleName,userEvent,createDate) values (@logId,@userId,@userName,@deptId,@deptName,@moduleName,@userEvent,To_date(@createDate,'yyyy-mm-dd hh24:mi:ss'))";
            Param  param  = new Param();

            param.Clear();
            param.Add("@logId", tsLog.logId);           //日志编号
            param.Add("@userId", tsLog.userId);         //用户编号
            param.Add("@userName", tsLog.userName);     //用户姓名
            param.Add("@deptId", tsLog.deptId);         //部门编号
            param.Add("@deptName", tsLog.deptName);     //部门名称
            param.Add("@moduleName", tsLog.moduleName); //模块名称
            param.Add("@userEvent", tsLog.userEvent);   //操作事件
            param.Add("@createDate", tsLog.createDate); //操作时间
            data.ExecuteNonQuery(CommandType.Text, strSQL, param);
        }
Beispiel #22
0
 /// <summary>
 /// 增加系统日志
 /// <param name="tsLog">系统日志</param>
 /// </summary>
 public void Add(TSLog tsLog)
 {
     try
     {
         db.Open();
         Add(db, tsLog);
     }
     catch (Exception e)
     {
         throw e;
     }
     finally
     {
         db.Close();
     }
 }
        public static string GetSafeName(string name, bool suppressWarning = false, bool checkReserved = true)
        {
            var n = GetSafeNameInternal(name);

            if (checkReserved && IsReservedName(n))
            {
                if (!suppressWarning)
                {
                    TSLog.LogWarning(LogCategory.Compile,
                                     string.Format("\"{0}\" is reserved by TypeSafe. Will have underscore prefixed. [{1}] -> [_{2}]", n, name, n));
                }

                n = "_" + n;
            }

            return(n);
        }
Beispiel #24
0
 void Update()
 {
     for (int i = 0; i < mAuthingConnections.Count;)
     {
         AuthingConnection uc = mAuthingConnections[i];
         if ((uc.timer -= Time.deltaTime) <= 0f)
         {
             TSLog.InfoFormat("remove auth timeout connection:{0}", uc.connection.RemoteEndPoint);
             uc.connection.Disconnect("auth timeout");
             mAuthingConnections.RemoveAt(i);
         }
         else
         {
             ++i;
         }
     }
 }
        public TypeSafeDataUnit GetTypeSafeDataUnit()
        {
            var rootUnit = new TypeSafeDataUnit(TypeSafeUtil.GetFinalClassName(Strings.AudioMixersName)
                                                , typeof(float), new List <TypeSafeDataEntry>(), false, "AudioMixers");

            var mixers = Settings.Instance.AudioMixers;

            foreach (var guid in mixers)
            {
                var assetPath = AssetDatabase.GUIDToAssetPath(guid);
                var asset     = AssetDatabase.LoadAssetAtPath <AudioMixer>(assetPath);

                TSLog.Log(LogCategory.Trace, string.Format("AudioMixer: {0}", assetPath), asset);
                rootUnit.NestedUnits.Add(CreateMixerDataUnit(new AudioMixerControllerWrapper(asset)));
            }

            return(rootUnit);
        }
Beispiel #26
0
 /// <summary>
 /// 记录日志
 /// </summary>
 /// <param name="userEvent">用户操作</param>
 public void Log(string userEvent)
 {
     try
     {
         TSLog tsLog = new TSLog();
         tsLog.logId      = commonDao.GetMaxNo("TSModule", "", 6);
         tsLog.deptId     = this.deptId;
         tsLog.deptName   = this.deptName;
         tsLog.userId     = this.userId;
         tsLog.userName   = this.userName;
         tsLog.moduleName = this.moduleName;
         tsLog.userEvent  = userEvent;
         new TSLogDAO().Add(tsLog);
     }
     catch
     {
     }
 }
        private TypeSafeDataUnit CreateAnimatorDataUnit(AnimatorController controller)
        {
            var unit = new TypeSafeDataUnit(controller.name, typeof(string));

            var parametersUnit = new TypeSafeDataUnit("Parameters", typeof(int));

            foreach (var param in controller.parameters)
            {
                TSLog.Log(LogCategory.Trace, string.Format("Parameter: {0} ({1})", param.name, param.nameHash));

                if (parametersUnit.Data.Any(p => p.PropertyName == param.name))
                {
                    TSLog.LogWarning(LogCategory.Compile, string.Format("[AnimatorController] Duplicate parameter name ({0}).", param.name), controller);
                    continue;
                }

                parametersUnit.Data.Add(new TypeSafeDataEntry(param.name, new object[] { param.nameHash }));
            }

            var layersUnit = new TypeSafeDataUnit("Layers", typeof(int));

            for (var i = 0; i < controller.layers.Length; i++)
            {
                var layer = controller.layers[i];
                TSLog.Log(LogCategory.Trace, string.Format("Layer: {0}, Index: {1}", layer.name, i));

                if (layersUnit.Data.Any(p => p.PropertyName == layer.name))
                {
                    TSLog.LogWarning(LogCategory.Compile, string.Format("[AnimatorController] Duplicate layer name ({0}).", layer.name),
                                     controller);
                    continue;
                }

                layersUnit.Data.Add(new TypeSafeDataEntry(layer.name, new object[] { i }));
            }

            unit.NestedUnits.Add(parametersUnit);
            unit.NestedUnits.Add(layersUnit);

            return(unit);
        }
Beispiel #28
0
        /// <summary>
        /// 读取系统日志信息
        /// </summary>
        /// <param name="dr">记录指针</param>
        /// <returns>系统日志对象</returns>
        protected virtual TSLog ReadData(ComDataReader dr)
        {
            TSLog tsLog = new TSLog();

            tsLog.logId      = dr["logId"].ToString();      //日志编号
            tsLog.userId     = dr["userId"].ToString();     //用户编号
            tsLog.userName   = dr["userName"].ToString();   //用户姓名
            tsLog.deptId     = dr["deptId"].ToString();     //部门编号
            tsLog.deptName   = dr["deptName"].ToString();   //部门名称
            tsLog.moduleName = dr["moduleName"].ToString(); //模块名称
            tsLog.userEvent  = dr["userEvent"].ToString();  //操作事件
            if (dr["createDate"] == null)
            {
                tsLog.createDate = "";//操作时间
            }
            else
            {
                tsLog.createDate = string.Format("{0:yyyy-MM-dd HH:mm:ss}", dr["createDate"]);//操作时间
            }
            return(tsLog);
        }
        private TypeSafeDataUnit CreateMixerDataUnit(AudioMixerControllerWrapper wrapper)
        {
            var unit = new TypeSafeDataUnit(wrapper.Mixer.name, typeof(string));

            var parametersUnit = new TypeSafeDataUnit("Parameters", typeof(string));

            foreach (var param in wrapper.exposedParameters)
            {
                TSLog.Log(LogCategory.Trace, string.Format("Parameter: {0}", param.name));

                if (parametersUnit.Data.Any(p => p.PropertyName == param.name))
                {
                    TSLog.LogWarning(LogCategory.Compile, string.Format("[AudioMixer] Duplicate parameter name ({0}).", param.name), wrapper.Mixer);
                    continue;
                }

                parametersUnit.Data.Add(new TypeSafeDataEntry(param.name, new object[] { param.name }));
            }

            var snapshotsUnit = new TypeSafeDataUnit("Snapshots", typeof(string));

            foreach (var snapshot in wrapper.snapshots)
            {
                TSLog.Log(LogCategory.Trace, string.Format("Snapshot: {0}", snapshot.name));

                if (snapshotsUnit.Data.Any(p => p.PropertyName == snapshot.name))
                {
                    TSLog.LogWarning(LogCategory.Compile, string.Format("[AudioMixer] Duplicate snapshot name ({0}).", snapshot.name), wrapper.Mixer);
                    continue;
                }

                snapshotsUnit.Data.Add(new TypeSafeDataEntry(snapshot.name, new object[] { snapshot.name }));
            }

            unit.NestedUnits.Add(parametersUnit);
            unit.NestedUnits.Add(snapshotsUnit);

            return(unit);
        }
        public TypeSafeDataUnit GetTypeSafeDataUnit()
        {
            var unit = new TypeSafeDataUnit(TypeSafeUtil.GetFinalClassName(Strings.TagsTypeName), typeof(string));
            var tags = InternalEditorUtility.tags;

            foreach (var tag in tags)
            {
                var ignore = string.IsNullOrEmpty(tag) || tag.Trim().Length == 0;

                TSLog.Log(LogCategory.Scanner, string.Format("Tag: {0}, (ignore={1})", tag, ignore));

                if (!ignore)
                {
                    unit.Data.Add(new TypeSafeDataEntry(tag, new object[] { tag }));
                }
            }

            unit.EnableAllProperty = true;
            unit.FileName          = "Tags";

            return(unit);
        }