mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
feat(coroutine): 实现协程系统核心功能
- 添加协程上下文、句柄、调度器和作用域管理类 - 实现协程等待指令包括 WaitForSeconds、WaitUntil 和 WaitWhile - 创建协程系统和全局协程作用域管理器 - 定义协程相关抽象接口 ICoroutineScheduler、ICoroutineScope 等 - 升级 Meziantou.Analyzer 依赖版本至 2.0.283 - 升级 Meziantou.Polyfill 依赖版本至 1.0.100
This commit is contained in:
parent
5ef6145688
commit
f143cf5c1b
@ -16,11 +16,11 @@
|
||||
<Using Include="GFramework.Core.Abstractions"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.279">
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.283">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.84">
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.100">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@ -18,11 +18,11 @@
|
||||
<Using Include="GFramework.Game.Abstractions"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.279">
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.283">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.84">
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.100">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
namespace GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 协程调度器接口,定义了协程系统的基本调度方法
|
||||
/// </summary>
|
||||
public interface ICoroutineScheduler
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新协程调度器,处理等待中的协程
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上一帧以来的时间间隔(以秒为单位)</param>
|
||||
void Update(float deltaTime);
|
||||
}
|
||||
17
GFramework.Game.Abstractions/coroutine/ICoroutineScope.cs
Normal file
17
GFramework.Game.Abstractions/coroutine/ICoroutineScope.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 协程作用域接口,用于管理协程的生命周期
|
||||
/// </summary>
|
||||
public interface ICoroutineScope
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取协程是否处于活动状态
|
||||
/// </summary>
|
||||
bool IsActive { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 取消协程执行
|
||||
/// </summary>
|
||||
void Cancel();
|
||||
}
|
||||
15
GFramework.Game.Abstractions/coroutine/ICoroutineSystem.cs
Normal file
15
GFramework.Game.Abstractions/coroutine/ICoroutineSystem.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using GFramework.Core.Abstractions.system;
|
||||
|
||||
namespace GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 协程系统接口,继承自ISystem,用于管理游戏中的协程执行
|
||||
/// </summary>
|
||||
public interface ICoroutineSystem : ISystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新协程系统,在每一帧调用以处理协程逻辑
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">距离上一帧的时间间隔(秒)</param>
|
||||
void OnUpdate(float deltaTime);
|
||||
}
|
||||
18
GFramework.Game.Abstractions/coroutine/IYieldInstruction.cs
Normal file
18
GFramework.Game.Abstractions/coroutine/IYieldInstruction.cs
Normal file
@ -0,0 +1,18 @@
|
||||
namespace GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 表示一个可等待的指令接口,用于协程中的等待操作
|
||||
/// </summary>
|
||||
public interface IYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前等待指令是否已完成
|
||||
/// </summary>
|
||||
bool IsDone { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新等待指令的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔(以秒为单位)</param>
|
||||
void Update(float deltaTime);
|
||||
}
|
||||
27
GFramework.Game/coroutine/CoroutineContext.cs
Normal file
27
GFramework.Game/coroutine/CoroutineContext.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 协程上下文类,用于封装协程执行所需的环境信息
|
||||
/// </summary>
|
||||
/// <param name="scope">协程作用域接口实例</param>
|
||||
/// <param name="scheduler">协程调度器实例</param>
|
||||
/// <param name="owner">协程的所有者对象,默认为null</param>
|
||||
public class CoroutineContext(ICoroutineScope scope, CoroutineScheduler scheduler, object? owner = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取协程作用域
|
||||
/// </summary>
|
||||
public ICoroutineScope Scope { get; } = scope;
|
||||
|
||||
/// <summary>
|
||||
/// 获取协程调度器
|
||||
/// </summary>
|
||||
public CoroutineScheduler Scheduler { get; } = scheduler;
|
||||
|
||||
/// <summary>
|
||||
/// 获取协程所有者对象
|
||||
/// </summary>
|
||||
public object? Owner { get; } = owner;
|
||||
}
|
||||
118
GFramework.Game/coroutine/CoroutineHandle.cs
Normal file
118
GFramework.Game/coroutine/CoroutineHandle.cs
Normal file
@ -0,0 +1,118 @@
|
||||
using System.Collections;
|
||||
using GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
public class CoroutineHandle : IYieldInstruction
|
||||
{
|
||||
private readonly Stack<IEnumerator> _stack = new();
|
||||
private IYieldInstruction? _waitingInstruction;
|
||||
|
||||
internal CoroutineHandle(IEnumerator routine, CoroutineContext context, IYieldInstruction? waitingInstruction)
|
||||
{
|
||||
_stack.Push(routine);
|
||||
Context = context;
|
||||
_waitingInstruction = waitingInstruction;
|
||||
}
|
||||
|
||||
public CoroutineContext Context { get; }
|
||||
public bool IsCancelled { get; private set; }
|
||||
public bool IsDone { get; private set; }
|
||||
|
||||
void IYieldInstruction.Update(float deltaTime)
|
||||
{
|
||||
InternalUpdate(deltaTime);
|
||||
}
|
||||
|
||||
public event Action? OnComplete;
|
||||
public event Action<Exception>? OnError;
|
||||
|
||||
private bool InternalUpdate(float deltaTime)
|
||||
{
|
||||
if (IsDone) return false;
|
||||
|
||||
if (_waitingInstruction != null)
|
||||
{
|
||||
_waitingInstruction.Update(deltaTime);
|
||||
if (!_waitingInstruction.IsDone) return true;
|
||||
_waitingInstruction = null;
|
||||
}
|
||||
|
||||
if (_stack.Count == 0)
|
||||
{
|
||||
Complete();
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var current = _stack.Peek();
|
||||
if (current.MoveNext())
|
||||
{
|
||||
ProcessYieldValue(current.Current);
|
||||
return true;
|
||||
}
|
||||
|
||||
_stack.Pop();
|
||||
return _stack.Count > 0 || !CompleteCheck();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleError(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessYieldValue(object yielded)
|
||||
{
|
||||
switch (yielded)
|
||||
{
|
||||
case null:
|
||||
break;
|
||||
case IEnumerator nested:
|
||||
_stack.Push(nested);
|
||||
break;
|
||||
// ✅ 将更具体的类型放在前面
|
||||
case CoroutineHandle otherHandle:
|
||||
_waitingInstruction = otherHandle;
|
||||
break;
|
||||
case IYieldInstruction instruction:
|
||||
_waitingInstruction = instruction;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException($"Unsupported yield type: {yielded.GetType()}");
|
||||
}
|
||||
}
|
||||
|
||||
private bool CompleteCheck()
|
||||
{
|
||||
if (_stack.Count == 0) Complete();
|
||||
return IsDone;
|
||||
}
|
||||
|
||||
private void Complete()
|
||||
{
|
||||
if (IsDone) return;
|
||||
IsDone = true;
|
||||
_stack.Clear();
|
||||
_waitingInstruction = null;
|
||||
OnComplete?.Invoke();
|
||||
}
|
||||
|
||||
private void HandleError(Exception ex)
|
||||
{
|
||||
IsDone = true;
|
||||
_stack.Clear();
|
||||
_waitingInstruction = null;
|
||||
OnError?.Invoke(ex);
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
if (IsDone) return;
|
||||
IsDone = true;
|
||||
IsCancelled = true;
|
||||
_stack.Clear();
|
||||
_waitingInstruction = null;
|
||||
}
|
||||
}
|
||||
52
GFramework.Game/coroutine/CoroutineScheduler.cs
Normal file
52
GFramework.Game/coroutine/CoroutineScheduler.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System.Collections;
|
||||
using GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
public class CoroutineScheduler : ICoroutineScheduler
|
||||
{
|
||||
private readonly List<CoroutineHandle> _active = new();
|
||||
private readonly List<CoroutineHandle> _toAdd = new();
|
||||
private readonly HashSet<CoroutineHandle> _toRemove = new();
|
||||
|
||||
public int ActiveCount => _active.Count;
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (_toAdd.Count > 0)
|
||||
{
|
||||
_active.AddRange(_toAdd);
|
||||
_toAdd.Clear();
|
||||
}
|
||||
|
||||
for (var i = _active.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var c = _active[i];
|
||||
|
||||
if (!c.Context.Scope.IsActive)
|
||||
{
|
||||
c.Cancel();
|
||||
_toRemove.Add(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!c.Update(deltaTime))
|
||||
_toRemove.Add(c);
|
||||
}
|
||||
|
||||
if (_toRemove.Count <= 0) return;
|
||||
{
|
||||
_active.RemoveAll(c => _toRemove.Contains(c));
|
||||
_toRemove.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
internal CoroutineHandle StartCoroutine(IEnumerator routine, CoroutineContext context)
|
||||
{
|
||||
var handle = new CoroutineHandle(routine, context);
|
||||
_toAdd.Add(handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal void RemoveCoroutine(CoroutineHandle handle) => _toRemove.Add(handle);
|
||||
}
|
||||
57
GFramework.Game/coroutine/CoroutineScope.cs
Normal file
57
GFramework.Game/coroutine/CoroutineScope.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System.Collections;
|
||||
using GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
public class CoroutineScope : ICoroutineScope, IDisposable
|
||||
{
|
||||
private readonly List<CoroutineScope> _children = new();
|
||||
private readonly CoroutineScope _parent;
|
||||
private readonly HashSet<CoroutineHandle> _runningCoroutines = new();
|
||||
private readonly CoroutineScheduler _scheduler;
|
||||
|
||||
private bool _isActive = true;
|
||||
|
||||
public CoroutineScope(CoroutineScheduler scheduler, string name = null, CoroutineScope parent = null)
|
||||
{
|
||||
_scheduler = scheduler ?? throw new ArgumentNullException(nameof(scheduler));
|
||||
_parent = parent;
|
||||
_parent?._children.Add(this);
|
||||
Name = name ?? $"Scope_{GetHashCode()}";
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public bool IsActive => _isActive;
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
if (!_isActive) return;
|
||||
|
||||
_isActive = false;
|
||||
|
||||
foreach (var child in _children.ToList())
|
||||
child.Cancel();
|
||||
|
||||
foreach (var handle in _runningCoroutines.ToList())
|
||||
handle.Cancel();
|
||||
|
||||
_runningCoroutines.Clear();
|
||||
}
|
||||
|
||||
public void Dispose() => Cancel();
|
||||
|
||||
public CoroutineHandle Launch(IEnumerator routine)
|
||||
{
|
||||
if (!_isActive)
|
||||
throw new InvalidOperationException($"Scope '{Name}' is not active");
|
||||
|
||||
var context = new CoroutineContext(this, _scheduler, this);
|
||||
var handle = _scheduler.StartCoroutine(routine, context);
|
||||
|
||||
_runningCoroutines.Add(handle);
|
||||
handle.OnComplete += () => _runningCoroutines.Remove(handle);
|
||||
handle.OnError += (ex) => _runningCoroutines.Remove(handle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
57
GFramework.Game/coroutine/CoroutineScopeExtensions.cs
Normal file
57
GFramework.Game/coroutine/CoroutineScopeExtensions.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System.Collections;
|
||||
using GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 为协程作用域提供扩展方法,支持延迟执行和重复执行功能
|
||||
/// </summary>
|
||||
public static class CoroutineScopeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动一个延迟执行的协程
|
||||
/// </summary>
|
||||
/// <param name="scope">协程作用域</param>
|
||||
/// <param name="delay">延迟时间(秒)</param>
|
||||
/// <param name="action">延迟后要执行的动作</param>
|
||||
/// <returns>协程句柄,可用于控制协程的生命周期</returns>
|
||||
public static CoroutineHandle LaunchDelayed(this ICoroutineScope scope, float delay, Action action)
|
||||
=> ((CoroutineScope)scope).Launch(DelayedRoutine(delay, action));
|
||||
|
||||
/// <summary>
|
||||
/// 创建延迟执行的协程迭代器
|
||||
/// </summary>
|
||||
/// <param name="delay">延迟时间(秒)</param>
|
||||
/// <param name="action">要执行的动作</param>
|
||||
/// <returns>协程迭代器</returns>
|
||||
private static IEnumerator DelayedRoutine(float delay, Action? action)
|
||||
{
|
||||
yield return new WaitForSeconds(delay);
|
||||
action?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动一个重复执行的协程
|
||||
/// </summary>
|
||||
/// <param name="scope">协程作用域</param>
|
||||
/// <param name="interval">重复间隔时间(秒)</param>
|
||||
/// <param name="action">每次重复时要执行的动作</param>
|
||||
/// <returns>协程句柄,可用于控制协程的生命周期</returns>
|
||||
public static CoroutineHandle LaunchRepeating(this ICoroutineScope scope, float interval, Action action)
|
||||
=> ((CoroutineScope)scope).Launch(RepeatingRoutine(interval, action));
|
||||
|
||||
/// <summary>
|
||||
/// 创建重复执行的协程迭代器
|
||||
/// </summary>
|
||||
/// <param name="interval">重复间隔时间(秒)</param>
|
||||
/// <param name="action">要执行的动作</param>
|
||||
/// <returns>协程迭代器</returns>
|
||||
private static IEnumerator RepeatingRoutine(float interval, Action action)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
action?.Invoke();
|
||||
yield return new WaitForSeconds(interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
GFramework.Game/coroutine/CoroutineSystem.cs
Normal file
28
GFramework.Game/coroutine/CoroutineSystem.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using GFramework.Core.system;
|
||||
using GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 协程系统类,负责管理和更新协程调度器
|
||||
/// </summary>
|
||||
/// <param name="scheduler">协程调度器实例</param>
|
||||
public class CoroutineSystem(CoroutineScheduler scheduler) : AbstractSystem, ICoroutineSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新协程系统,驱动协程调度器执行协程逻辑
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间间隔,表示自上一帧以来经过的时间(秒)</param>
|
||||
public void OnUpdate(float deltaTime)
|
||||
{
|
||||
// 更新协程调度器,处理等待中的协程
|
||||
scheduler.Update(deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化协程系统
|
||||
/// </summary>
|
||||
protected override void OnInit()
|
||||
{
|
||||
}
|
||||
}
|
||||
31
GFramework.Game/coroutine/GlobalCoroutineScope.cs
Normal file
31
GFramework.Game/coroutine/GlobalCoroutineScope.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.Collections;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 全局协程作用域管理器,提供全局唯一的协程执行环境
|
||||
/// </summary>
|
||||
public static class GlobalCoroutineScope
|
||||
{
|
||||
private static CoroutineScope? _instance;
|
||||
|
||||
/// <summary>
|
||||
/// 获取全局协程作用域实例,如果未初始化则抛出异常
|
||||
/// </summary>
|
||||
private static CoroutineScope Instance =>
|
||||
_instance ?? throw new InvalidOperationException("GlobalScope not initialized");
|
||||
|
||||
/// <summary>
|
||||
/// 初始化全局协程作用域
|
||||
/// </summary>
|
||||
/// <param name="scheduler">协程调度器实例</param>
|
||||
public static void Initialize(CoroutineScheduler scheduler) =>
|
||||
_instance = new CoroutineScope(scheduler, "GlobalScope");
|
||||
|
||||
/// <summary>
|
||||
/// 在全局作用域中启动一个协程
|
||||
/// </summary>
|
||||
/// <param name="routine">要执行的协程枚举器</param>
|
||||
/// <returns>协程句柄,用于控制和管理协程生命周期</returns>
|
||||
public static CoroutineHandle Launch(IEnumerator routine) => Instance.Launch(routine);
|
||||
}
|
||||
24
GFramework.Game/coroutine/WaitForSeconds.cs
Normal file
24
GFramework.Game/coroutine/WaitForSeconds.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 表示一个等待指定秒数的时间延迟指令
|
||||
/// </summary>
|
||||
/// <param name="seconds">需要等待的秒数</param>
|
||||
public class WaitForSeconds(float seconds) : IYieldInstruction
|
||||
{
|
||||
private float _elapsed;
|
||||
public bool IsDone { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间进度,当累计时间达到指定秒数时标记完成
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来经过的时间(秒)</param>
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (IsDone) return;
|
||||
_elapsed += deltaTime;
|
||||
if (_elapsed >= seconds) IsDone = true;
|
||||
}
|
||||
}
|
||||
24
GFramework.Game/coroutine/WaitUntil.cs
Normal file
24
GFramework.Game/coroutine/WaitUntil.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 等待直到指定条件满足的协程等待指令
|
||||
/// </summary>
|
||||
/// <param name="predicate">用于判断等待条件是否满足的布尔函数委托</param>
|
||||
public class WaitUntil(Func<bool> predicate) : IYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取等待指令是否已完成
|
||||
/// </summary>
|
||||
public bool IsDone { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新等待状态,在每一帧调用以检查条件是否满足
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上一帧以来的时间间隔</param>
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (!IsDone) IsDone = predicate();
|
||||
}
|
||||
}
|
||||
24
GFramework.Game/coroutine/WaitWhile.cs
Normal file
24
GFramework.Game/coroutine/WaitWhile.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using GFramework.Game.Abstractions.coroutine;
|
||||
|
||||
namespace GFramework.Game.coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 等待条件为假的等待指令,当指定的谓词条件变为false时完成等待
|
||||
/// </summary>
|
||||
/// <param name="predicate">用于判断是否继续等待的条件函数,返回true表示继续等待,返回false表示等待结束</param>
|
||||
public class WaitWhile(Func<bool> predicate) : IYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取等待指令是否已完成
|
||||
/// </summary>
|
||||
public bool IsDone { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新等待状态,检查谓词条件是否满足结束等待的要求
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (!IsDone) IsDone = !predicate();
|
||||
}
|
||||
}
|
||||
@ -19,11 +19,11 @@
|
||||
<Folder Include="logging\"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.279">
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.283">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.84">
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.100">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@ -18,11 +18,11 @@
|
||||
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj" PrivateAssets="all"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.279">
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.283">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.84">
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.100">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@ -22,11 +22,11 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" PrivateAssets="all"/>
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.279">
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="2.0.283">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.84">
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.100">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user