namespace AcDream.App.UI;
public enum InteractionModeKind
{
None,
Use,
Examine,
UseItemOnTarget,
}
public readonly record struct InteractionMode(
InteractionModeKind Kind,
uint SourceObjectId = 0)
{
public static InteractionMode None => new(InteractionModeKind.None);
}
public readonly record struct InteractionModeTransition(
InteractionMode Previous,
InteractionMode Current);
///
/// Single App-layer owner for retail's pointer interaction mode. Core selection
/// remains session truth; this state represents temporary UI orchestration.
///
public sealed class InteractionState
{
public InteractionMode Current { get; private set; } = InteractionMode.None;
public event Action? Changed;
public bool EnterUse() => Set(new InteractionMode(InteractionModeKind.Use));
public bool EnterExamine() => Set(new InteractionMode(InteractionModeKind.Examine));
public bool EnterUseItemOnTarget(uint sourceObjectId)
{
if (sourceObjectId == 0)
throw new ArgumentOutOfRangeException(nameof(sourceObjectId));
return Set(new InteractionMode(InteractionModeKind.UseItemOnTarget, sourceObjectId));
}
public bool Clear() => Set(InteractionMode.None);
private bool Set(InteractionMode mode)
{
if (Current == mode)
return false;
InteractionMode previous = Current;
Current = mode;
Changed?.Invoke(new InteractionModeTransition(previous, mode));
return true;
}
}