Skip to content

Commit

Permalink
V1.2.2 - show in inspector dynamic options (#22)
Browse files Browse the repository at this point in the history
* feat: added helpURL

* feat: splashdown inspector shows options overriden by dynamic options

* chore: bump package version
  • Loading branch information
Ale1 authored Aug 15, 2023
1 parent 42b06c5 commit d52a091
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 99 deletions.
2 changes: 1 addition & 1 deletion Assets/Test/Editor/DynamicOptionsExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public static class Example
{
[Splashdown.OptionsProvider]
[Splashdown.OptionsProvider("MySplashdown")]
public static Splashdown.Editor.Options ProvideSplashdownOptions() => new()
{
line1 = "Hello",
Expand Down
9 changes: 7 additions & 2 deletions Packages/com.ale1.splashdown/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Changelog
## com.coldtower.Splashdown
## com.ale1.Splashdown


##[1.2.2]
### Added
- Improvements to Splashdown inspector: options overriden by dynamic options will be marked with yellow label


## [1.2.1]
## Fixed
### Fixed
- Splash logo was trying to fetch sprite by sub-asset name but sprite has been made main asset.

## [1.2.0]
Expand Down
1 change: 0 additions & 1 deletion Packages/com.ale1.splashdown/Editor/Scripts/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public Options(bool applyDefaultValues = false)
public static Font DefaultFont => AssetDatabase.LoadAssetAtPath<Font>(Constants.FontPath_Roboto);
public static string DefaultFontGUID => AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(DefaultFont));
public static int DefaultFontSize => DefaultFont.fontSize;


[HideInInspector]
public string fileName;
Expand Down
125 changes: 38 additions & 87 deletions Packages/com.ale1.splashdown/Editor/Scripts/SplashdownImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,28 @@
namespace Splashdown.Editor
{
[ScriptedImporter(1, Constants.SplashdownFileType)]
[HelpURL("https://github.com/Ale1/Splashdown#readme")]
public class SplashdownImporter : ScriptedImporter
{
[HideInInspector][SerializeField] protected bool ActiveSplash;
[HideInInspector][SerializeField] protected bool ActiveIcon;
[HideInInspector] [SerializeField] protected bool ActiveSplash;
[HideInInspector] [SerializeField] protected bool ActiveIcon;
public bool IsSplashActive => ActiveSplash;
public bool IsIconActive => ActiveIcon;

public bool useDynamicOptions;

[HideInInspector] public Options inspectorOptions;

private Texture2D thumbnail => AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.ale1.splashdown/Editor/splashdown_thumbnail.png");
private Texture2D thumbnail =>
AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.ale1.splashdown/Editor/splashdown_thumbnail.png");

public SplashdownImporter()
{
SplashdownEvents.OnIconStateActivated -= IconStateListener;
SplashdownEvents.OnIconStateActivated += IconStateListener;
}

~SplashdownImporter() // Destructor
~SplashdownImporter() // Destructor
{
SplashdownEvents.OnIconStateActivated -= IconStateListener;
}
Expand All @@ -48,13 +50,13 @@ public void SetActiveIconWithEvent(bool val)
if (ActiveIcon != val)
{
ActiveIcon = val;
if(ActiveIcon) SplashdownEvents.OnIconStateActivated.Invoke(this);
if (ActiveIcon) SplashdownEvents.OnIconStateActivated.Invoke(this);
}
}

public string GetGuid => AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(this));


/// <summary>
/// Deserializes options for a splashdown asset from the asset database.
/// </summary>
Expand All @@ -70,6 +72,7 @@ public static Splashdown.Editor.Options DeserializeOptions(string pathToSplashdo
return JsonUtility.FromJson<Splashdown.Editor.Options>(textAsset.text);
}
}

return null;
}

Expand All @@ -89,7 +92,7 @@ public static void RefreshAllImporters()
AssetDatabase.ImportAsset(splashdownPath, ImportAssetOptions.ForceUpdate);
}
}


/// <summary>
/// The main import function that is called when a '.splashdown' file is imported.
Expand All @@ -101,9 +104,9 @@ public override void OnImportAsset(AssetImportContext ctx)
}

