106 lines
4.4 KiB
C#
106 lines
4.4 KiB
C#
#nullable enable
|
|
using System;
|
|
using UnityEngine;
|
|
|
|
namespace UVC.UI.Commands
|
|
{
|
|
public class ActionCommand : ICommand
|
|
{
|
|
private readonly Action? _action;
|
|
private readonly Action<object?>? _actionWithParam;
|
|
|
|
public ActionCommand(Action action)
|
|
{
|
|
_action = action ?? throw new ArgumentNullException(nameof(action));
|
|
}
|
|
|
|
public ActionCommand(Action<object?> actionWithParam)
|
|
{
|
|
_actionWithParam = actionWithParam ?? throw new ArgumentNullException(nameof(actionWithParam));
|
|
}
|
|
|
|
public void Execute(object? parameter = null)
|
|
{
|
|
_action?.Invoke();
|
|
_actionWithParam?.Invoke(parameter);
|
|
}
|
|
}
|
|
|
|
// 제네릭 ActionCommand<T>는 이미 파라미터를 생성자에서 받으므로,
|
|
// ICommand.Start(object parameter)를 구현할 때 해당 파라미터를 사용하지 않거나,
|
|
// 혹은 Start(object) 호출 시 전달된 파라미터로 내부 _parameter를 덮어쓰는 등의 정책을 정해야 합니다.
|
|
// 또는, ICommand<T> 인터페이스를 고려할 수도 있습니다 (아래 2번 방법).
|
|
public class ActionCommand<T> : ICommand<T> // ICommand<T>를 구현
|
|
{
|
|
private readonly Action<T>? _action;
|
|
private readonly T _defaultParameter;
|
|
private bool _useDefaultParameterForParameterlessExecute;
|
|
|
|
public ActionCommand(Action<T> action)
|
|
{
|
|
_action = action ?? throw new ArgumentNullException(nameof(action));
|
|
_useDefaultParameterForParameterlessExecute = true; // 기본적으로 default(T) 사용
|
|
_defaultParameter = default(T)!;
|
|
}
|
|
|
|
public ActionCommand(Action<T> action, T defaultParameter, bool useDefaultForParameterless = true)
|
|
{
|
|
_action = action ?? throw new ArgumentNullException(nameof(action));
|
|
_defaultParameter = defaultParameter;
|
|
_useDefaultParameterForParameterlessExecute = useDefaultForParameterless;
|
|
}
|
|
|
|
// ICommand<T>의 Start(T parameter) 구현
|
|
public void Execute(T parameter)
|
|
{
|
|
_action?.Invoke(parameter);
|
|
}
|
|
|
|
// ICommand<T> 인터페이스에 의해 추가된 파라미터 없는 Start()
|
|
// 기본 구현은 Start(default(T))를 호출합니다.
|
|
// 이 메서드는 ICommand<T>의 기본 인터페이스 메서드에 의해 제공되므로,
|
|
// 여기서 명시적으로 재정의할 필요는 없습니다. (void ICommand<T>.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));
|
|
}
|
|
}
|
|
}
|
|
}
|