-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
Initial working version
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Changelog | ||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
|
||
## [Unreleased] | ||
- Implement a better way display real screen pixel size of sprite renderer | ||
- Implement per Atlas display [On it] | ||
- Replace FullSerializer with something smaller | ||
- Test devices builds to make sure its not adding anything to the project. | ||
- Reload references after code compilation | ||
- Add option to reset specific Sprite Details data (size for instance) | ||
- Rename the project to Sprite Auditor | ||
- Remove old code | ||
|
||
|
||
|
||
|
||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
#if !NO_UNITY | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using FullSerializer.Internal; | ||
using UnityEditor; | ||
using UnityEngine; | ||
|
||
namespace FullSerializer { | ||
[InitializeOnLoad] | ||
public static class PlayStateNotifier { | ||
static PlayStateNotifier() { | ||
EditorApplication.playmodeStateChanged += ModeChanged; | ||
} | ||
|
||
private static void ModeChanged () { | ||
if (!EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying) { | ||
Debug.Log("There are " + fsAotCompilationManager.AotCandidateTypes.Count + " candidate types"); | ||
foreach (fsAotConfiguration target in Resources.FindObjectsOfTypeAll<fsAotConfiguration>()) { | ||
var seen = new HashSet<string>(target.aotTypes.Select(t => t.FullTypeName)); | ||
foreach (Type type in fsAotCompilationManager.AotCandidateTypes) { | ||
if (seen.Contains(type.FullName) == false) { | ||
target.aotTypes.Add(new fsAotConfiguration.Entry(type)); | ||
EditorUtility.SetDirty(target); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
[CustomEditor(typeof(fsAotConfiguration))] | ||
public class fsAotConfigurationEditor : Editor { | ||
[NonSerialized] | ||
private List<Type> _allAotTypes; | ||
private List<Type> allAotTypes { | ||
get { | ||
if (_allAotTypes == null) | ||
_allAotTypes = FindAllAotTypes().ToList(); | ||
return _allAotTypes; | ||
} | ||
} | ||
|
||
private string[] options = new string[] { "On", "Off", "[?]" }; | ||
private int GetIndexForState(fsAotConfiguration.AotState state) { | ||
switch (state) { | ||
case fsAotConfiguration.AotState.Enabled: | ||
return 0; | ||
case fsAotConfiguration.AotState.Disabled: | ||
return 1; | ||
case fsAotConfiguration.AotState.Default: | ||
return 2; | ||
} | ||
|
||
throw new ArgumentException("state is invalid " + state); | ||
} | ||
private fsAotConfiguration.AotState GetStateForIndex(int index) { | ||
switch (index) { | ||
case 0: return fsAotConfiguration.AotState.Enabled; | ||
case 1: return fsAotConfiguration.AotState.Disabled; | ||
case 2: return fsAotConfiguration.AotState.Default; | ||
} | ||
|
||
throw new ArgumentException("invalid index " + index); | ||
} | ||
|
||
private IEnumerable<Type> FindAllAotTypes() { | ||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { | ||
foreach (Type t in assembly.GetTypes()) { | ||
bool performAot = false; | ||
|
||
// check for [fsObject] | ||
{ | ||
var props = t.GetCustomAttributes(typeof(fsObjectAttribute), true); | ||
if (props != null && props.Length > 0) performAot = true; | ||
} | ||
|
||
// check for [fsProperty] | ||
if (!performAot) { | ||
foreach (PropertyInfo p in t.GetProperties()) { | ||
var props = p.GetCustomAttributes(typeof(fsPropertyAttribute), true); | ||
if (props.Length > 0) { | ||
performAot = true; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
if (performAot) | ||
yield return t; | ||
} | ||
} | ||
} | ||
|
||
private enum OutOfDateResult { | ||
NoAot, | ||
Stale, | ||
Current | ||
} | ||
private OutOfDateResult IsOutOfDate(Type type) { | ||
string converterName = fsAotCompilationManager.GetQualifiedConverterNameForType(type); | ||
Type converterType = fsTypeCache.GetType(converterName); | ||
if (converterType == null) | ||
return OutOfDateResult.NoAot; | ||
|
||
// TODO: We should also verify that the type is contained inside of fsConverterRegistrar as | ||
// an additional diagnostic. If it is not, then that means the type will not be used | ||
// at runtime. | ||
|
||
object instance_ = null; | ||
try { | ||
instance_ = Activator.CreateInstance(converterType); | ||
} catch (Exception) {} | ||
if (instance_ is fsIAotConverter == false) | ||
return OutOfDateResult.NoAot; | ||
var instance = (fsIAotConverter)instance_; | ||
|
||
var metatype = fsMetaType.Get(new fsConfig(), type); | ||
if (fsAotCompilationManager.IsAotModelUpToDate(metatype, instance) == false) | ||
return OutOfDateResult.Stale; | ||
|
||
return OutOfDateResult.Current; | ||
} | ||
|
||
private void DrawType(fsAotConfiguration.Entry entry, Type resolvedType) { | ||
var target = (fsAotConfiguration)this.target; | ||
|
||
EditorGUILayout.BeginHorizontal(); | ||
|
||
int currentIndex = GetIndexForState(entry.State); | ||
int newIndex = GUILayout.Toolbar(currentIndex, options, GUILayout.ExpandWidth(false)); | ||
if (currentIndex != newIndex) { | ||
entry.State = GetStateForIndex(newIndex); | ||
target.UpdateOrAddEntry(entry); | ||
EditorUtility.SetDirty(target); | ||
} | ||
|
||
string displayName = entry.FullTypeName; | ||
string tooltip = ""; | ||
if (resolvedType != null) { | ||
displayName = resolvedType.CSharpName(); | ||
tooltip = resolvedType.CSharpName(true); | ||
} | ||
GUIContent label = new GUIContent(displayName, tooltip); | ||
GUILayout.Label(label); | ||
|
||
GUILayout.FlexibleSpace(); | ||
|
||
GUIStyle messageStyle = new GUIStyle(EditorStyles.label); | ||
string message; | ||
if (resolvedType != null) { | ||
message = GetAotCompilationMessage(resolvedType); | ||
if (string.IsNullOrEmpty(message) == false) { | ||
messageStyle.normal.textColor = Color.red; | ||
} else { | ||
switch (IsOutOfDate(resolvedType)) { | ||
case OutOfDateResult.NoAot: | ||
message = "No AOT model found"; | ||
break; | ||
case OutOfDateResult.Stale: | ||
message = "Stale"; | ||
break; | ||
case OutOfDateResult.Current: | ||
message = "\u2713"; | ||
break; | ||
} | ||
} | ||
} else { | ||
message = "Cannot load type"; | ||
} | ||
|
||
GUILayout.Label(message, messageStyle); | ||
|
||
EditorGUILayout.EndHorizontal(); | ||
} | ||
|
||
private string GetAotCompilationMessage(Type type) { | ||
try { | ||
fsMetaType.Get(new fsConfig(), type).EmitAotData(true); | ||
} catch (Exception e) { | ||
return e.Message; | ||
} | ||
return ""; | ||
} | ||
|
||
private Vector2 _scrollPos; | ||
public override void OnInspectorGUI() { | ||
var target = (fsAotConfiguration)this.target; | ||
|
||
if (GUILayout.Button("Compile")) { | ||
if (Directory.Exists(target.outputDirectory) == false) | ||
Directory.CreateDirectory(target.outputDirectory); | ||
|
||
foreach (fsAotConfiguration.Entry entry in target.aotTypes) { | ||
if (entry.State == fsAotConfiguration.AotState.Enabled) { | ||
Type resolvedType = fsTypeCache.GetType(entry.FullTypeName); | ||
if (resolvedType == null) { | ||
Debug.LogError("Cannot find type " + entry.FullTypeName); | ||
continue; | ||
} | ||
|
||
try { | ||
string compilation = fsAotCompilationManager.RunAotCompilationForType(new fsConfig(), resolvedType); | ||
string path = Path.Combine(target.outputDirectory, "AotConverter_" + resolvedType.CSharpName(true, true) + ".cs"); | ||
File.WriteAllText(path, compilation); | ||
} catch (Exception e) { | ||
Debug.LogWarning("AOT compiling " + resolvedType.CSharpName(true) + " failed: " + e.Message); | ||
} | ||
} | ||
} | ||
AssetDatabase.Refresh(); | ||
} | ||
|
||
target.outputDirectory = EditorGUILayout.TextField("Output Directory", target.outputDirectory); | ||
|
||
EditorGUILayout.BeginHorizontal(); | ||
GUILayout.Label("Set All"); | ||
int newIndex = GUILayout.Toolbar(-1, options, GUILayout.ExpandWidth(false)); | ||
GUILayout.FlexibleSpace(); | ||
EditorGUILayout.EndHorizontal(); | ||
if (newIndex != -1) { | ||
var newState = fsAotConfiguration.AotState.Default; | ||
if (newIndex == 0) | ||
newState = fsAotConfiguration.AotState.Enabled; | ||
else if (newIndex == 1) | ||
newState = fsAotConfiguration.AotState.Disabled; | ||
|
||
for (int i = 0; i < target.aotTypes.Count; ++i) { | ||
var entry = target.aotTypes[i]; | ||
entry.State = newState; | ||
target.aotTypes[i] = entry; | ||
} | ||
} | ||
|
||
|
||
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos); | ||
foreach (fsAotConfiguration.Entry entry in target.aotTypes) { | ||
Type resolvedType = fsTypeCache.GetType(entry.FullTypeName); | ||
EditorGUI.BeginDisabledGroup(resolvedType == null || string.IsNullOrEmpty(GetAotCompilationMessage(resolvedType)) == false); | ||
DrawType(entry, resolvedType); | ||
EditorGUI.EndDisabledGroup(); | ||
} | ||
EditorGUILayout.EndScrollView(); | ||
} | ||
|
||
} | ||
} | ||
#endif |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.