86 lines
3.0 KiB
C#
86 lines
3.0 KiB
C#
using System;
|
|
using System.Runtime.CompilerServices;
|
|
using UnityEngine;
|
|
|
|
namespace Jovian.TagSystem {
|
|
/// <summary>
|
|
/// Lightweight tag identity. 8 bytes, no heap allocation.
|
|
/// Hierarchy queries are resolved via GameTagManager static lookups.
|
|
/// </summary>
|
|
[Serializable]
|
|
public struct JovianTag : IEquatable<JovianTag>, IComparable<JovianTag> {
|
|
[SerializeField] private int id;
|
|
[SerializeField] private int parentId;
|
|
|
|
public int Id => id;
|
|
public int ParentId => parentId;
|
|
|
|
public JovianTag(int id, int parentId) {
|
|
this.id = id;
|
|
this.parentId = parentId;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public readonly bool IsNone() => id == 0;
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public readonly bool IsValid() => id > 0;
|
|
|
|
/// <summary>
|
|
/// Checks if this tag is a descendant of the given ancestor.
|
|
/// Walks the parent chain via GameTagManager.
|
|
/// </summary>
|
|
public readonly bool IsDescendantOf(JovianTag ancestor) {
|
|
if(id == 0 || ancestor.id == 0) return false;
|
|
if(id == ancestor.id) return true;
|
|
|
|
// Walk up from this tag's parent chain
|
|
var current = this;
|
|
while(current.parentId != 0) {
|
|
if(current.parentId == ancestor.id) return true;
|
|
current = JovianTagsHandler.GetTag(current.parentId);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if this tag is an ancestor of the given descendant.
|
|
/// </summary>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public readonly bool IsAncestorOf(JovianTag descendant) {
|
|
return descendant.IsDescendantOf(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if this tag shares the same parent as the given tag.
|
|
/// </summary>
|
|
public readonly bool IsSiblingTo(JovianTag sibling) {
|
|
if(id == 0 || sibling.id == 0) return false;
|
|
return parentId == sibling.parentId;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static bool operator ==(JovianTag x, JovianTag y) => x.id == y.id;
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static bool operator !=(JovianTag x, JovianTag y) => x.id != y.id;
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public readonly bool Equals(JovianTag other) => id == other.id;
|
|
|
|
public readonly int CompareTo(JovianTag other) => id.CompareTo(other.id);
|
|
|
|
public override readonly bool Equals(object obj) => obj is JovianTag other && id == other.id;
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public override readonly int GetHashCode() => id;
|
|
|
|
public override readonly string ToString() {
|
|
if(JovianTagsHandler.IsInitialized) {
|
|
return JovianTagsHandler.TagToString(this);
|
|
}
|
|
return id == 0 ? "None" : $"Tag({id})";
|
|
}
|
|
}
|
|
}
|