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"));
        }
예제 #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"));
        }
예제 #3
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();
            }
        }
        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);
        }
        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);
        }
        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);
        }
        private static void LoadCache()
        {
            if (_typeCache != null)
            {
                return;
            }

            TSLog.Log(LogCategory.Trace, "[AssetTypeCache] Loading Asset Type Cache");

            _typeCache = new Dictionary <string, Type>();

            var cache = TypeCache.Instance.Contents;

            if (cache == null)
            {
                return;
            }

            for (var i = 0; i < cache.Length; i++)
            {
                var type = Type.GetType(cache[i].Type, false);

                if (type == null)
                {
                    TSLog.LogWarning(LogCategory.Trace,
                                     string.Format("[AssetTypeCache] Type from cache was not found (path: {0}, type: {1})", cache[i].Path, cache[i].Type));
                    continue;
                }

                if (_typeCache.ContainsKey(cache[i].Path))
                {
                    TSLog.LogError(LogCategory.Trace, string.Format("[AssetTypeCache] Duplicate path in type cache ({0})", cache[i].Path));
                    continue;
                }

                _typeCache.Add(cache[i].Path, type);
            }
        }
        public static void SaveCache()
        {
            if (_typeCache == null)
            {
                return;
            }

            TSLog.Log(LogCategory.Trace, "[AssetTypeCache] Saving Asset Type Cache");

            var l = new List <TypeCacheEntry>(_typeCache.Count);

            foreach (var kv in _typeCache)
            {
                l.Add(new TypeCacheEntry()
                {
                    Path = kv.Key,
                    Type = kv.Value.AssemblyQualifiedName
                });
            }

            TypeCache.Instance.Contents = l.ToArray();
            TypeCache.Instance.Save();
        }
        public TypeSafeDataUnit GetTypeSafeDataUnit()
        {
            var data = new List <TypeSafeDataEntry>();

            var inputManager =
                new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset")[0]);

            var axesArray = inputManager.FindProperty("m_Axes");

            TSLog.Log(LogCategory.Scanner, string.Format("Axes Array: {0}, count: {1}", axesArray, axesArray.arraySize));

            for (var i = 0; i < axesArray.arraySize; i++)
            {
                var entry = axesArray.GetArrayElementAtIndex(i);

                var name = entry.FindPropertyRelative("m_Name").stringValue;

                var hasPositive = !string.IsNullOrEmpty(entry.FindPropertyRelative("positiveButton").stringValue) ||
                                  !string.IsNullOrEmpty(entry.FindPropertyRelative("altPositiveButton").stringValue);

                var hasNegative = !string.IsNullOrEmpty(entry.FindPropertyRelative("negativeButton").stringValue) ||
                                  !string.IsNullOrEmpty(entry.FindPropertyRelative("altNegativeButton").stringValue);

                var isButton = (hasPositive && !hasNegative) || (!hasPositive && hasNegative);

                TSLog.Log(LogCategory.Scanner,
                          string.Format("Input Axis: {0}, hasPositive: {1}, hasNegative: {2}, isButton: {3}", name, hasPositive, hasNegative, isButton));

                if (!data.Any(p => p.PropertyName == name))
                {
                    data.Add(new TypeSafeDataEntry(name, new object[] { name }));
                }
            }

            return(new TypeSafeDataUnit(TypeSafeUtil.GetFinalClassName(Strings.InputTypeName), typeof(InputAxis), data,
                                        false, "Input"));
        }
        public IEnumerable <ResourceDefinition> Scan()
        {
            var paths =
                AssetDatabase.GetAllAssetPaths()
                .Where(p => Path.HasExtension(p) && PathUtility.IsAssetResource(p))
                .ToList();

            TotalAssets = paths.Count;

            foreach (var path in paths)
            {
                var name         = Path.GetFileNameWithoutExtension(path);
                var relativePath = GetResourceRelativePath(path);

                var inBlacklist = PathUtility.IsInBlacklist(path);
                var inWhitelist = PathUtility.IsInWhitelist(path);

                var skip = inBlacklist || (!inWhitelist && Settings.Instance.EnableWhitelist);

                Type type   = null;
                var  source = UnityUtility.TypeSource.None;

                if (!skip)
                {
                    if (!UnityUtility.GetAssetType(path, out type, out source))
                    {
                        TSLog.LogError(LogCategory.Scanner, string.Format("Failed finding type for asset at path {0}", path));
                        continue;
                    }
                }

                var isEditorType = !skip && UnityUtility.IsEditorType(type);
                var isPrivate    = !skip && (type.IsNotPublic && !UnityUtility.IsUserAssemblyType(type));

                TSLog.Log(LogCategory.Scanner,
                          string.Format("Resource [Name: {0}, RelativePath: {1}, FullPath: {2}, Type: {3}, isEditorType: {4}, typeSource: {5}, inBlacklist: {6}, inWhitelist: {7}, isPrivate: {8}]", name, relativePath, path, type != null ? type.FullName : null,
                                        isEditorType, source, inBlacklist, inWhitelist, isPrivate));

                if (isPrivate)
                {
                    TSLog.Log(LogCategory.Scanner, string.Format("Skipping {0} (isPrivate=true)", relativePath));
                    continue;
                }

                // Skip resources that are of an editor-only type
                if (isEditorType)
                {
                    TSLog.Log(LogCategory.Scanner, string.Format("Skipping {0} (isEditorType=true)", relativePath));
                    continue;
                }

                // Skip resources that are of an editor-only type
                if (inBlacklist)
                {
                    TSLog.Log(LogCategory.Scanner, string.Format("Skipping {0} (inBlacklist=true)", relativePath));
                    continue;
                }

                // Skip resources that are not in the white list.
                if (Settings.Instance.EnableWhitelist && !inWhitelist)
                {
                    TSLog.Log(LogCategory.Scanner, string.Format("Skipping {0} (inWhitelist = false)", relativePath));
                    continue;
                }

                if (type == typeof(Texture2D))
                {
                    var importer = AssetImporter.GetAtPath(path) as TextureImporter;

                    if (importer != null && importer.textureType == TextureImporterType.Sprite)
                    {
                        TSLog.Log(LogCategory.Scanner, "Overriding type -> Sprite (importer.textureType == TextureImporterType.Sprite)");
                        type = typeof(Sprite);
                    }
                }

                var resourceDefinition = new ResourceDefinition(name,
                                                                relativePath, path, type);

                yield return(resourceDefinition);
            }
        }
        private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets,
                                                   string[] movedFromAssetPaths)
        {
            // Short-circuit if all the paths are related to TypeSafe. Helps to reduce crashes when updating the DLLs
            if (importedAssets.All(PathUtility.IsTypeSafePath) && deletedAssets.All(PathUtility.IsTypeSafePath) &&
                movedAssets.All(PathUtility.IsTypeSafePath))
            {
                return;
            }

            TSLog.Log(LogCategory.Trace, "TypeSafeAssetPostProcessor.OnPostprocessAllAssets");

            if (!TypeSafeUtil.IsEnabled())
            {
                TSLog.Log(LogCategory.Trace, "OnPostProcessAllAssets, aborting. !IsEnabled()");
                return;
            }

            if (Settings.Instance == null)
            {
                TSLog.Log(LogCategory.Trace, "OnPostProcessAllAssets, aborting. Settings = null, likely AssetDatabase isn't ready yet.");
                return;
            }

            TSLog.Log(LogCategory.Trace, string.Format("Settings: AutoRebuild: {0}, ", Settings.Instance.AutoRebuild) +
                      string.Format("TriggerOnResourceChange={0}, ", Settings.Instance.TriggerOnResourceChange) +
                      string.Format("TriggerOnLayerChange={0}, ", Settings.Instance.TriggerOnLayerChange) +
                      string.Format("TriggerOnInputChange={0}, ", Settings.Instance.TriggerOnInputChange) +
                      string.Format("TriggerOnSceneChange={0}, ", Settings.Instance.TriggerOnSceneChange) +
                      string.Format("TriggerOnAssetChange={0})", Settings.Instance.TriggerOnAssetChange));

            // Check for changes that require deleting entries in the asset type cache
            var changes = 0;

            for (var i = 0; i < importedAssets.Length; i++)
            {
                if (AssetTypeCache.ClearAssetType(importedAssets[i]))
                {
                    changes++;
                }
            }

            for (var i = 0; i < deletedAssets.Length; i++)
            {
                if (AssetTypeCache.ClearAssetType(deletedAssets[i]))
                {
                    changes++;
                }
            }

            for (var i = 0; i < movedFromAssetPaths.Length; i++)
            {
                if (AssetTypeCache.ClearAssetType(movedFromAssetPaths[i]))
                {
                    changes++;
                }
            }

            if (changes > 0)
            {
                TSLog.Log(LogCategory.Trace, string.Format("OnPostProcessAllAssets: Items removed from AssetTypeCache: {0}", changes));
                AssetTypeCache.SaveCache();
            }

            if (!Settings.Instance.AutoRebuild)
            {
                return;
            }

            if (deletedAssets.Length > 0)
            {
                if (TypeSafeUtil.ContainsTypeSafeTrackedAsset(deletedAssets) && Settings.Instance.TriggerOnAssetChange)
                {
                    TSLog.Log(LogCategory.Trace, "Queuing refresh due to asset removal.");
                    TypeSafeController.Instance.Refresh();
                    return;
                }
            }

            if (Settings.Instance.TriggerOnAssetChange && importedAssets.Select(AssetDatabase.AssetPathToGUID).Any(
                    p => Settings.Instance.AudioMixers.Contains(p) ||
                    Settings.Instance.Animators.Contains(p)))
            {
                TSLog.Log(LogCategory.Trace, "Queuing refresh due to asset change.");
                TypeSafeController.Instance.Refresh();
                return;
            }

            if (Settings.Instance.TriggerOnResourceChange &&
                importedAssets.Concat(deletedAssets)
                .Concat(movedAssets)
                .Concat(movedFromAssetPaths)
                .Where(p => !PathUtility.IsInBlacklist(p) && (!Settings.Instance.EnableWhitelist || PathUtility.IsInWhitelist(p)))
                .Any(PathUtility.IsAssetResource))
            {
                TSLog.Log(LogCategory.Trace, "Queuing refresh due to resources change.");
                TypeSafeController.Instance.Refresh();
                return;
            }

            var isSceneChange = importedAssets.Contains("ProjectSettings/EditorBuildSettings.asset");
            var isLayerChange = importedAssets.Contains("ProjectSettings/TagManager.asset");
            var isInputChange = importedAssets.Contains("ProjectSettings/InputManager.asset");

            TSLog.Log(LogCategory.Trace, string.Format("IsLayerChange: {0}, ", isLayerChange) +
                      string.Format("IsSceneChange: {0}, ", isSceneChange) +
                      string.Format("IsInputChange: {0}", isInputChange));

            if (isSceneChange && Settings.Instance.TriggerOnSceneChange)
            {
                TSLog.Log(LogCategory.Trace, "Queuing refresh due to scene change.");
                TypeSafeController.Instance.Refresh();
                return;
            }

            if (isLayerChange && Settings.Instance.TriggerOnLayerChange)
            {
                TSLog.Log(LogCategory.Trace, "Queuing refresh due to layer change.");
                TypeSafeController.Instance.Refresh();
                return;
            }

            if (isInputChange && Settings.Instance.TriggerOnInputChange)
            {
                TSLog.Log(LogCategory.Trace, "Queuing refresh due to input change.");
                TypeSafeController.Instance.Refresh();
            }
        }