提交功能
This commit is contained in:
106
Core/Task/Collection/ParallelTaskCollection.cs
Normal file
106
Core/Task/Collection/ParallelTaskCollection.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
namespace NBC
|
||||
{
|
||||
public class ParallelTaskCollection : TaskCollection
|
||||
{
|
||||
private int _currentIndex;
|
||||
|
||||
/// <summary>
|
||||
/// 最大并行数量 (默认为9)
|
||||
/// </summary>
|
||||
public int ParallelNum = 9;
|
||||
|
||||
protected override NTaskStatus RunTasksAndCheckIfDone()
|
||||
{
|
||||
var st = NTaskStatus.Running;
|
||||
|
||||
if (CurRunTask.Count < ParallelNum && _currentIndex < RawList.Count)
|
||||
{
|
||||
var num = ParallelNum - CurRunTask.Count;
|
||||
for (var index = 0; index < num; index++)
|
||||
if (_currentIndex < RawList.Count)
|
||||
{
|
||||
CurRunTask.Add(RawList[_currentIndex]);
|
||||
_currentIndex += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (var index = 0; index < CurrentTask.Count; index++)
|
||||
{
|
||||
var element = CurrentTask[index];
|
||||
var childSt = element.Process();
|
||||
|
||||
if (FailBreak && childSt == NTaskStatus.Fail)
|
||||
{
|
||||
_errorMsg = element.ErrorMsg;
|
||||
st = NTaskStatus.Fail;
|
||||
break;
|
||||
}
|
||||
|
||||
if (childSt == NTaskStatus.Success || childSt == NTaskStatus.Fail)
|
||||
{
|
||||
CurrentTask.RemoveAt(index);
|
||||
index--;
|
||||
FinishList.Add(element);
|
||||
}
|
||||
}
|
||||
|
||||
if (FinishList.Count >= RawList.Count) st = NTaskStatus.Success;
|
||||
|
||||
// for (var index = 0; index < CurrentTask.Count; index++)
|
||||
// {
|
||||
// var element = CurrentTask[index];
|
||||
// var childSt = element.Process();
|
||||
//
|
||||
// if (childSt >= Status.Success)
|
||||
// {
|
||||
// if (FailBreak && childSt == Status.Fail)
|
||||
// {
|
||||
// _errorMsg = element.ErrorMsg;
|
||||
// st = Status.Fail;
|
||||
// }
|
||||
//
|
||||
// CurrentTask.RemoveAt(index);
|
||||
// index--;
|
||||
// FinishList.Add(element);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (FinishList.Count >= RawList.Count)
|
||||
// {
|
||||
// st = Status.Success;
|
||||
// }
|
||||
// else if (CurRunTask.Count < ParallelNum && _currentIndex < RawList.Count)
|
||||
// {
|
||||
// var num = ParallelNum - CurRunTask.Count;
|
||||
// for (var index = 0; index < num; index++)
|
||||
// {
|
||||
// if (_currentIndex < RawList.Count)
|
||||
// {
|
||||
// CurRunTask.Add(RawList[_currentIndex]);
|
||||
// _currentIndex += 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
_currentIndex = 0;
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
_currentIndex = 0;
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
_currentIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
113
Core/Task/Collection/SequenceTaskCollection.cs
Normal file
113
Core/Task/Collection/SequenceTaskCollection.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
namespace NBC
|
||||
{
|
||||
public class SequenceTaskCollection : TaskCollection
|
||||
{
|
||||
private int _currentIndex;
|
||||
|
||||
public override string Info
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CurrentTask != null && CurrentTask.Count > 0) return CurrentTask[0].Info;
|
||||
|
||||
return TaskInfo;
|
||||
}
|
||||
}
|
||||
|
||||
protected override NTaskStatus RunTasksAndCheckIfDone()
|
||||
{
|
||||
var st = NTaskStatus.Running;
|
||||
|
||||
if (RawList.Count > 0)
|
||||
{
|
||||
if (CurRunTask.Count == 0 && _currentIndex < RawList.Count) CurRunTask.Add(RawList[_currentIndex]);
|
||||
|
||||
NTaskStatus curSt;
|
||||
do
|
||||
{
|
||||
var childTask = CurRunTask[0];
|
||||
curSt = childTask.Process();
|
||||
if (curSt >= NTaskStatus.Success)
|
||||
{
|
||||
if (FailBreak && curSt == NTaskStatus.Fail)
|
||||
{
|
||||
_errorMsg = childTask.ErrorMsg;
|
||||
st = NTaskStatus.Fail;
|
||||
break;
|
||||
}
|
||||
|
||||
FinishList.Add(childTask);
|
||||
CurRunTask.RemoveAt(0);
|
||||
_currentIndex++;
|
||||
if (_currentIndex < RawList.Count)
|
||||
CurRunTask.Add(RawList[_currentIndex]);
|
||||
}
|
||||
} while (curSt >= NTaskStatus.Success && CurRunTask.Count > 0);
|
||||
|
||||
if (FinishList.Count == RawList.Count)
|
||||
st = NTaskStatus.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
st = NTaskStatus.Success;
|
||||
}
|
||||
|
||||
|
||||
// if (RawList.Count > 0)
|
||||
// {
|
||||
// if (FinishList.Count == RawList.Count)
|
||||
// {
|
||||
// st = Status.Success;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (CurRunTask.Count == 0)
|
||||
// {
|
||||
// CurRunTask.Add(RawList[_currentIndex]);
|
||||
// }
|
||||
//
|
||||
// var childTask = CurRunTask[0];
|
||||
// var curSt = childTask.Process();
|
||||
//
|
||||
//
|
||||
// if (curSt >= Status.Success)
|
||||
// {
|
||||
// if (FailBreak && curSt == Status.Fail)
|
||||
// {
|
||||
// _errorMsg = childTask.ErrorMsg;
|
||||
// st = Status.Fail;
|
||||
// }
|
||||
//
|
||||
// FinishList.Add(childTask);
|
||||
// CurRunTask.RemoveAt(0);
|
||||
// _currentIndex++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// st = Status.Success;
|
||||
// }
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
_currentIndex = 0;
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
_currentIndex = 0;
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
_currentIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Core/Task/Collection/TaskCollection.cs
Normal file
88
Core/Task/Collection/TaskCollection.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public abstract class TaskCollection : NTask, ITaskCollection
|
||||
{
|
||||
protected readonly List<ITask> CurRunTask;
|
||||
protected readonly List<ITask> FinishList;
|
||||
protected readonly List<ITask> RawList;
|
||||
|
||||
|
||||
public TaskCollection(string taskInfo = "")
|
||||
{
|
||||
RawList = new List<ITask>();
|
||||
FinishList = new List<ITask>();
|
||||
CurRunTask = new List<ITask>();
|
||||
TaskInfo = taskInfo;
|
||||
Status = NTaskStatus.None;
|
||||
}
|
||||
|
||||
public virtual int Count => RawList.Count + FinishList.Count;
|
||||
|
||||
/// <summary>
|
||||
/// 任务失败中断任务链
|
||||
/// </summary>
|
||||
public virtual bool FailBreak { get; set; }
|
||||
|
||||
public List<ITask> CurrentTask => CurRunTask;
|
||||
|
||||
public override float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Status == NTaskStatus.Success) return 1;
|
||||
if (Status == NTaskStatus.None) return 0;
|
||||
var finishCount = FinishList.Count;
|
||||
for (var index = 0; index < CurRunTask.Count; index++)
|
||||
{
|
||||
var element = CurRunTask[index];
|
||||
finishCount += (int)element.Progress;
|
||||
}
|
||||
|
||||
return finishCount * 1f / RawList.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public ITaskCollection AddTask(ITask task)
|
||||
{
|
||||
RawList.Add(task);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
FinishList.Clear();
|
||||
CurrentTask.Clear();
|
||||
Status = NTaskStatus.None;
|
||||
for (int i = 0, len = RawList.Count; i < len; i++) RawList[i].Reset();
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
FinishList.Clear();
|
||||
Status = NTaskStatus.None;
|
||||
for (var i = 0; i < CurRunTask.Count; i++)
|
||||
{
|
||||
var task = CurrentTask[i];
|
||||
task.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
FinishList.Clear();
|
||||
RawList.Clear();
|
||||
Status = NTaskStatus.None;
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
return RunTasksAndCheckIfDone();
|
||||
}
|
||||
|
||||
protected abstract NTaskStatus RunTasksAndCheckIfDone();
|
||||
}
|
||||
}
|
||||
10
Core/Task/Interface/IProcess.cs
Normal file
10
Core/Task/Interface/IProcess.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace NBC
|
||||
{
|
||||
/// <summary>
|
||||
/// 进度
|
||||
/// </summary>
|
||||
public interface IProcess
|
||||
{
|
||||
NTaskStatus Process();
|
||||
}
|
||||
}
|
||||
49
Core/Task/Interface/IRunner.cs
Normal file
49
Core/Task/Interface/IRunner.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
namespace NBC
|
||||
{
|
||||
public interface IRunner
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否暂停
|
||||
/// </summary>
|
||||
bool IsPaused { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经终止了
|
||||
/// </summary>
|
||||
bool IsKilled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前运行的任务数量
|
||||
/// </summary>
|
||||
int RunningTaskNum { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 准备执行的任务数量
|
||||
/// </summary>
|
||||
int NeedRunTaskNum { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行一个任务
|
||||
/// </summary>
|
||||
/// <param name="task">任务对象</param>
|
||||
void Run(ITask task);
|
||||
|
||||
void Process();
|
||||
|
||||
/// <summary>
|
||||
/// 停止任务
|
||||
/// </summary>
|
||||
/// <param name="task">任务对象</param>
|
||||
void StopTask(ITask task);
|
||||
|
||||
/// <summary>
|
||||
/// 停止所有任务
|
||||
/// </summary>
|
||||
void StopAllTask();
|
||||
|
||||
/// <summary>
|
||||
/// 终止任务
|
||||
/// </summary>
|
||||
void ShutDown();
|
||||
}
|
||||
}
|
||||
77
Core/Task/Interface/ITask.cs
Normal file
77
Core/Task/Interface/ITask.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public interface ITask : IProcess, IEnumerator
|
||||
{
|
||||
NTaskStatus Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前任务的信息
|
||||
/// </summary>
|
||||
string Info { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
string ErrorMsg { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前任务的进度
|
||||
/// </summary>
|
||||
float Progress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务正在执行
|
||||
/// </summary>
|
||||
bool IsRunning { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务是否执行完成
|
||||
/// </summary>
|
||||
bool IsDone { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务参数
|
||||
/// </summary>
|
||||
/// <param name="argsName"></param>
|
||||
object this[string argsName] { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 停止任务
|
||||
/// </summary>
|
||||
void Stop();
|
||||
|
||||
/// <summary>
|
||||
/// 任务开始回调
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
/// <param name="cover"></param>
|
||||
/// <returns></returns>
|
||||
ITask OnStarted(Action<ITask> callback, bool cover = false);
|
||||
|
||||
/// <summary>
|
||||
/// 任务执行回调
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
/// <param name="cover"></param>
|
||||
/// <returns></returns>
|
||||
ITask OnUpdated(Action<ITask> callback, bool cover = false);
|
||||
|
||||
/// <summary>
|
||||
/// 任务完成回调
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
/// <param name="cover"></param>
|
||||
/// <returns></returns>
|
||||
ITask OnCompleted(Action<ITask> callback, bool cover = false);
|
||||
|
||||
/// <summary>
|
||||
/// 运行任务
|
||||
/// </summary>
|
||||
/// <param name="runner">任务运行器</param>
|
||||
void Run(IRunner runner);
|
||||
}
|
||||
}
|
||||
24
Core/Task/Interface/ITaskCollection.cs
Normal file
24
Core/Task/Interface/ITaskCollection.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public interface ITaskCollection : ITask
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前运行的任务堆栈
|
||||
/// </summary>
|
||||
List<ITask> CurrentTask { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 添加一个任务
|
||||
/// </summary>
|
||||
/// <param name="task"></param>
|
||||
/// <returns></returns>
|
||||
ITaskCollection AddTask(ITask task);
|
||||
|
||||
/// <summary>
|
||||
/// 清理任务列表
|
||||
/// </summary>
|
||||
void Clear();
|
||||
}
|
||||
}
|
||||
7
Core/Task/Interface/ITaskRun.cs
Normal file
7
Core/Task/Interface/ITaskRun.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace NBC
|
||||
{
|
||||
public interface ITaskRun
|
||||
{
|
||||
void Run(IRunner runner);
|
||||
}
|
||||
}
|
||||
198
Core/Task/NTask.cs
Normal file
198
Core/Task/NTask.cs
Normal file
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public abstract class NTask : ITask
|
||||
{
|
||||
protected readonly Dictionary<string, object> _argsDic = new();
|
||||
protected string _errorMsg;
|
||||
protected float _progress;
|
||||
protected string TaskInfo;
|
||||
|
||||
public virtual string Info
|
||||
{
|
||||
get => TaskInfo;
|
||||
set => TaskInfo = value;
|
||||
}
|
||||
|
||||
public NTaskStatus Status { get; protected set; } = NTaskStatus.None;
|
||||
public virtual string ErrorMsg => _errorMsg;
|
||||
public virtual float Progress => _progress;
|
||||
|
||||
public virtual bool IsRunning => Status == NTaskStatus.Running;
|
||||
public virtual bool IsDone => Status == NTaskStatus.Success || Status == NTaskStatus.Fail;
|
||||
|
||||
public object this[string argsName]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_argsDic.TryGetValue(argsName, out var args)) return args;
|
||||
|
||||
return null;
|
||||
}
|
||||
set => _argsDic[argsName] = value;
|
||||
}
|
||||
|
||||
|
||||
public virtual void Stop()
|
||||
{
|
||||
Status = NTaskStatus.None;
|
||||
}
|
||||
|
||||
|
||||
public virtual void Run(IRunner runner)
|
||||
{
|
||||
Reset();
|
||||
runner?.Run(this);
|
||||
}
|
||||
|
||||
public NTaskStatus Process()
|
||||
{
|
||||
if (Status == NTaskStatus.None) Start();
|
||||
|
||||
Status = OnProcess();
|
||||
CallUpdateListener();
|
||||
if (Status == NTaskStatus.Success)
|
||||
{
|
||||
_progress = 1;
|
||||
CallCompleteListener(Status);
|
||||
}
|
||||
else if (Status == NTaskStatus.Fail)
|
||||
{
|
||||
_progress = 1;
|
||||
CallCompleteListener(Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
protected virtual void OnStart()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual NTaskStatus OnProcess()
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
protected void Finish()
|
||||
{
|
||||
_progress = 1;
|
||||
Status = NTaskStatus.Success;
|
||||
}
|
||||
|
||||
protected void Fail(string message)
|
||||
{
|
||||
_progress = 1;
|
||||
Status = NTaskStatus.Fail;
|
||||
_errorMsg = message;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Reset();
|
||||
Status = NTaskStatus.Running;
|
||||
_progress = 0;
|
||||
OnStart();
|
||||
CallStartListener();
|
||||
}
|
||||
|
||||
#region 事件
|
||||
|
||||
protected event Action<ITask> OnStartListener;
|
||||
protected event Action<ITask> OnCompleteListener;
|
||||
protected event Action<ITask> OnUpdateListener;
|
||||
|
||||
public ITask OnStarted(Action<ITask> callback, bool cover = false)
|
||||
{
|
||||
if (cover)
|
||||
OnStartListener = callback;
|
||||
else
|
||||
OnStartListener += callback;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ITask OnUpdated(Action<ITask> callback, bool cover = false)
|
||||
{
|
||||
if (cover)
|
||||
OnUpdateListener = callback;
|
||||
else
|
||||
OnUpdateListener += callback;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ITask OnCompleted(Action<ITask> callback, bool cover = false)
|
||||
{
|
||||
if (cover)
|
||||
OnCompleteListener = callback;
|
||||
else
|
||||
OnCompleteListener += callback;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void CallStartListener()
|
||||
{
|
||||
OnStartListener?.Invoke(this);
|
||||
}
|
||||
|
||||
protected void CallCompleteListener(NTaskStatus taskStatus)
|
||||
{
|
||||
OnCompleteListener?.Invoke(this);
|
||||
|
||||
_taskCompletionSource?.TrySetResult(null);
|
||||
}
|
||||
|
||||
protected void CallUpdateListener()
|
||||
{
|
||||
OnUpdateListener?.Invoke(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 异步编程相关
|
||||
|
||||
private TaskCompletionSource<object> _taskCompletionSource;
|
||||
|
||||
/// <summary>
|
||||
/// 异步操作任务
|
||||
/// </summary>
|
||||
public Task Task
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_taskCompletionSource == null)
|
||||
{
|
||||
_taskCompletionSource = new TaskCompletionSource<object>();
|
||||
if (IsDone)
|
||||
_taskCompletionSource.SetResult(null);
|
||||
}
|
||||
|
||||
return _taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerator
|
||||
|
||||
bool IEnumerator.MoveNext()
|
||||
{
|
||||
return !IsDone;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
Status = NTaskStatus.None;
|
||||
}
|
||||
|
||||
object IEnumerator.Current => null;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
25
Core/Task/NTaskStatus.cs
Normal file
25
Core/Task/NTaskStatus.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
namespace NBC
|
||||
{
|
||||
public enum NTaskStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务还未执行
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 任务运行
|
||||
/// </summary>
|
||||
Running,
|
||||
|
||||
/// <summary>
|
||||
/// 任务执行成功
|
||||
/// </summary>
|
||||
Success,
|
||||
|
||||
/// <summary>
|
||||
/// 任务执行失败
|
||||
/// </summary>
|
||||
Fail
|
||||
}
|
||||
}
|
||||
18
Core/Task/Runner/FlushingOperation.cs
Normal file
18
Core/Task/Runner/FlushingOperation.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace NBC
|
||||
{
|
||||
/// <summary>
|
||||
/// 操作信息类
|
||||
/// </summary>
|
||||
public class FlushingOperation
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否被终结
|
||||
/// </summary>
|
||||
public bool Kill;
|
||||
|
||||
/// <summary>
|
||||
/// 是否暂停
|
||||
/// </summary>
|
||||
public bool Paused;
|
||||
}
|
||||
}
|
||||
89
Core/Task/Runner/Runner.cs
Normal file
89
Core/Task/Runner/Runner.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class Runner : IRunner
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前运行的任务
|
||||
/// </summary>
|
||||
protected readonly List<ITask> Coroutines = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前操作的信息
|
||||
/// </summary>
|
||||
protected readonly FlushingOperation FlushingOperation = new();
|
||||
|
||||
/// <summary>
|
||||
/// 准备要运行的任务
|
||||
/// </summary>
|
||||
protected readonly Queue<ITask> ReadyTask = new();
|
||||
|
||||
public bool IsPaused
|
||||
{
|
||||
get => FlushingOperation.Paused;
|
||||
set => FlushingOperation.Paused = value;
|
||||
}
|
||||
|
||||
public bool IsKilled => FlushingOperation.Kill;
|
||||
public int RunningTaskNum => Coroutines.Count;
|
||||
public int NeedRunTaskNum => ReadyTask.Count;
|
||||
|
||||
public virtual void Run(ITask task)
|
||||
{
|
||||
ReadyTask.Enqueue(task);
|
||||
}
|
||||
|
||||
public virtual void Process()
|
||||
{
|
||||
var count = ReadyTask.Count;
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var task = ReadyTask.Dequeue();
|
||||
Coroutines.Add(task);
|
||||
}
|
||||
|
||||
if (Coroutines.Count < 1) return;
|
||||
|
||||
var index = 0;
|
||||
bool mustExit;
|
||||
do
|
||||
{
|
||||
var childTask = Coroutines[index];
|
||||
var st = childTask.Process();
|
||||
if (st >= NTaskStatus.Success)
|
||||
Coroutines.Remove(childTask);
|
||||
else
|
||||
index++;
|
||||
|
||||
mustExit = Coroutines.Count == 0 || index >= Coroutines.Count;
|
||||
} while (!mustExit);
|
||||
}
|
||||
|
||||
public virtual void StopTask(ITask task)
|
||||
{
|
||||
var index = Coroutines.IndexOf(task);
|
||||
if (index != -1)
|
||||
{
|
||||
var t = Coroutines[index];
|
||||
t.Stop();
|
||||
Coroutines.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StopAllTask()
|
||||
{
|
||||
ReadyTask.Clear();
|
||||
for (var i = 0; i < Coroutines.Count; i++) Coroutines[i].Stop();
|
||||
|
||||
Coroutines.Clear();
|
||||
}
|
||||
|
||||
public virtual void ShutDown()
|
||||
{
|
||||
IsPaused = false;
|
||||
FlushingOperation.Kill = true;
|
||||
StopAllTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
77
Core/Task/Runner/RunnerProcess.cs
Normal file
77
Core/Task/Runner/RunnerProcess.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class RunnerProcess : IProcess
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前运行的任务
|
||||
/// </summary>
|
||||
protected readonly List<ITask> Coroutines;
|
||||
|
||||
/// <summary>
|
||||
/// 当前操作的信息
|
||||
/// </summary>
|
||||
protected readonly FlushingOperation FlushingOperation;
|
||||
|
||||
/// <summary>
|
||||
/// 准备要运行的任务
|
||||
/// </summary>
|
||||
protected readonly Queue<ITask> ReadyTask;
|
||||
|
||||
/// <summary>
|
||||
/// 进程名称
|
||||
/// </summary>
|
||||
protected string Name;
|
||||
|
||||
public RunnerProcess(string name, List<ITask> coroutines, Queue<ITask> readyTask, FlushingOperation op)
|
||||
{
|
||||
Name = name;
|
||||
Coroutines = coroutines;
|
||||
ReadyTask = readyTask;
|
||||
FlushingOperation = op;
|
||||
}
|
||||
|
||||
public NTaskStatus Process()
|
||||
{
|
||||
var flag = false;
|
||||
if (FlushingOperation.Kill)
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var index = 0; index < ReadyTask.Count; index++)
|
||||
{
|
||||
// var task = ReadyTask[0];
|
||||
var task = ReadyTask.Dequeue();
|
||||
Coroutines.Add(task);
|
||||
// ReadyTask.RemoveAt(0);
|
||||
}
|
||||
|
||||
if (Coroutines.Count == 0 || FlushingOperation.Paused)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var index = 0;
|
||||
var mustExit = false;
|
||||
do
|
||||
{
|
||||
var childTask = Coroutines[index];
|
||||
var st = childTask.Process();
|
||||
if (st >= NTaskStatus.Success)
|
||||
Coroutines.RemoveAt(index); //.splice(index, 1);
|
||||
else
|
||||
index++;
|
||||
|
||||
mustExit = Coroutines.Count == 0 || index >= Coroutines.Count;
|
||||
} while (!mustExit);
|
||||
}
|
||||
}
|
||||
|
||||
return flag ? NTaskStatus.Success : NTaskStatus.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
54
Core/TaskRunner.cs
Normal file
54
Core/TaskRunner.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using NBC;
|
||||
|
||||
namespace ACBuildService;
|
||||
|
||||
/// <summary>
|
||||
/// 默认任务执行器
|
||||
/// </summary>
|
||||
public class TaskRunner : Runner
|
||||
{
|
||||
private static TaskRunner mUpdateRunner;
|
||||
public static TaskRunner Scheduler => mUpdateRunner ??= new TaskRunner();
|
||||
|
||||
private readonly List<IProcess> _updateRoutines = new List<IProcess>();
|
||||
|
||||
public event Action OnUpdate;
|
||||
|
||||
public TaskRunner()
|
||||
{
|
||||
Time.OnUpdate += Update;
|
||||
StartCoroutine(new RunnerProcess("TaskRunner", Coroutines, ReadyTask, FlushingOperation));
|
||||
}
|
||||
|
||||
private void StartCoroutine(IProcess process)
|
||||
{
|
||||
var routines = _updateRoutines;
|
||||
if (!routines.Contains(process))
|
||||
{
|
||||
routines.Add(process);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
ExecuteRoutines(_updateRoutines);
|
||||
OnUpdate?.Invoke();
|
||||
}
|
||||
|
||||
private void ExecuteRoutines(List<IProcess> arr)
|
||||
{
|
||||
if (arr != null && arr.Count > 0)
|
||||
{
|
||||
for (var index = 0; index < arr.Count; index++)
|
||||
{
|
||||
var task = arr[index];
|
||||
var st = task.Process();
|
||||
if (st == NTaskStatus.Success)
|
||||
{
|
||||
arr.RemoveAt(index);
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Core/Time.cs
Normal file
88
Core/Time.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
namespace ACBuildService;
|
||||
|
||||
public static class Time
|
||||
{
|
||||
public const long OneDay = 86400000;
|
||||
public const long Hour = 3600000;
|
||||
public const long Minute = 60000;
|
||||
|
||||
private static TimeInfo _timeInfo = new TimeInfo();
|
||||
|
||||
public static long Now => _timeInfo.Now();
|
||||
|
||||
public static long NowSeconds => Now / 1000;
|
||||
|
||||
public static DateTime DateTimeNow => DateTime.Now;
|
||||
|
||||
public static long FrameTime => _timeInfo.FrameTime;
|
||||
|
||||
public static event Action OnUpdate;
|
||||
public static event Action OnLateUpdate;
|
||||
|
||||
internal static void Awake()
|
||||
{
|
||||
}
|
||||
|
||||
internal static void Update()
|
||||
{
|
||||
_timeInfo.Update();
|
||||
OnUpdate?.Invoke();
|
||||
}
|
||||
|
||||
internal static void LateUpdate()
|
||||
{
|
||||
OnLateUpdate?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public class TimeInfo
|
||||
{
|
||||
private int timeZone;
|
||||
|
||||
public int TimeZone
|
||||
{
|
||||
get => timeZone;
|
||||
set
|
||||
{
|
||||
timeZone = value;
|
||||
dt = dt1970.AddHours(TimeZone);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly DateTime dt1970;
|
||||
private DateTime dt;
|
||||
|
||||
public long FrameTime;
|
||||
|
||||
public TimeInfo()
|
||||
{
|
||||
dt1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
FrameTime = Now();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
FrameTime = Now();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据时间戳获取时间
|
||||
/// </summary>
|
||||
public DateTime ToDateTime(long timeStamp)
|
||||
{
|
||||
return dt.AddTicks(timeStamp * 10000);
|
||||
}
|
||||
|
||||
// 线程安全
|
||||
public long Now()
|
||||
{
|
||||
return (DateTime.UtcNow.Ticks - dt1970.Ticks) / 10000;
|
||||
}
|
||||
|
||||
|
||||
public long Transition(DateTime d)
|
||||
{
|
||||
return (d.Ticks - dt.Ticks) / 10000;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user