public override IEnumerable <ValidationProfileResult> Validate(ValidationRunner runner) { var assetPaths = this.GetAllAssetsToValidate().ToList(); var step = 1f / assetPaths.Count; for (int i = 0; i < assetPaths.Count; i++) { var path = assetPaths[i]; var progress = step * i; var assetsAtPath = this.LoadAllAssetsAtPathProperly(path); foreach (var loadInfo in assetsAtPath) { if (loadInfo.Type == LoadedAssetInfo.AssetType.Normal) { List <ValidationResult> results = null; runner.ValidateUnityObjectRecursively(loadInfo.Asset, ref results); yield return(new ValidationProfileResult() { Profile = this, Progress = progress, Name = Path.GetFileName(path), Source = loadInfo.Asset, Results = results, SourceRecoveryData = loadInfo.Asset, Path = path, }); } else if (loadInfo.Type == LoadedAssetInfo.AssetType.BrokenComponent) { yield return(new ValidationProfileResult() { Profile = this, Progress = progress, Name = Path.GetFileName(path), Source = loadInfo.OwningGO, Results = new List <ValidationResult>() { new ValidationResult() { Message = object.ReferenceEquals(loadInfo.BrokenComponent, null) ? "Broken Component: a component at index '" + loadInfo.ComponentIndex + "' is null on the GameObject '" + loadInfo.OwningGO.name + "'! A script reference is likely broken." : "Broken Component: a component of type '" + loadInfo.BrokenComponent.GetType().GetNiceName() + "' at index '" + loadInfo.ComponentIndex + "' is null on the GameObject '" + loadInfo.OwningGO.name + "'! A script reference is likely broken.", ResultType = ValidationResultType.Error, } }, SourceRecoveryData = loadInfo.OwningGO, Path = path, }); } else { throw new NotImplementedException(loadInfo.Type.ToString()); } } } }
public override IEnumerable <ValidationProfileResult> Validate(ValidationRunner runner) { List <string> assetPaths = this.GetAllAssetsToValidate().ToList(); float step = 1f / assetPaths.Count; for (int i = 0; i < assetPaths.Count; i++) { string path = assetPaths[i]; float progress = step * i; UnityEngine.Object[] assetsAtPath = AssetDatabase.LoadAllAssetsAtPath(path); foreach (UnityEngine.Object asset in assetsAtPath) { List <ValidationResult> results = null; runner.ValidateUnityObjectRecursively(asset, ref results); yield return(new ValidationProfileResult() { Profile = this, Progress = progress, Name = Path.GetFileName(path), Source = asset, Results = results, SourceRecoveryData = asset, }); } } }
protected override void Initialize() { this.menuTreeWidth = this.GetPersistentValue <float>("menuTreeWidth", 320); this.overviewHeight = this.GetPersistentValue <float>("overviewHeight", 300); this.columns = new List <ResizableColumn>() { ResizableColumn.FlexibleColumn(this.menuTreeWidth.Value, 80), ResizableColumn.DynamicColumn(0, 200) }; this.runner = new ValidationRunner(); this.overview = new ValidationOverview(); this.editor = this.ValueEntry.SmartValue; this.profile = this.editor.Profile; this.sourceProperty = this.Property.Children["selectedSourceTarget"]; this.validationProfileTree = new ValidationProfileTree(); this.overviewToggle = this.GetPersistentValue <bool>("overviewToggle", true); this.validationProfileTree.Selection.SelectionChanged += (x) => { if (x == SelectionChangedType.ItemAdded) { var value = this.validationProfileTree.Selection.SelectedValue; var result = value as ValidationProfileResult; if (result != null) { this.editor.SetTarget(result.GetSource()); } else { this.editor.SetTarget(value); } } }; this.overview.OnProfileResultSelected += result => { var mi = this.validationProfileTree.GetMenuItemForObject(result); mi.Select(); var source = result.GetSource(); this.editor.SetTarget(source); }; this.validationProfileTree.AddProfileRecursive(this.ValueEntry.SmartValue.Profile); OdinMenuTree.ActiveMenuTree = this.validationProfileTree; if (this.editor.ScanProfileImmediatelyWhenOpening) { this.editor.ScanProfileImmediatelyWhenOpening = false; this.ScanProfile(this.editor.Profile); } }
public override IEnumerable <ValidationProfileResult> Validate(ValidationRunner runner) { var partialProgress = 0f; var partialProgressStepSize = 1f / this.Profiles.Length; for (int i = 0; i < this.Profiles.Length; i++) { IValidationProfile profile = this.Profiles[i]; foreach (var result in profile.Validate(runner)) { result.Progress = result.Progress * partialProgressStepSize + partialProgress; yield return(result); } partialProgress += partialProgressStepSize; } }
public void OnHookExecuting() { using (var runner = new ValidationRunner()) { bool stopTriggeringEvent = false; try { foreach (var validation in this.Validations) { bool openValidatorWindow = false; IValidationProfile actuallyFailingProfile = null; try { foreach (var profile in validation.ProfilesToRun) { foreach (var result in profile.Validate(runner)) { if (GUIHelper.DisplaySmartUpdatingCancellableProgressBar("Executing Validation Hook: " + this.Name + " (Profile: " + profile.Name + ")", result.Name, result.Progress)) { // Cancel validation return; } foreach (var subResult in result.Results) { bool couldExitFromFailure = false; if (subResult.ResultType == ValidationResultType.Error) { if (validation.HasActionFlag(AutomatedValidation.Action.LogError)) { var source = result.GetSource() as UnityEngine.Object; Debug.LogError("Validation error on object '" + source + "', path '" + subResult.Path + "': " + subResult.Message, source); } if (validation.HasActionFlag(AutomatedValidation.Action.OpenValidatorIfError)) { openValidatorWindow = true; couldExitFromFailure = true; } if (validation.HasActionFlag(AutomatedValidation.Action.StopHookEventOnError)) { stopTriggeringEvent = true; couldExitFromFailure = true; } } else if (subResult.ResultType == ValidationResultType.Warning) { if (validation.HasActionFlag(AutomatedValidation.Action.LogWarning)) { var source = result.GetSource() as UnityEngine.Object; Debug.LogWarning("Validation warning on object '" + source + "', path '" + subResult.Path + "': " + subResult.Message, source); } if (validation.HasActionFlag(AutomatedValidation.Action.OpenValidatorIfWarning)) { openValidatorWindow = true; couldExitFromFailure = true; } if (validation.HasActionFlag(AutomatedValidation.Action.StopHookEventOnWarning)) { stopTriggeringEvent = true; couldExitFromFailure = true; } } if (couldExitFromFailure) { actuallyFailingProfile = profile; if (!this.FinishValidationOnFailures) { return; } } } } } } finally { if (openValidatorWindow) { if (this.Hook is OnPlayValidationHook) { stopTriggeringEvent = true; } this.OpenValidator(validation.ProfilesToRun, actuallyFailingProfile); } if (stopTriggeringEvent) { this.Hook.StopTriggeringEvent(); } } } } finally { EditorUtility.ClearProgressBar(); } } }
public override IEnumerable <ValidationProfileResult> Validate(ValidationRunner runner) { if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) { yield break; } var selection = Selection.objects; var scenesToTest = this.GetAllScenes().ToList(); var setup = EditorSceneManager.GetSceneManagerSetup(); var partialProgress = 0f; var partialProgressStepSize = 1f / (scenesToTest.Count + (this.IncludeAssetDependencies ? 1 : 0)); try { for (int i = 0; i < scenesToTest.Count; i++) { var scene = scenesToTest[i]; EditorSceneManager.OpenScene(scene, OpenSceneMode.Single); var gameObjectsToScan = Resources.FindObjectsOfTypeAll <Transform>() .Where(x => (x.gameObject.scene.IsValid() && (x.gameObject.hideFlags & HideFlags.HideInHierarchy) == 0)) //.SelectMany(x => x.GetComponents(typeof(Component)).Select(c => new { go = x.gameObject, component = c })) .ToList(); var step = 1f / gameObjectsToScan.Count; for (int j = 0; j < gameObjectsToScan.Count; j++) { var go = gameObjectsToScan[j].gameObject; var progress = j * step * partialProgressStepSize + partialProgress; { var result = runner.ValidateUnityObjectRecursively(go); var entry = new ValidationProfileResult() { Name = go.name, Profile = this, Source = go, Results = result, Progress = progress, SourceRecoveryData = this.GetRecoveryData(go, null, scene), }; yield return(entry); } var components = go.GetComponents <Component>(); for (int k = 0; k < components.Length; k++) { var component = components[k]; if (component == null) { var entry = new ValidationProfileResult() { Name = "Broken Component", Source = go, SourceRecoveryData = this.GetRecoveryData(go, component, scene), Profile = this, Progress = progress, Results = new List <ValidationResult>() { new ValidationResult() { Message = object.ReferenceEquals(component, null) ? "Broken Component (A component is null on the GameObject '" + go.name + "'! A script reference is likely broken.)" : "Broken Component (A component of type '" + component.GetType().GetNiceName() + "' is null on the GameObject '" + go.name + "'! A script reference is likely broken.)", ResultType = ValidationResultType.Error, } } }; yield return(entry); } else { var result = runner.ValidateUnityObjectRecursively(component); var entry = new ValidationProfileResult() { Name = go.name + " - " + component.GetType().GetNiceName().SplitPascalCase(), Profile = this, Source = component, Results = result, Progress = progress, SourceRecoveryData = this.GetRecoveryData(go, component, scene), }; yield return(entry); } } } partialProgress += partialProgressStepSize; } } finally { // Load a new empty scene that will be unloaded immediately, just to be sure we completely clear all changes made by the scan EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); if (setup.Length != 0) { EditorSceneManager.RestoreSceneManagerSetup(setup); } } if (this.IncludeAssetDependencies) { var scenes = scenesToTest .ToHashSet() .Select(x => AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(x)) .ToArray(); var dep = EditorUtility.CollectDependencies(scenes); var components = dep.OfType <Component>().ToList(); var scriptableObjects = dep.OfType <ScriptableObject>().ToList(); var allObjects = components.Cast <UnityEngine.Object>().Concat(scriptableObjects.Cast <UnityEngine.Object>()) .ToArray(); var step = 1f / allObjects.Length; for (int i = 0; i < allObjects.Length; i++) { var obj = allObjects[i]; var progress = i * step * partialProgressStepSize + partialProgress; var result = runner.ValidateUnityObjectRecursively(obj); var entry = new ValidationProfileResult() { Name = obj.name, Profile = this, Source = obj, Results = result, Progress = progress, }; yield return(entry); } } Selection.objects = selection; }
public abstract IEnumerable <ValidationProfileResult> Validate(ValidationRunner runner);
public void Dispose() { this.runner.Dispose(); this.runner = null; }