This repository has been archived on 2024-04-19. You can view files and clone it, but cannot push or open issues or pull requests.
Jessist/addons/godot-action/Core/GDAction.gd

256 lines
6.7 KiB
GDScript3
Raw Normal View History

2022-06-18 13:05:48 +02:00
class_name GDAction extends Reference
signal action_finished()
signal action_cancelled()
var delay = 0.0
var speed = 1.0
var time_func = null
var ease_func_value = null
var _cache_action_node = Dictionary()
var _gd_utils
func _init(gd_utils: Node):
_gd_utils = gd_utils
# This func needs to be overridden in subclass
func _create_action_node(key: String, node: Node):
var action_node = GDActionNode.new(self, key, node)
action_node.time_func = time_func
action_node.ease_func_value = ease_func_value
return action_node
# Key is the id of the action-node,
# It determines whether the gd-action needs to be created or reused from the cache.
func _create_key(node: Node) -> String:
if is_instance_valid(node):
return String(node.get_instance_id()) + "_" + String(self.get_instance_id())
return String(self.get_instance_id())
func _create_key_by_parent_key(parent_key: String) -> String:
return parent_key + "_" + String(self.get_instance_id())
# Key will be updated if this gd-action is a child of chaining-action
func _update_key_if_need(key: String) -> String:
return key
func _create_action_node_by_key(key: String, node: Node) -> GDActionNode:
if _cache_action_node.has(key):
var action_node = _cache_action_node[key]
if action_node != null:
return action_node
var action_node = _create_action_node(key, node)
_cache_action_node[key] = action_node
return action_node
# Remove action
func _prepare_remove_action_node_from_key(key: String):
pass
func _remove_action_node_from_key(key: String):
_prepare_remove_action_node_from_key(key)
if _cache_action_node.has(key):
_cache_action_node[key].queue_free()
_cache_action_node.erase(key)
func _remove_action_node(action_node: GDActionNode):
_remove_action_node_from_key(action_node.key)
# This func can be called if this action is a child-action in the chaining-action
func _remove_action_node_from_parent_key(key: String):
var child_key = _update_key_if_need(key)
_remove_action_node_from_key(child_key)
# Func start(with_node) is public func.
# The user will use this func to run the action
func start(node: Node):
var action_key = _create_key(node)
var action_node = _create_action_node_by_key(action_key, node)
action_node.is_remove_when_done = true
_gd_utils._cache.add_action_node(action_node)
_run_action(action_node, delay, speed)
# This func is called when the action is started from a chaining aciton
func _start_from_action(node: Node, key: String, speed: float) -> GDActionNode:
var child_key = _update_key_if_need(key)
var action_node = _create_action_node_by_key(child_key, node)
_run_action(action_node, delay, self.speed * speed)
return action_node
# This func needs to be overridden in subclassnode
func _run_action(action_node: GDActionNode, delay: float, speed: float):
if action_node.get_parent() == null and is_instance_valid(action_node.node):
if is_instance_valid(_gd_utils):
_gd_utils._cache.add_child(action_node)
else:
action_node.node.get_tree().get_root().add_child(action_node)
# Pause old action node running
_pause_action_with_key(action_node.key)
# This method always returns an action object; however, not all actions are reversible.
# When reversed, some actions return an object that either does nothing or
# that performs the same action as the original action.
func reversed():
return self
# Function callback when action node complete
func _on_action_node_completed(action_node: GDActionNode):
# print("_on_action_node_completed: " + action_node.get_class())
emit_signal("action_finished")
if action_node.is_remove_when_done:
_gd_utils._cache.remove_action_node(action_node)
_remove_action_node(action_node)
func _on_action_node_cancelled(action_node: GDActionNode):
# print("_on_action_node_cancelled: " + action_node.get_class())
emit_signal("action_cancelled")
if action_node.is_remove_when_done:
_gd_utils._cache.remove_action_node(action_node)
_remove_action_node(action_node)
# Config property action
func with_delay(delay: float) -> GDAction:
self.delay = delay
return self
func with_speed(speed: float) -> GDAction:
self.speed = speed
return self
func with_time_func(time_func: Curve) -> GDAction:
self.time_func = time_func
return self
func with_easing(ease_func_value: float) -> GDAction:
self.ease_func_value = ease_func_value
return self
# Stop action
# Need override, used to pause dependent action nodes (ex: list_node in sequence or group...)
func _prepare_pause_action_with_key(key: String):
pass
func _pause_action_with_key(key: String):
_prepare_pause_action_with_key(key)
if _cache_action_node.has(key):
_cache_action_node[key].pause()
func _pause_action_with_parem_key(key: String):
var child_key = _update_key_if_need(key)
_pause_action_with_key(child_key)
func pause_action_on_node(node: Node):
var key = _create_key(node)
_pause_action_with_key(key)
func pause_all():
for key in _cache_action_node:
_pause_action_with_key(key)
# Resume action
# Need override, used to resume dependent action nodes (ex: list_node in sequence or group...)
func _prepare_resume_action_with_key(key: String):
pass
func _resume_action_with_key(key: String):
_prepare_resume_action_with_key(key)
if _cache_action_node.has(key):
_cache_action_node[key].resume()
func _resume_action_with_parem_key(key: String):
var child_key = _update_key_if_need(key)
_resume_action_with_key(child_key)
func resume_action_on_node(node: Node):
var key = _create_key(node)
_resume_action_with_key(key)
func resume_all():
for key in _cache_action_node:
_resume_action_with_key(key)
# Cancelled action
# Need override, used to cancel dependent action nodes (ex: list_node in sequence or group...)
func _prepare_cancel_action_with_key(key: String):
pass
func _cancel_action_with_key(key: String):
_prepare_cancel_action_with_key(key)
if _cache_action_node.has(key):
_cache_action_node[key].cancel()
func _cancel_action_with_parem_key(key: String):
var child_key = _update_key_if_need(key)
_cancel_action_with_key(child_key)
func cancel_action_on_node(node: Node):
var key = _create_key(node)
_cancel_action_with_key(key)
func cancel_all():
for key in _cache_action_node:
_cancel_action_with_key(key)
# Finish action
# Need override, used to finish dependent action nodes (ex: list_node in sequence or group...)
func _prepare_finish_action_with_key(key: String):
pass
func _finish_action_with_key(key: String):
_prepare_finish_action_with_key(key)
if _cache_action_node.has(key):
_cache_action_node[key].finished()
func _finish_action_with_parem_key(key: String):
var child_key = _update_key_if_need(key)
_finish_action_with_key(child_key)
func finish_action_on_node(node: Node):
var key = _create_key(node)
_finish_action_with_key(key)
func finish_all():
for key in _cache_action_node:
_finish_action_with_key(key)