using QFramework; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using XMLTool; public class OperationController : MonoSingleton { public struct StepExecute { public int index; } public struct OnNextStep { } public struct StepStatusOnChange { public int curIndex; public StepStatus status; } public enum StepStatus { NoStart, Start, Finished, } OperationController() { } public Operation operation; List steps = new List(); int index = -1; bool isStepRun = false; IAction curAction; public override void OnSingletonInit() { base.OnSingletonInit(); TypeEventSystem.Global.Register((arg) => { Refresh(); }).UnRegisterWhenGameObjectDestroyed(gameObject); } public void Refresh() { Global.AppType operationType = Global.AppType.All; foreach (var operation in Global.Instance.curModule.Operations) { if (string.IsNullOrEmpty(operation.moduleType) == false) { Enum.TryParse(operation.moduleType, out operationType); } if (Global.appTpe == operationType || operationType == Global.AppType.All) { this.operation = operation; foreach (var item in operation.Steps) { AddStep(item); } TypeEventSystem.Global.Register(OnExecute); TypeEventSystem.Global.Register(OnNext); TypeEventSystem.Global.Register(arg => Clear()); } } } public void Clear() { curAction.Deinit(); steps.Clear(); TypeEventSystem.Global.UnRegister(arg => Clear()); TypeEventSystem.Global.UnRegister(OnExecute); TypeEventSystem.Global.UnRegister(OnNext); } private void OnNext(OnNextStep step) { Execute(this.index + 1); } private void OnExecute(StepExecute execute) { Execute(execute.index); } public void Begin() { index = 0; Execute(index); } public void AddStep(Step step) { steps.Add(step); if (step.SubSteps != null && step.SubSteps.Count > 0) { foreach (var subStep in step.SubSteps) { AddStep(subStep); } } } public void Execute(int targetIndex) { if (isStepRun) { curAction?.Deinit(); } if (targetIndex < steps.Count && targetIndex >= 0) { if (this.index < targetIndex) { var seq = ActionKit.Sequence(); for (int i = this.index + 1; i < targetIndex; i++) { // 完成动作 直接执行 IAction finishAction = ActionHelper.GetActionAndSub(steps[i].Finished); TypeEventSystem.Global.Send(new StepStatusOnChange() { curIndex = i, status = StepStatus.Finished }); if (finishAction!=null) { seq.Append(finishAction); } } seq.Start(this,() => { curAction = ActionHelper.GetActionAndSub(steps[targetIndex].Start); RunCurAction(curAction, targetIndex); }); } else if (this.index > targetIndex) { for (int i = this.index; i > targetIndex; i--) { // 重置动作 直接重置 IAction resetAction = ActionHelper.GetActionAndSub(steps[i].Reset); if (resetAction != null) { resetAction.Start(this); } TypeEventSystem.Global.Send(new StepStatusOnChange() { curIndex = i, status = StepStatus.NoStart }); } curAction = ActionHelper.GetActionAndSub(steps[targetIndex].Start); RunCurAction(curAction, targetIndex); } else { curAction = ActionHelper.GetActionAndSub(steps[targetIndex].Start); RunCurAction(curAction, targetIndex); } } } public void RunCurAction(IAction curAction,int targetIndex) { if (curAction != null) { this.index = targetIndex; isStepRun = true; TypeEventSystem.Global.Send(new StepStatusOnChange() { curIndex = targetIndex, status = StepStatus.Start }); curAction.Start(this, () => { isStepRun = false; TypeEventSystem.Global.Send(new StepStatusOnChange() { curIndex = targetIndex, status = StepStatus.Finished }); }); } else { this.index = targetIndex; TypeEventSystem.Global.Send(new StepStatusOnChange() { curIndex = targetIndex, status = StepStatus.Finished }); Execute(this.index + 1); } } }