Use CancellationToken.Register to cancel DOTWeen

pull/485/head
hadashiA 2023-09-07 17:05:11 +09:00
parent 716402a180
commit afe5f57adc
1 changed files with 68 additions and 85 deletions

View File

@ -144,7 +144,6 @@ namespace Cysharp.Threading.Tasks
} }
readonly TweenCallback onCompleteCallbackDelegate; readonly TweenCallback onCompleteCallbackDelegate;
readonly TweenCallback onUpdateDelegate;
Tween tween; Tween tween;
TweenCancelBehaviour cancelBehaviour; TweenCancelBehaviour cancelBehaviour;
@ -152,14 +151,12 @@ namespace Cysharp.Threading.Tasks
CallbackType callbackType; CallbackType callbackType;
bool canceled; bool canceled;
TweenCallback originalUpdateAction;
TweenCallback originalCompleteAction; TweenCallback originalCompleteAction;
UniTaskCompletionSourceCore<AsyncUnit> core; UniTaskCompletionSourceCore<AsyncUnit> core;
TweenConfiguredSource() TweenConfiguredSource()
{ {
onCompleteCallbackDelegate = OnCompleteCallbackDelegate; onCompleteCallbackDelegate = OnCompleteCallbackDelegate;
onUpdateDelegate = OnUpdate;
} }
public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, CallbackType callbackType, out short token) public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, CallbackType callbackType, out short token)
@ -179,17 +176,8 @@ namespace Cysharp.Threading.Tasks
result.cancelBehaviour = cancelBehaviour; result.cancelBehaviour = cancelBehaviour;
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.callbackType = callbackType; result.callbackType = callbackType;
result.originalUpdateAction = tween.onUpdate;
result.canceled = false; result.canceled = false;
if (result.originalUpdateAction == result.onUpdateDelegate)
{
result.originalUpdateAction = null;
}
tween.onUpdate = result.onUpdateDelegate;
switch (callbackType) switch (callbackType)
{ {
case CallbackType.Kill: case CallbackType.Kill:
@ -225,6 +213,73 @@ namespace Cysharp.Threading.Tasks
result.originalCompleteAction = null; result.originalCompleteAction = null;
} }
if (cancellationToken.CanBeCanceled)
{
cancellationToken.RegisterWithoutCaptureExecutionContext(x =>
{
var source = (TweenConfiguredSource)x;
switch (source.cancelBehaviour)
{
case TweenCancelBehaviour.Kill:
default:
source.tween.Kill(false);
break;
case TweenCancelBehaviour.KillAndCancelAwait:
source.canceled = true;
source.tween.Kill(false);
break;
case TweenCancelBehaviour.KillWithCompleteCallback:
source.tween.Kill(true);
break;
case TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait:
source.canceled = true;
source.tween.Kill(true);
break;
case TweenCancelBehaviour.Complete:
source.tween.Complete(false);
break;
case TweenCancelBehaviour.CompleteAndCancelAwait:
source.canceled = true;
source.tween.Complete(false);
break;
case TweenCancelBehaviour.CompleteWithSequenceCallback:
source.tween.Complete(true);
break;
case TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait:
source.canceled = true;
source.tween.Complete(true);
break;
case TweenCancelBehaviour.CancelAwait:
// restore to original callback
switch (callbackType)
{
case CallbackType.Kill:
tween.onKill = source.originalCompleteAction;
break;
case CallbackType.Complete:
tween.onComplete = source.originalCompleteAction;
break;
case CallbackType.Pause:
tween.onPause = source.originalCompleteAction;
break;
case CallbackType.Play:
tween.onPlay = source.originalCompleteAction;
break;
case CallbackType.Rewind:
tween.onRewind = source.originalCompleteAction;
break;
case CallbackType.StepComplete:
tween.onStepComplete = source.originalCompleteAction;
break;
default:
break;
}
source.core.TrySetCanceled(source.cancellationToken);
break;
}
}, result);
}
TaskTracker.TrackActiveTask(result, 3); TaskTracker.TrackActiveTask(result, 3);
token = result.core.Version; token = result.core.Version;
@ -255,76 +310,6 @@ namespace Cysharp.Threading.Tasks
} }
} }
void OnUpdate()
{
if (!cancellationToken.IsCancellationRequested)
{
originalUpdateAction?.Invoke();
return;
}
switch (this.cancelBehaviour)
{
case TweenCancelBehaviour.Kill:
default:
this.tween.Kill(false);
break;
case TweenCancelBehaviour.KillAndCancelAwait:
this.canceled = true;
this.tween.Kill(false);
break;
case TweenCancelBehaviour.KillWithCompleteCallback:
this.tween.Kill(true);
break;
case TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait:
this.canceled = true;
this.tween.Kill(true);
break;
case TweenCancelBehaviour.Complete:
this.tween.Complete(false);
break;
case TweenCancelBehaviour.CompleteAndCancelAwait:
this.canceled = true;
this.tween.Complete(false);
break;
case TweenCancelBehaviour.CompleteWithSequenceCallback:
this.tween.Complete(true);
break;
case TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait:
this.canceled = true;
this.tween.Complete(true);
break;
case TweenCancelBehaviour.CancelAwait:
// restore to original callback
switch (callbackType)
{
case CallbackType.Kill:
tween.onKill = originalCompleteAction;
break;
case CallbackType.Complete:
tween.onComplete = originalCompleteAction;
break;
case CallbackType.Pause:
tween.onPause = originalCompleteAction;
break;
case CallbackType.Play:
tween.onPlay = originalCompleteAction;
break;
case CallbackType.Rewind:
tween.onRewind = originalCompleteAction;
break;
case CallbackType.StepComplete:
tween.onStepComplete = originalCompleteAction;
break;
default:
break;
}
this.core.TrySetCanceled(this.cancellationToken);
break;
}
}
static void DoCancelBeforeCreate(Tween tween, TweenCancelBehaviour tweenCancelBehaviour) static void DoCancelBeforeCreate(Tween tween, TweenCancelBehaviour tweenCancelBehaviour)
{ {
@ -391,7 +376,6 @@ namespace Cysharp.Threading.Tasks
{ {
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
core.Reset(); core.Reset();
tween.onUpdate = originalUpdateAction;
switch (callbackType) switch (callbackType)
{ {
@ -419,7 +403,6 @@ namespace Cysharp.Threading.Tasks
tween = default; tween = default;
cancellationToken = default; cancellationToken = default;
originalUpdateAction = default;
originalCompleteAction = default; originalCompleteAction = default;
return pool.TryPush(this); return pool.TryPush(this);
} }