private void OnEditorUpdate() { TypeSafeUtil.ReportCodeRefreshCompleted(); Settings settings = Settings.Instance; if (settings == null) { return; } if (!WelcomeWindow.HasOpenedBefore() || !settings.HasShownWelcome) { TSLog.Log(LogCategory.Trace, string.Format("Opening welcome window (HasOpenedBefore={0}, HasShownWelcome={1})", WelcomeWindow.HasOpenedBefore(), settings.HasShownWelcome)); WelcomeWindow.Open(); } else if (WelcomeWindow.GetPreviousOpenedVersion() != Strings.Version) { TSLog.Log(LogCategory.Trace, string.Format("Opening changelog window (previousVersion={0}, currentVersion={1})", WelcomeWindow.GetPreviousOpenedVersion(), Strings.Version)); WelcomeWindow.Open(true); TSLog.Log(LogCategory.Trace, "Clearing AssetTypeCache (new TypeSafe version detected)"); AssetTypeCache.ClearCache(); } Step(); }
private void OnDisable() { TSLog.Log(LogCategory.Trace, "TypeSafeController.OnDisable"); TypeSafeUtil.ReportCodeRefreshStarted(); if (State != States.Idle) { Cancel(); Queue(); } TSLog.CloseLog(); }
private void OnEnable() { TSLog.Log(LogCategory.Trace, string.Format("TypeSafeController.OnEnable (Version={0}, ", Strings.Version) + string.Format("UnityVersion={0}, ", Application.unityVersion) + string.Format("TypeSafePath={0}, ", PathUtility.GetTypeSafePath()) + string.Format("TypeSafeEditorPath={0})", PathUtility.GetTypeSafeEditorPath())); _instance = this; TypeSafeUtil.EnsureCorrectUnityVersion(); EditorApplication.update += OnEditorUpdate; }
private static TypeCache GetInstance(bool autoCreate) { if (!TypeSafeUtil.IsEnabled()) { throw new InvalidOperationException( "Attempted to create settings instance while TypeSafe is disabled. Something should be checking TypeSafeUtil.IsEnabled() before running."); } var cachePath = PathUtility.GetTypeCachePath(); TSLog.Log(LogCategory.Trace, string.Format("Checking for TypeCache asset at {0}", cachePath)); var fileExists = File.Exists(cachePath); var instance = AssetDatabase.LoadAssetAtPath <TypeCache>(cachePath); if (instance == null && fileExists) { TSLog.Log(LogCategory.Trace, "TypeCache asset exists, but AssetDatabase doesn't know it. Likely project reimport in progress."); return(null); } if (instance == null) { TSLog.Log(LogCategory.Trace, string.Format("TypeCache asset not found at {0} (fileExists={1}, instance=null)", cachePath, fileExists)); if (!autoCreate) { return(null); } // Create instance instance = CreateInstance <TypeCache>(); TSLog.Log(LogCategory.Info, string.Format("Creating TypeCache asset at {0}", cachePath)); try { AssetDatabase.CreateAsset(instance, cachePath); } catch (Exception e) { TSLog.LogError(LogCategory.Info, "Error creating TypeCache asset."); TSLog.LogError(LogCategory.Info, e.ToString()); } } return(instance); }
private void BeginScan() { if (_state != States.Idle && _state != States.ScanQueued) { throw new InvalidOperationException(); } TSLog.BeginBuffer(LogCategory.Compile); TSLog.Log(LogCategory.Trace, "BeginScan"); TypeSafeUtil.CheckForRemovedAssets(); _stopwatch.Reset(); _stopwatch.Start(); _scanController = new ScanController(); _scanController.Begin(); _state = States.Scanning; }
/// <summary> /// Format a string with the class prefix/suffix specified in the Settings window. /// </summary> /// <param name="baseName"></param> /// <returns>A string in the format {prefix}{baseName}{suffix}</returns> public static string FormatTypeName(string baseName) { return(TypeSafeUtil.GetFinalClassName(baseName)); }
private static void DoCompile(CompileParameters p) { using (var provider = new CSharpCodeProvider()) { var compileUnits = new List <CodeCompileUnit>(); if (p.ResourceDatabase != null) { var compiler = new ResourceCompiler(); compiler.ClassName = TypeSafeUtil.GetFinalClassName(Strings.ResourcesTypeName); compiler.Namespace = Settings.Instance.Namespace; try { var u = compiler.Compile(p.ResourceDatabase); compileUnits.Add(u); } catch (Exception e) { TSLog.LogError(LogCategory.Compile, "Exception occured while compiling resources unit."); TSLog.LogError(LogCategory.Compile, e.ToString()); } } if (p.DataUnits != null) { var compiler = new DataUnitCompiler(); compiler.Namespace = Settings.Instance.Namespace; foreach (var dataUnit in p.DataUnits) { try { compileUnits.Add(compiler.Compile(dataUnit)); } catch (Exception e) { TSLog.LogError(LogCategory.Compile, string.Format("Exception occured while compiling data unit {0}", dataUnit.ClassName)); TSLog.LogError(LogCategory.Compile, e.ToString()); } } } var results = new List <string>(); var didSucceed = false; switch (p.CompileMode) { case CompileModes.Dll: string path; didSucceed = CompileToDll(provider, compileUnits, p, out path); results.Add(path); break; case CompileModes.SourceFiles: IList <string> r; didSucceed = CompileToSourceFiles(provider, compileUnits, p, out r); results.AddRange(r); break; } if (p.OnComplete != null) { p.OnComplete(didSucceed, results); } } }
private IEnumerable ScanProcess() { TSLog.Log(LogCategory.Scanner, "ScanController.ScanProcess start"); ResourceDatabase db; var sw = new Stopwatch(); sw.Start(); using (var scanIterator = ResourceScanProcess().GetEnumerator()) { while (scanIterator.MoveNext()) { if (sw.Elapsed.TotalSeconds > MaxUpdateProcessingTime) { TSLog.Log(LogCategory.Scanner, "ScanProcess Suspending"); Resources.UnloadUnusedAssets(); sw.Stop(); sw.Reset(); yield return(null); sw.Start(); } } db = scanIterator.Current; } var dataUnits = new List <TypeSafeDataUnit>(); TSLog.Log(LogCategory.Scanner, "Beginning ITypeSafeDataSource hooks"); foreach (var dataSource in TypeSafeUtil.GetCustomDataSources()) { if (Settings.Instance.DisabledDataSources.Contains(dataSource.GetType().AssemblyQualifiedName)) { TSLog.Log(LogCategory.Scanner, string.Format("Skipping {0}", dataSource.GetType().FullName)); continue; } TSLog.Log(LogCategory.Scanner, string.Format("Processing {0}", dataSource.GetType().FullName)); try { var data = dataSource.GetTypeSafeDataUnit(); if (ValidateDataUnit(data)) { dataUnits.Add(data); } } catch (Exception e) { TSLog.LogError(LogCategory.Info, string.Format("Exception occured inside data source ({0})", dataSource.GetType().FullName)); TSLog.LogError(LogCategory.Info, e.ToString()); } } TSLog.Log(LogCategory.Scanner, "Done running ITypeSafeDataSource hooks"); Result = new ScanResult(db, dataUnits); TSLog.Log(LogCategory.Scanner, "ScanProcess Done"); IsDone = true; WasSuccessful = true; }
private bool ValidateDataUnit(TypeSafeDataUnit unit, bool isNested = false) { if (string.IsNullOrEmpty(unit.ClassName) || string.IsNullOrEmpty(unit.ClassName.Trim())) { TSLog.LogError(LogCategory.Compile, string.Format("Error validating TypeSafeDataUnit ({0})", unit.ClassName)); TSLog.LogError(LogCategory.Compile, Strings.Error_NameMustNotBeEmpty); return(false); } string errorMessage; if (!isNested && !TypeSafeUtil.ValidateTypeName(unit.ClassName, out errorMessage)) { TSLog.LogError(LogCategory.Compile, string.Format("Error validating TypeSafeDataUnit ({0})", unit.ClassName)); TSLog.LogError(LogCategory.Compile, errorMessage); return(false); } if (!isNested && !TypeSafeUtil.TestTypeNameConflicts(unit.ClassName)) { TSLog.LogError(LogCategory.Compile, string.Format("Error validating TypeSafeDataUnit ({0})", unit.ClassName)); TSLog.LogError(LogCategory.Compile, Strings.Error_ConflictsWithExistingType); return(false); } foreach (var nestedUnit in unit.NestedUnits) { if (!ValidateDataUnit(nestedUnit, true)) { return(false); } } foreach (var data in unit.Data) { if (string.IsNullOrEmpty(data.PropertyName.Trim())) { TSLog.LogError(LogCategory.Compile, "Error validating data entry"); TSLog.LogError(LogCategory.Compile, Strings.Error_NameMustNotBeEmpty); return(false); } var dataType = /*data.OverrideDataType ??*/ unit.DataType; if ((dataType.IsPrimitive || dataType == typeof(string)) && data.Parameters.Length == 1 && data.Parameters[0] != null && data.Parameters[0].GetType() == dataType) { continue; } foreach (var parameter in data.Parameters) { if (parameter == null) { TSLog.LogError(LogCategory.Compile, "Data parameter must not be null"); return(false); } var pType = parameter.GetType(); if (pType.IsPrimitive) { continue; } if (pType == typeof(string)) { continue; } TSLog.LogError(LogCategory.Compile, "Data constructor parameter must be primitive or string"); return(false); } var pTypeArray = data.Parameters.Select(p => p.GetType()).ToArray(); var constructor = dataType.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, pTypeArray, null); if (constructor == null) { var sig = string.Join(", ", pTypeArray.Select(p => p.FullName).ToArray()); TSLog.LogError(LogCategory.Compile, string.Format("Data Type does not have constructor that matches provided data ({0})", sig)); } } return(true); }
private void Step() { switch (State) { case States.Idle: break; case States.ScanQueued: if (!TypeSafeUtil.ShouldBeOperating()) { break; } BeginScan(); break; case States.Scanning: if (_scanController == null) { TSLog.LogError(LogCategory.Trace, "ScanController = null, but State = Scanning"); _state = States.Idle; break; } if (!TypeSafeUtil.ShouldBeOperating()) { TSLog.Log(LogCategory.Trace, "Aborting scan due to script reload in progress."); Cancel(); Queue(); break; } _scanController.Update(); ItemsCompleted = _scanController.ItemsCompleted; TotalItems = _scanController.TotalItems; if (_scanController.IsDone) { TSLog.Log(LogCategory.Trace, string.Format("Scan complete (took {0}s).", _stopwatch.Elapsed.TotalSeconds)); if (_scanController.WasSuccessful) { _scanResult = _scanController.Result; _scanController = null; BeginCompile(); } else { TSLog.LogError(LogCategory.Info, "Error occured while scanning. Aborting process."); _state = States.Idle; } } break; case States.Compiling: case States.Waiting: if (_compileController == null) { TSLog.LogError(LogCategory.Trace, "CompileController = null, but State = Compiling"); _state = States.Idle; break; } if (!TypeSafeUtil.ShouldBeOperating()) { TSLog.Log(LogCategory.Trace, "Aborting compile."); Cancel(); Queue(); break; } if (_compileController.IsDone) { if (_state != States.Waiting) { // Perform a dry run of the deploy step to see if there were any changes since the last compile int changeCount; TypeSafeUtil.DeployBuildArtifacts(_compileController.Output, out changeCount, true); // Delay for minimum build time if not user initiated and there were changes if (Settings.Instance.EnableWaiting && changeCount > 0 && !_userInitiated && _stopwatch.Elapsed.TotalSeconds < Settings.Instance.MinimumBuildTime) { _state = States.Waiting; break; } } else { // Wait for wait stage to elapse if (!_abortWait && _stopwatch.Elapsed.TotalSeconds < Settings.Instance.MinimumBuildTime) { break; } } _abortWait = false; TSLog.Log(LogCategory.Trace, string.Format("Compile Complete (WasSuccessful={0})", _compileController.WasSuccessful)); if (_compileController.WasSuccessful) { int updatedFileCount; var deployResult = TypeSafeUtil.DeployBuildArtifacts(_compileController.Output, out updatedFileCount); TSLog.Log(LogCategory.Trace, string.Format("Deploy Complete (WasSuccessful={0}, updatedFileCount={1})", deployResult, updatedFileCount)); var shouldReport = _userInitiated || updatedFileCount > 0; TSLog.EndBuffer(LogCategory.Compile, shouldReport); if (!deployResult) { TSLog.LogError(LogCategory.Info, "Compile failed."); } else if (shouldReport) { if (updatedFileCount == 0) { TSLog.Log(LogCategory.Info, "Compile complete, no changes."); } else { TSLog.Log(LogCategory.Info, string.Format("Compile completed. (Took {0}s)", _stopwatch.Elapsed.Seconds)); } } } _compileController = null; _state = States.Idle; } break; } }