Skip to content

Commit

Permalink
feat!: allow specifying asset path with AssetPathAttribute
Browse files Browse the repository at this point in the history
BREAKING CHANGE: LayoutAttribute and StylesheetAttribute's
RelativeTo property has been removed.
  • Loading branch information
jonisavo committed Apr 28, 2022
1 parent 9626f3d commit 336b6b9
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 12 deletions.
17 changes: 17 additions & 0 deletions Core/AssetPathAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using JetBrains.Annotations;

namespace UIComponents.Core
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class, AllowMultiple = true)]
[BaseTypeRequired(typeof(UIComponent))]
public class AssetPathAttribute : Attribute
{
public readonly string Path;

public AssetPathAttribute(string path)
{
Path = path;
}
}
}
3 changes: 3 additions & 0 deletions Core/AssetPathAttribute.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 58 additions & 5 deletions Core/PathAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,75 @@
using System;
using UnityEditor;

namespace UIComponents.Core
{
public abstract class PathAttribute : Attribute
{
public string Path { get; protected set; }

public string RelativeTo { get; set; }

public string GetAssetPath()
public string GetAssetPathForComponent(UIComponent component)
{
if (Path == null)
Path = string.Empty;

if (!string.IsNullOrEmpty(RelativeTo))
return string.Join("/", RelativeTo, Path);
if (!ConfiguredPathIsComplete())
{
if (TryGetPathFromComponent(component, out var pathFromComponent))
Path = pathFromComponent;
else if (TryGetPathFromAssembly(component, out var pathFromAssembly))
Path = pathFromAssembly;
}

return Path;
}

private bool ConfiguredPathIsComplete()
{
return Path.StartsWith("Assets/") ||
Path.StartsWith("Packages/");
}

private bool TryGetPathFromComponent(UIComponent component, out string path)
{
path = "";

return TryGetValidAssetPathFromAttributes(component.AssetPathAttributes, out path);
}

private bool TryGetPathFromAssembly(UIComponent component, out string path)
{
path = "";

var assembly = component.GetType().Assembly;

var assetPathAttributes =
assembly.GetCustomAttributes(typeof(AssetPathAttribute), false);

return TryGetValidAssetPathFromAttributes((AssetPathAttribute[]) assetPathAttributes, out path);
}

private bool TryGetValidAssetPathFromAttributes(
AssetPathAttribute[] attributes,
out string path)
{
path = "";

if (attributes.Length == 0)
return false;

foreach (var attribute in attributes)
{
var filePath = string.Join("/", attribute.Path, Path);

if (string.IsNullOrEmpty(AssetDatabase.AssetPathToGUID(filePath)))
continue;

path = filePath;

return true;
}

return false;
}
}
}
27 changes: 20 additions & 7 deletions Core/UIComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public abstract class UIComponent : VisualElement

private readonly StylesheetAttribute[] _stylesheetAttributes;

internal readonly AssetPathAttribute[] AssetPathAttributes;

private static readonly Dictionary<Type, DependencyInjector> InjectorDictionary =
new Dictionary<Type, DependencyInjector>();

Expand All @@ -31,7 +33,8 @@ public abstract class UIComponent : VisualElement
protected UIComponent()
{
_componentType = GetType();
_layoutAttribute = GetLayoutAttribute();
_layoutAttribute = GetSingleAttribute<LayoutAttribute>();
AssetPathAttributes = GetAttributes<AssetPathAttribute>();
_stylesheetAttributes = GetAttributes<StylesheetAttribute>();

var type = GetType();
Expand All @@ -55,8 +58,10 @@ protected virtual VisualTreeAsset GetLayout()
{
if (_layoutAttribute == null)
return null;

var assetPath = _layoutAttribute.GetAssetPathForComponent(this);

return AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(_layoutAttribute.GetAssetPath());
return AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(assetPath);
}

protected virtual StyleSheet[] GetStyleSheets()
Expand All @@ -65,17 +70,25 @@ protected virtual StyleSheet[] GetStyleSheets()

for (var i = 0; i < _stylesheetAttributes.Length; i++)
{
var assetPath = _stylesheetAttributes[i].GetAssetPath();
loadedStyleSheets[i] = AssetDatabase.LoadAssetAtPath<StyleSheet>(assetPath);
var assetPath = _stylesheetAttributes[i].GetAssetPathForComponent(this);
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>(assetPath);

if (styleSheet == null)
{
Debug.LogError($"Could not find stylesheet {assetPath} for {GetType().Name}");
continue;
}

loadedStyleSheets[i] = styleSheet;
}

return loadedStyleSheets;
}

[CanBeNull]
private LayoutAttribute GetLayoutAttribute()
private T GetSingleAttribute<T>() where T : Attribute
{
var layoutAttributes = GetAttributes<LayoutAttribute>();
var layoutAttributes = GetAttributes<T>();

if (layoutAttributes.Length == 0)
return null;
Expand Down

0 comments on commit 336b6b9

Please sign in to comment.