using System; using JetBrains.Annotations; using NaughtyAttributes; using UnityEngine; using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger; using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace Station46.Scripts { public enum ButtonEventType { Pressed, Released, Activated, Deactivated } public static class ButtonEventExtensions { public static string Description(this ButtonEventType type, Button button) { var action = type switch { ButtonEventType.Pressed => "pressed", ButtonEventType.Released => "released", ButtonEventType.Activated => "activated", ButtonEventType.Deactivated => "deactivated", _ => throw new ArgumentOutOfRangeException(nameof(type), type, null) }; return $"{button} was {action}"; } } public delegate void ButtonEventHandler(Button source, ButtonEventType e); /// /// A general component for buttons that handles button events. /// public class Button : MonoBehaviour { public event ButtonEventHandler ButtonEvent; /// /// Whether this button accepts input. /// [ShowNativeProperty] protected bool Active { get => _active; set { var previous = _active; _active = value; if (previous != _active) { OnButtonEvent(_active ? ButtonEventType.Activated : ButtonEventType.Deactivated); } } } /// /// Whether this button is currently pressed. /// [ShowNativeProperty] protected bool Pressed { get => _pressed; set { var previous = _pressed; _pressed = Active && value; if (previous != _pressed) { OnButtonEvent(_pressed ? ButtonEventType.Pressed : ButtonEventType.Released); } } } private bool _active = true, _pressed; protected virtual void Start() { ButtonEvent += (_, type) => { if (type == ButtonEventType.Deactivated) { Pressed = false; // release button if it is deactivated } }; } private void OnButtonEvent(ButtonEventType type) { Logger.Log(type.Description(this), LogType.PuzzleDetail); ButtonEvent?.Invoke(this, type); } #region Debug Buttons [Button(enabledMode: EButtonEnableMode.Playmode)] public void Enable() => Active = true; [Button(enabledMode: EButtonEnableMode.Playmode)] public void Disable() => Active = false; [Button(enabledMode: EButtonEnableMode.Playmode)] public void Press() => Pressed = true; [Button(enabledMode: EButtonEnableMode.Playmode)] public void Release() => Pressed = false; [UsedImplicitly] [Button(enabledMode: EButtonEnableMode.Playmode)] public void PressAndRelease() { Press(); Release(); } #endregion public override string ToString() { return name; } } }