diff --git a/Editor/N8.Utils.SOA.Editor.asmdef b/Editor/N8.Utils.SOA.Editor.asmdef index ce39f94..0f022fe 100644 --- a/Editor/N8.Utils.SOA.Editor.asmdef +++ b/Editor/N8.Utils.SOA.Editor.asmdef @@ -1,7 +1,9 @@ { "name": "N8.Utils.SOA.Editor", "rootNamespace": "N8.Utils.SOA.Editor", - "references": [], + "references": [ + "N8.Utils.SOA" + ], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false, diff --git a/Editor/RefPropertyDrawer.cs b/Editor/RefPropertyDrawer.cs new file mode 100644 index 0000000..9bf726e --- /dev/null +++ b/Editor/RefPropertyDrawer.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + +namespace N8.Utils.SOA.Editor +{ + //[CustomPropertyDrawer(type: typeof(IRef), useForChildren: true)] + public sealed class RefPropertyDrawer : PropertyDrawer + { + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + VisualElement container = new VisualElement(); + + Debug.Log("Active"); + + FloatField floatField = new FloatField(label: "Fancy Label"); + + floatField.RegisterCallback>(callback: evt => + { + Debug.Log(evt.newValue); + }); + + //PropertyField useDefault = new PropertyField(property.FindPropertyRelative(_USE_DEFAULT)); + //PropertyField defaultValue = new PropertyField(property.FindPropertyRelative(_DEFAULT_VALUE)); + //PropertyField variable = new PropertyField(property.FindPropertyRelative(_VAR)); + + //SerializedProperty useDefault = property.FindPropertyRelative(_USE_DEFAULT); + //SerializedProperty defaultValue = property.FindPropertyRelative(_DEFAULT_VALUE); + //SerializedProperty variable = property.FindPropertyRelative(_VAR); + + //var t = new PopupField(label: "Test", choices: new List {1f, 2f, 3f}, defaultValue: 1f); + //container.Add(t); + + //container.Add(useDefault); + //container.Add(defaultValue); + //container.Add(variable); + + return container; + } + + /* + private const String _USE_DEFAULT = "useDefault"; + private const String _DEFAULT_VALUE = "defaultValue"; + private const String _VAR = "Var"; + */ + } +} diff --git a/Runtime/Refs/Ref.cs b/Runtime/Refs/Ref.cs new file mode 100644 index 0000000..4c5f4d8 --- /dev/null +++ b/Runtime/Refs/Ref.cs @@ -0,0 +1,96 @@ +using System; +using System.Runtime.CompilerServices; +using static System.Runtime.CompilerServices.MethodImplOptions; + +using UnityEngine; + +namespace N8.Utils.SOA +{ + using Vars; + + public interface IRef { } //for PropertyDrawer purposes + + [Serializable] + public class Ref : IRef where TVar : Var + { + #region Fields & Properties + + [SerializeField] protected Boolean useDefault; + [SerializeField] protected T defaultValue; + + [field: SerializeField] + protected TVar Var { get; private set; } + + private Boolean IsUsingDefault => (useDefault || (Var == null)); + + public T Value + { + get => IsUsingDefault ? defaultValue : (T)Var; + set + { + if (IsUsingDefault) + { + defaultValue = value; + } + else + { + Var.Value = value; + } + } + } + + #endregion + + #region Structors + + public Ref() { } + + public Ref(T val) + { + this.Value = val; + } + + public Ref(TVar var) + { + this.Var = var; + } + + /* + public Ref(T value, Boolean useDefault = true) + { + this.useDefault = useDefault; + this.Value = value; + } + + public Ref(TVar variable, Boolean useDefault = false) + { + this.useDefault = useDefault; + this.variable = variable; + } + */ + + #endregion + + #region Methods + + public override String ToString() => Value.ToString(); + + #endregion + + #region Operators + + //TODO: Conversion Operators default check. + + [MethodImpl(AggressiveInlining)] + public static implicit operator T (Ref input) => input.Value; + [MethodImpl(AggressiveInlining)] + public static implicit operator TVar (Ref input) => input.Var; + + [MethodImpl(AggressiveInlining)] + public static implicit operator Ref (T val) => new Ref(val: val); + [MethodImpl(AggressiveInlining)] + public static implicit operator Ref (TVar var) => new Ref(var: var); + + #endregion + } +} diff --git a/Runtime/Refs/Vector3Ref.cs b/Runtime/Refs/Vector3Ref.cs new file mode 100644 index 0000000..6582a29 --- /dev/null +++ b/Runtime/Refs/Vector3Ref.cs @@ -0,0 +1,30 @@ +using System; +using System.Runtime.CompilerServices; +using static System.Runtime.CompilerServices.MethodImplOptions; + +using UnityEngine; + +namespace N8.Utils.SOA.Refs +{ + using Vars; + + [Serializable] + public sealed class Vector3Ref : Ref + { + public Vector3Ref() : base() { } + public Vector3Ref(Vector3 val) : base(val: val) { } + public Vector3Ref(Vector3Var var) : base(var: var) { } + //public Vector3Ref(Vector3 value, Boolean useDefault = true) : base(value: value, useDefault: useDefault) { } + //public Vector3Ref(Vector3Var variable, Boolean useDefault = false) : base(variable: variable, useDefault: useDefault) { } + + [MethodImpl(AggressiveInlining)] + public static implicit operator Vector3 (Vector3Ref input) => input.Value; + [MethodImpl(AggressiveInlining)] + public static implicit operator Vector3Var (Vector3Ref input) => input.Var; + + [MethodImpl(AggressiveInlining)] + public static implicit operator Vector3Ref (Vector3 val) => new Vector3Ref(val: val); + [MethodImpl(AggressiveInlining)] + public static implicit operator Vector3Ref (Vector3Var var) => new Vector3Ref(var: var); + } +} \ No newline at end of file diff --git a/Runtime/Variables/Variable.cs b/Runtime/Variables/Variable.cs deleted file mode 100644 index 92721eb..0000000 --- a/Runtime/Variables/Variable.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using UnityEngine; - -namespace N8.Utils.SOA.Variables -{ - public abstract class Variable : ScriptableObject, ISerializationCallbackReceiver - { - [SerializeField] - private T _value; - - [field: NonSerialized] //Shouldn't be serialized anyhow, even with Odin installed, right? - public T Value { get; set; } - - public void OnBeforeSerialize() => Value = _value; - public void OnAfterDeserialize() { } - - public static implicit operator T(Variable input) => input.Value; - - public override string ToString() => Value.ToString(); - } -} \ No newline at end of file diff --git a/Runtime/Variables/FloatVariable.cs b/Runtime/Vars/FloatVar.cs similarity index 65% rename from Runtime/Variables/FloatVariable.cs rename to Runtime/Vars/FloatVar.cs index 0942f74..3633ae1 100644 --- a/Runtime/Variables/FloatVariable.cs +++ b/Runtime/Vars/FloatVar.cs @@ -1,11 +1,10 @@ -using UnityEngine; - using Sirenix.OdinInspector; +using UnityEngine; -namespace N8.Utils.SOA.Variables +namespace N8.Utils.SOA.Vars { [CreateAssetMenu(fileName = "NewFloatVariable", menuName = "N8Dev/SOA/Variables/Float"), InlineEditor] - public sealed class FloatVariable : Variable + public sealed class FloatVar : Var { } diff --git a/Runtime/Variables/ReadonlyFloatVariable.cs b/Runtime/Vars/ReadonlyFloatVar.cs similarity index 69% rename from Runtime/Variables/ReadonlyFloatVariable.cs rename to Runtime/Vars/ReadonlyFloatVar.cs index 1c7d512..8aa08de 100644 --- a/Runtime/Variables/ReadonlyFloatVariable.cs +++ b/Runtime/Vars/ReadonlyFloatVar.cs @@ -1,11 +1,10 @@ -using UnityEngine; - using Sirenix.OdinInspector; +using UnityEngine; -namespace N8.Utils.SOA.Variables +namespace N8.Utils.SOA.Vars { [CreateAssetMenu(fileName = "NewFloatVariable", menuName = "N8Dev/SOA/Variables/Float"), InlineEditor] //TODO: That won't work, it uses the same menuName as the regular float. - public sealed class ReadonlyFloatVariable : ReadonlyVariable + public sealed class ReadonlyFloatVar : ReadonlyVar { } diff --git a/Runtime/Variables/ReadonlyVariable.cs b/Runtime/Vars/ReadonlyVar.cs similarity index 67% rename from Runtime/Variables/ReadonlyVariable.cs rename to Runtime/Vars/ReadonlyVar.cs index 4b8e05b..a951001 100644 --- a/Runtime/Variables/ReadonlyVariable.cs +++ b/Runtime/Vars/ReadonlyVar.cs @@ -1,9 +1,9 @@ using System; using UnityEngine; -namespace N8.Utils.SOA.Variables +namespace N8.Utils.SOA.Vars { - public abstract class ReadonlyVariable : ScriptableObject, ISerializationCallbackReceiver + public abstract class ReadonlyVar : ScriptableObject, ISerializationCallbackReceiver { [SerializeField] private T _value; @@ -14,7 +14,7 @@ public abstract class ReadonlyVariable : ScriptableObject, ISerializationCall public void OnBeforeSerialize() => Value = _value; public void OnAfterDeserialize() { } - public static implicit operator T(ReadonlyVariable input) => input.Value; + public static implicit operator T(ReadonlyVar input) => input.Value; public override string ToString() => Value.ToString(); } diff --git a/Runtime/Vars/Var.cs b/Runtime/Vars/Var.cs new file mode 100644 index 0000000..71fa1fa --- /dev/null +++ b/Runtime/Vars/Var.cs @@ -0,0 +1,57 @@ +using System; +using UnityEngine; + +namespace N8.Utils.SOA.Vars +{ + public abstract class Var : ScriptableObject, ISerializationCallbackReceiver + { + #region Fields & Properties + + [SerializeField] + private T _value; + + public T Value { get; set; } + + #endregion + + /* + //TODO: Figure these out. + #region "Structors" + + public static Var New() + { + Var newVar = CreateInstance>(); + + return newVar; + } + + public static Var New(T val) + { + Var newVar = CreateInstance>(); + + newVar.Value = val; + + return newVar; + } + + #endregion + */ + + #region Methods + + public void OnBeforeSerialize() => Value = _value; + public void OnAfterDeserialize() { } + + + public override String ToString() => Value.ToString(); + + #endregion + + #region Operators + + //Can't work in reverse because ScriptableObjects can't be created via constructor. + public static implicit operator T(Var input) => input.Value; + + #endregion + } +} \ No newline at end of file diff --git a/Runtime/Vars/Vector3Var.cs b/Runtime/Vars/Vector3Var.cs new file mode 100644 index 0000000..78f8961 --- /dev/null +++ b/Runtime/Vars/Vector3Var.cs @@ -0,0 +1,29 @@ +using Sirenix.OdinInspector; +using UnityEngine; + +namespace N8.Utils.SOA.Vars +{ + [CreateAssetMenu(fileName = "NewVector3Var", menuName = "N8Dev/SOA/Variables/Vector3"), InlineEditor] + public sealed class Vector3Var : Var + { + #region "Structors" + + public new static Vector3Var New() + { + Vector3Var newVar = CreateInstance(); + + return newVar; + } + + public new static Vector3Var New(Vector3 val) + { + Vector3Var newVar = CreateInstance(); + + newVar.Value = val; + + return newVar; + } + + #endregion + } +} \ No newline at end of file diff --git a/Tests/Editor/N8.Utils.SOA.Tests.Editor.asmdef b/Tests/Editor/N8.Utils.SOA.Tests.Editor.asmdef new file mode 100644 index 0000000..ce4a3c0 --- /dev/null +++ b/Tests/Editor/N8.Utils.SOA.Tests.Editor.asmdef @@ -0,0 +1,24 @@ +{ + "name": "N8.Utils.SOA.Tests.Editor", + "rootNamespace": "N8.Utils.SOA.Tests.Editor", + "references": [ + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "N8.Utils.SOA" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Tests/Editor/RefTests.cs b/Tests/Editor/RefTests.cs new file mode 100644 index 0000000..a3008ba --- /dev/null +++ b/Tests/Editor/RefTests.cs @@ -0,0 +1,44 @@ +using NUnit.Framework; +using UnityEngine; + +namespace N8.Utils.SOA.Tests.Editor +{ + using Refs; + + public class RefTests + { + [Test] + public void Constructor_Empty() + { + Vector3Ref __vector3Ref = new Vector3Ref(); + + Assert.AreEqual( + expected: Vector3.zero, + actual: __vector3Ref.Value); + + Assert.AreNotEqual( + expected: Vector3.one, + actual: __vector3Ref.Value); + } + + [Test] + public void Constructor_T() + { + Vector3Ref __vector3Ref = new Vector3Ref(val: Vector3.one); + + Assert.AreEqual( + expected: Vector3.one, + actual: __vector3Ref.Value); + + Assert.AreNotEqual( + expected: Vector3.zero, + actual: __vector3Ref.Value); + } + + [Test] + public void Constructor_TVal() + { + // Use the Assert class to test conditions + } + } +} diff --git a/Tests/Editor/VarTests.cs b/Tests/Editor/VarTests.cs new file mode 100644 index 0000000..2d114bd --- /dev/null +++ b/Tests/Editor/VarTests.cs @@ -0,0 +1,68 @@ +using NUnit.Framework; +using UnityEngine; + +namespace N8.Utils.SOA.Tests.Editor +{ + using Vars; + + public class VarTests + { + /* + [Test] + public void New_Empty() + { + Var __vector3Var = Var.New(); + + Assert.AreEqual( + expected: Vector3.zero, + actual: __vector3Var.Value); + + Assert.AreNotEqual( + expected: Vector3.one, + actual: __vector3Var.Value); + } + + [Test] + public void New_T() + { + Var __vector3Var = Var.New(val: Vector3.one); + + Assert.AreEqual( + expected: Vector3.one, + actual: __vector3Var.Value); + + Assert.AreNotEqual( + expected: Vector3.zero, + actual: __vector3Var.Value); + } + */ + + [Test] + public void New_Empty() + { + Vector3Var __vector3Var = Vector3Var.New(); + + Assert.AreEqual( + expected: Vector3.zero, + actual: __vector3Var.Value); + + Assert.AreNotEqual( + expected: Vector3.one, + actual: __vector3Var.Value); + } + + [Test] + public void New_T() + { + Vector3Var __vector3Var = Vector3Var.New(val: Vector3.one); + + Assert.AreEqual( + expected: Vector3.one, + actual: __vector3Var.Value); + + Assert.AreNotEqual( + expected: Vector3.zero, + actual: __vector3Var.Value); + } + } +} \ No newline at end of file diff --git a/Tests/Runtime/N8.Utils.SOA.Tests.Runtime.asmdef b/Tests/Runtime/N8.Utils.SOA.Tests.Runtime.asmdef new file mode 100644 index 0000000..0a161fc --- /dev/null +++ b/Tests/Runtime/N8.Utils.SOA.Tests.Runtime.asmdef @@ -0,0 +1,22 @@ +{ + "name": "N8.Utils.SOA.Tests.Runtime", + "rootNamespace": "N8.Utils.SOA.Tests.Runtime", + "references": [ + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "N8.Utils.SOA" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/package.json b/package.json index 1c5f138..849b3d9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "com.n8dev.utils.soa", - "displayName": "N8Dev.Utils.SOA", + "name": "com.n8.utils.soa", + "displayName": "N8.Utils.SOA", "version": "0.1.0", "description": "Delivers flexible decoupling via ScriptableObject editor references inside Unity.", "keywords": [