using System;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Tilemaps
{
///
/// Represents a custom property value that can be of various types.
///
public readonly struct TilemapPropertyValue
{
[StructLayout(LayoutKind.Explicit)]
private readonly struct ValueData
{
[FieldOffset(0)] public readonly int Int32;
[FieldOffset(0)] public readonly float Single;
[FieldOffset(0)] public readonly bool Boolean;
[FieldOffset(0)] public readonly uint ColorPackedValue;
public ValueData(int value) => Int32 = value;
public ValueData(float value) => Single = value;
public ValueData(bool value) => Boolean = value;
public ValueData(uint value) => ColorPackedValue = value;
}
private readonly ValueData _valueData;
private readonly string _stringValue;
///
/// Gets the type of this property value.
///
public TilemapPropertyType Type { get; }
private TilemapPropertyValue(TilemapPropertyType type, ValueData valueData, string stringValue = null)
{
Type = type;
_valueData = valueData;
_stringValue = stringValue;
}
#region Factory Methods
///
/// Creates a string property value.
///
/// The string value.
/// A property value containing the string.
public static TilemapPropertyValue CreateString(string value)
{
return new TilemapPropertyValue(TilemapPropertyType.String, default, value);
}
///
/// Creates an integer property value.
///
/// The integer value.
/// A property value containing the integer.
public static TilemapPropertyValue CreateInt(int value)
{
return new TilemapPropertyValue(TilemapPropertyType.Int, new ValueData(value));
}
///
/// Creates a float property value.
///
/// The float value.
/// A property value containing the float.
public static TilemapPropertyValue CreateFloat(float value)
{
return new TilemapPropertyValue(TilemapPropertyType.Float, new ValueData(value));
}
///
/// Creates a boolean property value.
///
/// The boolean value.
/// A property value containing the boolean.
public static TilemapPropertyValue CreateBool(bool value)
{
return new TilemapPropertyValue(TilemapPropertyType.Bool, new ValueData(value));
}
///
/// Creates a color property value.
///
/// The color value.
/// A property value containing the color.
public static TilemapPropertyValue CreateColor(Color value)
{
return new TilemapPropertyValue(TilemapPropertyType.Color, new ValueData(value.PackedValue));
}
///
/// Creates a file path property value.
///
/// The file path.
/// A property value containing the file path.
public static TilemapPropertyValue CreateFile(string path)
{
return new TilemapPropertyValue(TilemapPropertyType.File, default, path);
}
///
/// Creates an object reference property value.
///
/// The object reference ID.
/// A property value containing the object ID.
public static TilemapPropertyValue CreateObject(int objectId)
{
return new TilemapPropertyValue(TilemapPropertyType.Object, new ValueData(objectId));
}
#endregion
#region Type-safe Accessors
///
/// Gets the value as a string.
///
/// The string value.
/// The property type is not
public string AsString()
{
if (Type != TilemapPropertyType.String)
throw new InvalidOperationException($"Cannot access property of type {Type} as String");
return _stringValue;
}
///
/// Gets the value as an integer.
///
/// The integer value.
/// The property type is not
public int AsInt()
{
if (Type != TilemapPropertyType.Int)
throw new InvalidOperationException($"Cannot access property of type {Type} as Int.");
return _valueData.Int32;
}
///
/// Gets the value as a float.
///
/// The float value.
/// The property type is not
public float AsFloat()
{
if (Type != TilemapPropertyType.Float)
throw new InvalidOperationException($"Cannot access property of type {Type} as Float.");
return _valueData.Single;
}
///
/// Gets the value as a boolean.
///
/// The bool value.
/// The property type is not
public bool AsBool()
{
if (Type != TilemapPropertyType.Bool)
throw new InvalidOperationException($"Cannot access property of type {Type} as Bool.");
return _valueData.Boolean;
}
///
/// Gets the value as a color.
///
/// The color value.
/// The property type is not
public Color AsColor()
{
if (Type != TilemapPropertyType.Color)
throw new InvalidOperationException($"Cannot access property of type {Type} as Color.");
return new Color(_valueData.ColorPackedValue);
}
///
/// Gets the value as a file path.
///
/// The file path.
/// The property type is not
public string AsFile()
{
if (Type != TilemapPropertyType.File)
throw new InvalidOperationException($"Cannot access property of type {Type} as File.");
return _stringValue;
}
///
/// Gets the value as an object reference ID.
///
/// The object ID.
/// The property type is not
public int AsObject()
{
if (Type != TilemapPropertyType.Object)
throw new InvalidOperationException($"Cannot access property of type {Type} as Object.");
return _valueData.Int32;
}
#endregion
}
}