|
using System.Threading; |
|
using UnityEngine; |
|
|
|
|
|
public class DestroyCancellationTokeTest : MonoBehaviour |
|
{ |
|
private CancellationToken _token; |
|
|
|
private void Awake() |
|
{ |
|
Log($"Awake(), default state: {_token.CanBeCanceled} {_token.IsCancellationRequested}"); |
|
} |
|
|
|
private void OnEnable() |
|
{ |
|
_token = destroyCancellationToken; |
|
Log($"OnEnable(), created state: {_token.CanBeCanceled} {_token.IsCancellationRequested}"); |
|
Log($"OnEnable(), are equal: {_token == destroyCancellationToken}"); |
|
|
|
_token.Register(() => { this.Log($"Registered synchron callback: {this._token.CanBeCanceled} {this._token.IsCancellationRequested}"); }, true); |
|
_token.Register(() => { this.Log($"Registered not synchron callback: {this._token.CanBeCanceled} {this._token.IsCancellationRequested}"); }, false); |
|
_token.Register(() => { this.Log($"Registered not synchron2 callback: {this._token.CanBeCanceled} {this._token.IsCancellationRequested}"); }, false); |
|
_token.Register(() => { this.Log($"Registered synchron2 callback: {this._token.CanBeCanceled} {this._token.IsCancellationRequested}"); }, true); |
|
} |
|
|
|
private void Start() |
|
{ |
|
Log($"Start(), before destroy call: {_token.CanBeCanceled} {_token.IsCancellationRequested}"); |
|
|
|
// # Behavior of Object.Destroy() in Unity 6.3: |
|
// # 1. this.OnDisable() called immediately, before next line. |
|
// # 2. Next line after Destroy() is executed with `this != null`. |
|
// # All next steps are delayed. |
|
// # 3. Internally `_token.IsCancellationRequested` is set to `true`. |
|
// # 4. Calls token's registered callbacks in **REVERSE** order. |
|
// # 5. Calls this.OnDestroy(). |
|
// # NOTE: Unity's null check `this == null` **NEVER** returns true in this chain. |
|
// # NOTE: After Destroy() is called no other callbacks (Update, LateUpdate) will be invoked despite delayed execution of steps 3,4,5. |
|
Destroy(this); |
|
|
|
// # Behavior of Object.DestroyImmediate() in Unity 6.3: |
|
// # 1. this.OnDisable() called immediately, before next line. `this != null` and `isCancelled == false`. |
|
// # 2. Internally `_token.IsCancellationRequested` is set to `true`. |
|
// # 3. Calls registered callbacks in **REVERSE** order. `this != null` and `isCancelled == true`. |
|
// # 4. Calls this.OnDestroy() immediately, before next line. `this != null` and `isCancelled == true`. |
|
// # 5. Next line after DestroyImmediate() is executed, finally `this == null`. |
|
// DestroyImmediate(this); |
|
Log($"Start(), after destroy call: {_token.CanBeCanceled} {_token.IsCancellationRequested}"); |
|
} |
|
|
|
private void Update() |
|
{ |
|
Log($"Update() {_token.CanBeCanceled} {_token.IsCancellationRequested}"); |
|
} |
|
|
|
private void LateUpdate() |
|
{ |
|
Log($"LateUpdate() {_token.CanBeCanceled} {_token.IsCancellationRequested}"); |
|
} |
|
|
|
private void OnDisable() |
|
{ |
|
Log($"OnDisable() {_token.CanBeCanceled} {_token.IsCancellationRequested}"); |
|
} |
|
|
|
private void OnDestroy() |
|
{ |
|
Log($"OnDestroy() {_token.CanBeCanceled} {_token.IsCancellationRequested}"); |
|
} |
|
|
|
private void Log(string message) |
|
{ |
|
Debug.Log($"[DestroyCancellationTokeTest] {message}, {(this == null ? "THIS IS NULL" : "")}"); |
|
} |
|
} |