private void ImportWithContext(AssetImportContext ctx)
{
{
Options options;

// Load the deserialized options
var deserializedOptions = DeserializeOptions(ctx.assetPath);
if (deserializedOptions != null)
Expand All @@ -114,36 +117,33 @@ private void ImportWithContext(AssetImportContext ctx)
{
options = new Options(true);
}

string filename = System.IO.Path.GetFileNameWithoutExtension(ctx.assetPath);
this.name = filename;
//save name of splashdown file in Options
options.fileName = filename;
// Set the sprite path in the options
options.assetPath = $"{ctx.assetPath}";
if(inspectorOptions != null)

if (inspectorOptions != null)
options.UpdateWith(inspectorOptions);


if (useDynamicOptions)
{
var dynamicOptions = FetchDynamicOptions(name);
if(dynamicOptions != null) options.UpdateWith(dynamicOptions);
var dynamicOptions = SplashdownUtils.FetchDynamicOptions(name);
if (dynamicOptions != null) options.UpdateWith(dynamicOptions);
}


var key = Constants.EditorPrefsKey+ "." + this.name;
if(EditorPrefs.HasKey(key))

var key = Constants.EditorPrefsKey + "." + this.name;
if (EditorPrefs.HasKey(key))
{
var cliOptionsJson = EditorPrefs.GetString(key);
var newOptions = JsonUtility.FromJson<Options>(cliOptionsJson);
options.UpdateWith(newOptions);

EditorApplication.delayCall += () =>
{
EditorPrefs.DeleteKey(key);
};
EditorApplication.delayCall += () => { EditorPrefs.DeleteKey(key); };
}

SplashdownGenerator.CreateTexture(ctx.assetPath, options);
Expand All @@ -159,7 +159,7 @@ private void ImportWithContext(AssetImportContext ctx)
// Create a sprite from the texture
var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
sprite.name = Constants.GeneratedSpriteName;

// Convert Options to a serialized object and save as a sub-asset
string jsonOptions = JsonUtility.ToJson(options);
TextAsset serializedOptions = new TextAsset(jsonOptions)
Expand All @@ -175,76 +175,27 @@ private void ImportWithContext(AssetImportContext ctx)
}


/// <summary>
/// Listens to the icon state activation event. If the event is fired by another importer, it deactivates its own icon state.
/// </summary>
/// <param name="emiter">The importer that emitted the event.</param>
private void IconStateListener(AssetImporter emitter)
public Options FetchDynamicOptions()
{
if (ActiveIcon == true && emitter != this)
if (!String.IsNullOrWhiteSpace(this.name))
{
ActiveIcon = false;
return SplashdownUtils.FetchDynamicOptions(this.name);
}

return null;
}


/// <summary>
/// Fetches dynamic Splashdown options by searching all assemblies for a method marked with the Splashdown.OptionsProviderAttribute that has the correct signature.
/// Listens to the icon state activation event. If the event is fired by another importer, it deactivates its own icon state.
/// </summary>
/// <remarks>
/// If there are multiple methods in the assemblies that are marked with the Splashdown.OptionsProviderAttribute and have the correct signature,
/// this method is non-deterministic and it's not guaranteed to return the options from the same method every time.
/// </remarks>
/// <returns>
/// The Splashdown.Options returned by the first valid method it finds, or null if no valid method is found.
/// </returns>
private Options FetchDynamicOptions(string targetName)
/// <param name="emiter">The importer that emitted the event.</param>
private void IconStateListener(AssetImporter emitter)
{
// Get all assemblies in the current AppDomain
var assemblies = AppDomain.CurrentDomain.GetAssemblies();

foreach (var assembly in assemblies)
if (ActiveIcon == true && emitter != this)
{
foreach (var type in assembly.GetTypes())
{
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Static))
{
// method has the SplashdownOptionProviderAttribute
if (method.GetCustomAttributes(typeof(OptionsProviderAttribute), false)
.FirstOrDefault() is OptionsProviderAttribute)
{
// check for correct implementation by reading the return type
if (method.ReturnType != typeof(Options))
{
Debug.LogWarning(
$"Splashdown :: {method} with {nameof(OptionsProviderAttribute)} does not have correct return type ");
continue;
}

// Check the parameters (should take none)
var parameters = method.GetParameters();
if (parameters.Length != 0)
{
Debug.LogWarning(
$"Splashdown :: {method} with {nameof(OptionsProviderAttribute)} should not take any parameters ");
continue;
}

//Check Name is a match
OptionsProviderAttribute attribute = (OptionsProviderAttribute)Attribute.GetCustomAttribute(method, typeof(OptionsProviderAttribute));
if(attribute.Filter != null && attribute.Filter != targetName)
continue;

// If we get here, the method is valid
var dynamicOptions = (Options)method.Invoke(null, null);
return dynamicOptions;
}
}
}
ActiveIcon = false;
}

return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,75 @@

