using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Rive.Utils; namespace Rive { /// /// A view model instance property that holds an enum. /// public sealed class ViewModelInstanceEnumProperty : ViewModelInstancePrimitiveProperty { private string[] m_enumValues; /// /// Constructor for the enum property. This is used when the enum values are known ahead of time. /// /// The pointer to the instance property. /// The root instance of the view model. /// The list of enum values. internal ViewModelInstanceEnumProperty(IntPtr instanceValuePtr, ViewModelInstance rootInstance, string[] enumValues) : base(instanceValuePtr, rootInstance) { m_enumValues = enumValues; } /// /// Constructor for the enum property. This is used when the enum values are not known ahead of time. /// /// The pointer to the instance property. /// The root instance of the view model. internal ViewModelInstanceEnumProperty(IntPtr instanceValuePtr, ViewModelInstance rootInstance) : base(instanceValuePtr, rootInstance) { PopulateEnumValuesIfNeeded(); } /// /// The current enum value of the property. /// public override string Value { get { ThrowIfOwnerDisposed(); if (InstancePropertyPtr == IntPtr.Zero) { DebugLogger.Instance.LogWarning("Trying to get a null enum property."); return null; } if (m_enumValues.Length == 0) { return null; } return m_enumValues[(int)getViewModelInstanceEnumIndex(InstancePropertyPtr)]; } set { ThrowIfOwnerDisposed(); int index = Array.IndexOf(m_enumValues, value); if (index == -1) { DebugLogger.Instance.LogWarning("Invalid enum value: " + value); return; } if (index < 0) { DebugLogger.Instance.LogWarning("Trying to set a negative enum value."); return; } setViewModelInstanceEnumIndex(InstancePropertyPtr, (uint)index); } } /// /// The current enum value index of the property in the enum values list. /// internal int ValueIndex { get { ThrowIfOwnerDisposed(); if (InstancePropertyPtr == IntPtr.Zero) { DebugLogger.Instance.LogWarning("Trying to get a null enum property."); return -1; } return (int)getViewModelInstanceEnumIndex(InstancePropertyPtr); } set { ThrowIfOwnerDisposed(); if (value < 0 || value >= m_enumValues.Length) { DebugLogger.Instance.LogWarning("Invalid enum value index: " + value); return; } setViewModelInstanceEnumIndex(InstancePropertyPtr, (uint)value); } } private void PopulateEnumValuesIfNeeded() { if (m_enumValues == null) { IntPtr m_enumValuesPtr = getViewModelInstanceEnumValues(InstancePropertyPtr); nuint valueCount = getViewModelInstanceEnumValueCount(m_enumValuesPtr); m_enumValues = new string[(int)valueCount]; for (nuint i = 0; i < valueCount; i++) { m_enumValues[i] = Marshal.PtrToStringAnsi(getViewModelInstanceEnumValueAtIndex(m_enumValuesPtr, i)); } freeViewModelInstanceEnumValues(m_enumValuesPtr); } } /// /// The list of enum options for this property. /// public IReadOnlyList EnumValues { get { if (m_enumValues == null) { PopulateEnumValuesIfNeeded(); } return m_enumValues; } } [DllImport(NativeLibrary.name)] private static extern uint getViewModelInstanceEnumIndex(IntPtr instanceProperty); [DllImport(NativeLibrary.name)] private static extern void setViewModelInstanceEnumIndex(IntPtr instanceProperty, uint value); [DllImport(NativeLibrary.name)] private static extern IntPtr getViewModelInstanceEnumValues(IntPtr instanceProperty); [DllImport(NativeLibrary.name)] private static extern nuint getViewModelInstanceEnumValueCount(IntPtr listPtr); [DllImport(NativeLibrary.name)] private static extern IntPtr getViewModelInstanceEnumValueAtIndex(IntPtr listPtr, nuint index); [DllImport(NativeLibrary.name)] private static extern void freeViewModelInstanceEnumValues(IntPtr listPtr); } }