234 lines
6.3 KiB
C#
234 lines
6.3 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.Kit
|
|
{
|
|
public enum ActionStatus
|
|
{
|
|
NotStart,
|
|
Started,
|
|
Finished,
|
|
}
|
|
|
|
public enum ActionUpdateModes
|
|
{
|
|
ScaledDeltaTime,
|
|
UnscaledDeltaTime,
|
|
}
|
|
|
|
public interface IActionController
|
|
{
|
|
ulong ActionID { get; set; }
|
|
|
|
IAction Action { get; set; }
|
|
|
|
ActionUpdateModes UpdateMode { get; set; }
|
|
|
|
bool Paused { get; set; }
|
|
void Reset();
|
|
void Deinit();
|
|
void Recycle();
|
|
}
|
|
|
|
public interface IAction
|
|
{
|
|
ulong ActionID { get; set; }
|
|
ActionStatus Status { get; set; }
|
|
|
|
void OnStart();
|
|
void OnExecute(float dt);
|
|
void OnFinish();
|
|
|
|
bool IsFinalized { get; set; }
|
|
|
|
bool Paused { get; set; }
|
|
void Reset();
|
|
void Deinit();
|
|
}
|
|
|
|
public class ActionController : IActionController
|
|
{
|
|
private static readonly SimpleObjectPool<ActionController> Pool = new(
|
|
() => new ActionController(), controller =>
|
|
{
|
|
controller.UpdateMode = ActionUpdateModes.ScaledDeltaTime;
|
|
controller.ActionID = 0;
|
|
controller.Action = null;
|
|
}, 50);
|
|
|
|
public ulong ActionID { get; set; }
|
|
public IAction Action { get; set; }
|
|
|
|
public ActionUpdateModes UpdateMode { get; set; }
|
|
|
|
private bool _recycled;
|
|
|
|
public bool Paused
|
|
{
|
|
get => Action.Paused;
|
|
set => Action.Paused = value;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
if (Action.ActionID == ActionID)
|
|
{
|
|
Action.Reset();
|
|
}
|
|
}
|
|
|
|
public static IActionController Allocate()
|
|
{
|
|
var controller = Pool.Allocate();
|
|
controller._recycled = false;
|
|
return controller;
|
|
}
|
|
|
|
public void Deinit()
|
|
{
|
|
if (Action != null && Action.ActionID == ActionID)
|
|
{
|
|
Action.Deinit();
|
|
}
|
|
}
|
|
|
|
public void Recycle()
|
|
{
|
|
Pool.Recycle(this);
|
|
}
|
|
}
|
|
|
|
|
|
public static class IActionExtensions
|
|
{
|
|
public static IActionController Start(this IAction self, MonoBehaviour monoBehaviour,
|
|
Action<IActionController> onFinish = null)
|
|
{
|
|
var controller = ActionController.Allocate();
|
|
controller.ActionID = self.ActionID;
|
|
controller.Action = self;
|
|
controller.UpdateMode = ActionUpdateModes.ScaledDeltaTime;
|
|
monoBehaviour.ExecuteByUpdate(self, controller, onFinish);
|
|
return controller;
|
|
}
|
|
|
|
public static IActionController Start(this IAction self, MonoBehaviour monoBehaviour,
|
|
Action onFinish)
|
|
{
|
|
var controller = ActionController.Allocate();
|
|
controller.ActionID = self.ActionID;
|
|
controller.Action = self;
|
|
controller.UpdateMode = ActionUpdateModes.ScaledDeltaTime;
|
|
monoBehaviour.ExecuteByUpdate(self, controller, _ => onFinish());
|
|
return controller;
|
|
}
|
|
|
|
// public static IActionController StartCurrentScene(this IAction self, Action<IActionController> onFinish = null)
|
|
// {
|
|
// return self.Start(ActionKitCurrentScene.SceneComponent, onFinish);
|
|
// }
|
|
//
|
|
// public static IActionController StartCurrentScene(this IAction self, Action onFinish)
|
|
// {
|
|
// return self.Start(ActionKitCurrentScene.SceneComponent, onFinish);
|
|
// }
|
|
|
|
public static IActionController StartGlobal(this IAction self, Action<IActionController> onFinish = null)
|
|
{
|
|
return self.Start(ActionKitMonoBehaviourEvents.GetOrCreate(), onFinish);
|
|
}
|
|
|
|
public static IActionController StartGlobal(this IAction self, Action onFinish)
|
|
{
|
|
return self.Start(ActionKitMonoBehaviourEvents.GetOrCreate(), onFinish);
|
|
}
|
|
|
|
|
|
public static void Pause(this IActionController self)
|
|
{
|
|
if (self.ActionID == self.Action.ActionID)
|
|
{
|
|
self.Action.Paused = true;
|
|
}
|
|
}
|
|
|
|
public static void Resume(this IActionController self)
|
|
{
|
|
if (self.ActionID == self.Action.ActionID)
|
|
{
|
|
self.Action.Paused = false;
|
|
}
|
|
}
|
|
|
|
public static void Finish(this IAction self)
|
|
{
|
|
self.Status = ActionStatus.Finished;
|
|
}
|
|
|
|
public static bool Execute(this IAction self, float dt)
|
|
{
|
|
if (self.Status == ActionStatus.NotStart)
|
|
{
|
|
self.OnStart();
|
|
|
|
if (self.Status == ActionStatus.Finished)
|
|
{
|
|
self.OnFinish();
|
|
return true;
|
|
}
|
|
|
|
self.Status = ActionStatus.Started;
|
|
}
|
|
else if (self.Status == ActionStatus.Started)
|
|
{
|
|
if (self.Paused) return false;
|
|
|
|
self.OnExecute(dt);
|
|
|
|
if (self.Status == ActionStatus.Finished)
|
|
{
|
|
self.OnFinish();
|
|
return true;
|
|
}
|
|
}
|
|
else if (self.Status == ActionStatus.Finished)
|
|
{
|
|
self.OnFinish();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static class IActionControllerExtensions
|
|
{
|
|
public static IActionController IgnoreTimeScale(this IActionController self)
|
|
{
|
|
self.UpdateMode = ActionUpdateModes.UnscaledDeltaTime;
|
|
return self;
|
|
}
|
|
}
|
|
|
|
|
|
public interface IActionExecutor
|
|
{
|
|
void Execute(IActionController controller, Action<IActionController> onFinish = null);
|
|
}
|
|
|
|
public static class IActionExecutorExtensions
|
|
{
|
|
public static bool UpdateAction(this IActionExecutor self, IActionController controller, float dt,
|
|
Action<IActionController> onFinish = null)
|
|
{
|
|
if (!controller.Action.IsFinalized && controller.Action.Execute(dt))
|
|
{
|
|
onFinish?.Invoke(controller);
|
|
controller.Deinit();
|
|
return true;
|
|
}
|
|
|
|
return controller.Action.IsFinalized;
|
|
}
|
|
}
|
|
} |