using UnityEditor;
using UnityEditor.AssetImporters;
using UnityEditor.Graphs;
using UnityEngine;
using UnityEngine.UIElements;

namespace Splashdown.Editor
{
[CustomEditor(typeof(SplashdownImporter))]
public class SplashdownImporterEditor : ScriptedImporterEditor
{
private Options options;

private GUIStyle _line1Style;
private GUIStyle _line2Style;
private GUIStyle _line3Style;
private GUIStyle _backgroundStyle;
private GUIStyle _textcolorStyle;

private string dynamicOptionsName;

public override void OnEnable()
{
base.OnEnable();

Color defaultLabelColor = EditorStyles.label.normal.textColor;
var importer = (SplashdownImporter)target;
var dynamicOptions = importer.FetchDynamicOptions();


_line1Style = new GUIStyle(EditorStyles.label)
{
normal = { textColor = dynamicOptions?.line1 != null ? Color.yellow: defaultLabelColor }
};

_line2Style = new GUIStyle(EditorStyles.label)
{
normal = { textColor = dynamicOptions?.line2 != null ? Color.yellow : defaultLabelColor }
};

_line3Style = new GUIStyle(EditorStyles.label)
{
normal = { textColor = dynamicOptions?.line3 != null ? Color.yellow : defaultLabelColor }
};

_backgroundStyle = new GUIStyle(EditorStyles.label)
{
normal =
{
textColor = dynamicOptions is { backgroundColor: { hasValue: true } }
? Color.yellow
: defaultLabelColor
}
};

_textcolorStyle = new GUIStyle(EditorStyles.label)
{
normal =
{
textColor = dynamicOptions is { textColor: { hasValue: true } }
? Color.yellow
: defaultLabelColor
}
};
}

//dont remove. It looks unecessary, but its actually unitybug where sometimes inspector is not disposed property if not explicitly disabled.
public override void OnDisable()
{
base.OnDisable();
}

public override void OnInspectorGUI()
{
Expand Down Expand Up @@ -59,15 +120,37 @@ public override void OnInspectorGUI()

DrawDivider();



// Draw the Options fields
EditorGUI.BeginChangeCheck();
//todo: show warning when these inspector options will be overriden by dynamic options. e.g: "if(importer.dynamicOptions && dynamicOptions.hasLine1) => |show warning|"
options.line1 = EditorGUILayout.TextField("Line 1", options.line1);
options.line2 = EditorGUILayout.TextField("Line 2", options.line2);
options.line3 = EditorGUILayout.TextField("Line 3", options.line3);
options.backgroundColor = EditorGUILayout.ColorField("Background Color", (UnityEngine.Color) options.backgroundColor);
options.textColor = EditorGUILayout.ColorField("Text Color Color", (UnityEngine.Color) options.textColor);


GUILayout.BeginHorizontal();
EditorGUILayout.LabelField(new GUIContent("Line 1", ""), _line1Style, GUILayout.Width(128));
options.line1 = EditorGUILayout.TextField(options.line1, GUILayout.MaxWidth(84));
GUILayout.EndHorizontal();

GUILayout.BeginHorizontal();
EditorGUILayout.LabelField(new GUIContent("Line 2", ""), _line2Style, GUILayout.Width(128));
options.line2 = EditorGUILayout.TextField(options.line2, GUILayout.MaxWidth(84));
GUILayout.EndHorizontal();

GUILayout.BeginHorizontal();
EditorGUILayout.LabelField(new GUIContent("Line 3", ""), _line3Style, GUILayout.Width(128));
options.line3 = EditorGUILayout.TextField(options.line3, GUILayout.MaxWidth(84));
GUILayout.EndHorizontal();

GUILayout.BeginHorizontal();
EditorGUILayout.LabelField(new GUIContent("Background Color", "being overriden by Dynamic Options"), _backgroundStyle, GUILayout.Width(128));
options.backgroundColor = EditorGUILayout.ColorField((Color) options.backgroundColor, GUILayout.MaxWidth(84));
GUILayout.EndHorizontal();

GUILayout.BeginHorizontal();
EditorGUILayout.LabelField(new GUIContent("Text Color",""), _textcolorStyle, GUILayout.Width(128));
options.textColor = EditorGUILayout.ColorField((Color) options.textColor, GUILayout.MaxWidth(84));
GUILayout.EndHorizontal();


if (EditorGUI.EndChangeCheck())
{
importer.inspectorOptions = options;
Expand Down
Loading

0 comments on commit d52a091

Please sign in to comment.