99 lines
3.6 KiB
C#
99 lines
3.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Unity.VisualScripting;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.Kit
|
|
{
|
|
internal class MonoUpdateActionExecutor : MonoBehaviour, IActionExecutor
|
|
{
|
|
public class ActionTask
|
|
{
|
|
public IAction action;
|
|
public IActionController controller;
|
|
public Action<IActionController> onFinish;
|
|
}
|
|
|
|
private List<ActionTask> _prepareExecutionActions = new();
|
|
|
|
private Dictionary<IAction, ActionTask> _executingActions = new();
|
|
|
|
private static SimpleObjectPool<ActionTask> _actionTaskPool = new(
|
|
() => new ActionTask(), (task) =>
|
|
{
|
|
task.action = null;
|
|
task.controller = null;
|
|
task.onFinish = null;
|
|
}, 50);
|
|
|
|
public void Execute(IActionController controller, Action<IActionController> onFinish = null)
|
|
{
|
|
if (controller.Action.Status == ActionStatus.Finished) controller.Action.Reset();
|
|
if (this.UpdateAction(controller, 0, onFinish)) return;
|
|
|
|
var actionTask = _actionTaskPool.Allocate();
|
|
actionTask.action = controller.Action;
|
|
actionTask.controller = controller;
|
|
actionTask.onFinish = onFinish;
|
|
_prepareExecutionActions.Add(actionTask);
|
|
}
|
|
|
|
private List<IActionController> _toActionRemove = new();
|
|
|
|
private void Update()
|
|
{
|
|
if (_prepareExecutionActions.Count > 0)
|
|
{
|
|
foreach (var prepareExecutionAction in _prepareExecutionActions)
|
|
{
|
|
_executingActions[prepareExecutionAction.action] = prepareExecutionAction;
|
|
}
|
|
|
|
_prepareExecutionActions.Clear();
|
|
}
|
|
|
|
foreach (var actionAndFinishCallback in _executingActions)
|
|
{
|
|
if (actionAndFinishCallback.Value.controller.UpdateMode == ActionUpdateModes.ScaledDeltaTime)
|
|
{
|
|
if (this.UpdateAction(actionAndFinishCallback.Value.controller, Time.deltaTime,
|
|
actionAndFinishCallback.Value.onFinish))
|
|
{
|
|
_toActionRemove.Add(actionAndFinishCallback.Value.controller);
|
|
}
|
|
}
|
|
else if (actionAndFinishCallback.Value.controller.UpdateMode == ActionUpdateModes.UnscaledDeltaTime)
|
|
{
|
|
if (this.UpdateAction(actionAndFinishCallback.Value.controller, Time.unscaledDeltaTime,
|
|
actionAndFinishCallback.Value.onFinish))
|
|
{
|
|
_toActionRemove.Add(actionAndFinishCallback.Value.controller);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_toActionRemove.Count > 0)
|
|
{
|
|
foreach (var controller in _toActionRemove)
|
|
{
|
|
_executingActions.Remove(controller.Action);
|
|
controller.Recycle();
|
|
}
|
|
|
|
_toActionRemove.Clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class MonoUpdateActionExecutorExtension
|
|
{
|
|
public static IAction ExecuteByUpdate<T>(this T self, IAction action, IActionController controller,
|
|
Action<IActionController> onFinish = null)
|
|
where T : MonoBehaviour
|
|
{
|
|
if (action.Status == ActionStatus.Finished) action.Reset();
|
|
self.gameObject.GetOrAddComponent<MonoUpdateActionExecutor>().Execute(controller, onFinish);
|
|
return action;
|
|
}
|
|
}
|
|
} |