Implemented TweenChannel.
This commit is contained in:
parent
73bcc8c315
commit
1437194677
|
@ -0,0 +1,62 @@
|
||||||
|
class_name TweenChannel extends RefCounted
|
||||||
|
## Arbitrates between concurrent tweens, e.g. of the same property.
|
||||||
|
|
||||||
|
## Emitted when a tween finishes or is killed.
|
||||||
|
signal terminated(what: Tween)
|
||||||
|
|
||||||
|
## How to arbitrate between a tween request and an already running tween.
|
||||||
|
enum ArbitrationMode {
|
||||||
|
YIELD, ## Request yields until there is no longer any current tween.
|
||||||
|
REPLACE, ## Rather than request yielding, current tween is killed.
|
||||||
|
IGNORE ## Rather than request yielding, request is denied (returns null).
|
||||||
|
}
|
||||||
|
|
||||||
|
## How to arbitrate between a tween request and an already running tween.
|
||||||
|
var arbitration_mode := ArbitrationMode.YIELD
|
||||||
|
## Tween currently running if any, else null.
|
||||||
|
var current_tween: Tween = null
|
||||||
|
|
||||||
|
## Returns target.create_tween() if and when arbitration_mode allows.
|
||||||
|
##
|
||||||
|
## "If:" if arbitration_mode is IGNORE and there is a current tween,
|
||||||
|
## then null is returned.
|
||||||
|
## "When:" if arbitration_mode is YIELD and there is a current tween,
|
||||||
|
## then this function yields until there is not.
|
||||||
|
## (If arbitration_mode is REPLACE and there is a current tween,
|
||||||
|
## then this function returns target.create_tween() immediately,
|
||||||
|
## and the preexisting current tween is killed.)
|
||||||
|
func create_tween(target: Variant) -> Tween:
|
||||||
|
assert(target is Node or target is SceneTree)
|
||||||
|
match arbitration_mode:
|
||||||
|
ArbitrationMode.YIELD:
|
||||||
|
while current_tween:
|
||||||
|
await terminated
|
||||||
|
ArbitrationMode.REPLACE:
|
||||||
|
if current_tween and current_tween.is_valid():
|
||||||
|
current_tween.kill()
|
||||||
|
ArbitrationMode.IGNORE:
|
||||||
|
if current_tween:
|
||||||
|
return null
|
||||||
|
current_tween = target.create_tween()
|
||||||
|
_cleanup_later(current_tween)
|
||||||
|
return current_tween
|
||||||
|
|
||||||
|
## Yields until the given tween has terminated.
|
||||||
|
##
|
||||||
|
## The given tween must have been created with self.create_tween.
|
||||||
|
func sync(what: Tween) -> void:
|
||||||
|
var last_terminated: Tween = null
|
||||||
|
while last_terminated != what:
|
||||||
|
last_terminated = await terminated
|
||||||
|
|
||||||
|
## Yields until the given tween is invalid and then cleans up bookkeeping.
|
||||||
|
##
|
||||||
|
## Bookkeeping cleanup entails the following:
|
||||||
|
## - if the given tween is the current tween, clears the current tween;
|
||||||
|
## - terminated is emitted with the given tween as the argument.
|
||||||
|
func _cleanup_later(what: Tween) -> void:
|
||||||
|
while what.is_valid():
|
||||||
|
await Wait.tick()
|
||||||
|
if current_tween == what:
|
||||||
|
current_tween = null
|
||||||
|
terminated.emit(what)
|
Loading…
Reference in New Issue