#nullable enable using System; using UnityEngine; namespace UVC.UI.Commands { public class ActionCommand : ICommand { private readonly Action? _action; private readonly Action? _actionWithParam; public ActionCommand(Action action) { _action = action ?? throw new ArgumentNullException(nameof(action)); } public ActionCommand(Action actionWithParam) { _actionWithParam = actionWithParam ?? throw new ArgumentNullException(nameof(actionWithParam)); } public void Execute(object? parameter = null) { _action?.Invoke(); _actionWithParam?.Invoke(parameter); } } // 제네릭 ActionCommand는 이미 파라미터를 생성자에서 받으므로, // ICommand.Start(object parameter)를 구현할 때 해당 파라미터를 사용하지 않거나, // 혹은 Start(object) 호출 시 전달된 파라미터로 내부 _parameter를 덮어쓰는 등의 정책을 정해야 합니다. // 또는, ICommand 인터페이스를 고려할 수도 있습니다 (아래 2번 방법). public class ActionCommand : ICommand // ICommand를 구현 { private readonly Action? _action; private readonly T _defaultParameter; private bool _useDefaultParameterForParameterlessExecute; public ActionCommand(Action action) { _action = action ?? throw new ArgumentNullException(nameof(action)); _useDefaultParameterForParameterlessExecute = true; // 기본적으로 default(T) 사용 _defaultParameter = default(T)!; } public ActionCommand(Action action, T defaultParameter, bool useDefaultForParameterless = true) { _action = action ?? throw new ArgumentNullException(nameof(action)); _defaultParameter = defaultParameter; _useDefaultParameterForParameterlessExecute = useDefaultForParameterless; } // ICommand의 Start(T parameter) 구현 public void Execute(T parameter) { _action?.Invoke(parameter); } // ICommand 인터페이스에 의해 추가된 파라미터 없는 Start() // 기본 구현은 Start(default(T))를 호출합니다. // 이 메서드는 ICommand의 기본 인터페이스 메서드에 의해 제공되므로, // 여기서 명시적으로 재정의할 필요는 없습니다. (void ICommand.Start() => Start(default(T));) // 만약 다른 동작을 원한다면 여기서 재정의할 수 있습니다. // public new void Start() // 'new'는 인터페이스의 기본 구현을 숨기기 위함이 아님. // { // if (_useDefaultParameterForParameterlessExecute) // { // _action.Invoke(_defaultParameter); // } // else // { // // 또는 예외를 발생시키거나, 로깅 후 아무것도 하지 않음 // Debug.LogWarning($"ActionCommand<{typeof(T).Name}>의 파라미터 없는 Start()가 호출되었으나, 기본 파라미터 사용이 설정되지 않았습니다."); // } // } // ICommand의 Start(object parameter = null) 구현 void ICommand.Execute(object? parameter) // 명시적 인터페이스 구현 { if (parameter is T typedParameter) { Execute(typedParameter); } else if (parameter == null) { // 파라미터가 null로 전달된 경우, T의 기본값 또는 생성자에서 설정된 기본값을 사용할지 결정 if (_useDefaultParameterForParameterlessExecute) { Execute(_defaultParameter); } else { // T가 참조 타입이면 default(T)는 null. 값 타입이면 0, false 등. Execute(default(T)!); } } else { Debug.LogError($"ActionCommand<{typeof(T).Name}>.Start(object): 잘못된 파라미터 타입입니다. 기대: {typeof(T).Name}, 실제: {parameter.GetType().Name}"); // 예외를 발생시킬 수도 있습니다: throw new ArgumentException("잘못된 파라미터 타입입니다.", nameof(parameter)); } } } }