Files
experiment-adventure-ai/addons/cutscene_editor/editor/UndoRedoManager.gd
2025-08-01 08:34:51 -07:00

246 lines
6.5 KiB
GDScript
Executable File

@tool
class_name UndoRedoManager
extends Object
# Manager for undo/redo operations
# Signals
signal undo_redo_state_changed()
# Properties
var undo_stack: Array = [] # Stack of undo operations
var redo_stack: Array = [] # Stack of redo operations
var max_history: int = 100 # Maximum number of operations to store
var is_processing: bool = false # Flag to prevent recursive processing
# Operation types
enum OperationType {
NODE_ADDED,
NODE_REMOVED,
NODE_MOVED,
NODE_PROPERTY_CHANGED,
CONNECTION_CREATED,
CONNECTION_REMOVED,
GRAPH_CLEARED
}
# Initialize the undo/redo manager
func _init() -> void:
pass
# Add an operation to the undo stack
func add_operation(operation: Dictionary) -> void:
if is_processing:
return
# Add to undo stack
undo_stack.push_back(operation)
# Limit stack size
if undo_stack.size() > max_history:
undo_stack.pop_front()
# Clear redo stack when new operation is added
redo_stack.clear()
# Emit signal
emit_signal("undo_redo_state_changed")
# Perform undo operation
func undo() -> void:
if undo_stack.is_empty():
return
# Set processing flag to prevent recursive calls
is_processing = true
# Get last operation
var operation = undo_stack.pop_back()
# Perform reverse operation
_perform_reverse_operation(operation)
# Add to redo stack
redo_stack.push_back(operation)
# Limit redo stack size
if redo_stack.size() > max_history:
redo_stack.pop_front()
# Clear processing flag
is_processing = false
# Emit signal
emit_signal("undo_redo_state_changed")
# Perform redo operation
func redo() -> void:
if redo_stack.is_empty():
return
# Set processing flag to prevent recursive calls
is_processing = true
# Get last redo operation
var operation = redo_stack.pop_back()
# Perform original operation
_perform_operation(operation)
# Add to undo stack
undo_stack.push_back(operation)
# Limit undo stack size
if undo_stack.size() > max_history:
undo_stack.pop_front()
# Clear processing flag
is_processing = false
# Emit signal
emit_signal("undo_redo_state_changed")
# Check if undo is possible
func can_undo() -> bool:
return not undo_stack.is_empty()
# Check if redo is possible
func can_redo() -> bool:
return not redo_stack.is_empty()
# Clear all history
func clear_history() -> void:
undo_stack.clear()
redo_stack.clear()
emit_signal("undo_redo_state_changed")
# Perform an operation
func _perform_operation(operation: Dictionary) -> void:
# This would be implemented in the graph editor
pass
# Perform the reverse of an operation
func _perform_reverse_operation(operation: Dictionary) -> void:
match operation["type"]:
OperationType.NODE_ADDED:
_reverse_node_added(operation)
OperationType.NODE_REMOVED:
_reverse_node_removed(operation)
OperationType.NODE_MOVED:
_reverse_node_moved(operation)
OperationType.NODE_PROPERTY_CHANGED:
_reverse_node_property_changed(operation)
OperationType.CONNECTION_CREATED:
_reverse_connection_created(operation)
OperationType.CONNECTION_REMOVED:
_reverse_connection_removed(operation)
OperationType.GRAPH_CLEARED:
_reverse_graph_cleared(operation)
# Create operation for node added
func create_node_added_operation(node: BaseGraphNode) -> Dictionary:
return {
"type": OperationType.NODE_ADDED,
"node_name": node.name,
"node_type": node.node_type,
"position": node.position_offset,
"parameters": node.action_parameters.duplicate(true)
}
# Reverse node added operation
func _reverse_node_added(operation: Dictionary) -> void:
# This would remove the node in the graph editor
pass
# Create operation for node removed
func create_node_removed_operation(node: BaseGraphNode) -> Dictionary:
return {
"type": OperationType.NODE_REMOVED,
"node_name": node.name,
"node_type": node.node_type,
"position": node.position_offset,
"parameters": node.action_parameters.duplicate(true),
"connections": _get_node_connections(node.name)
}
# Reverse node removed operation
func _reverse_node_removed(operation: Dictionary) -> void:
# This would add the node back in the graph editor
pass
# Create operation for node moved
func create_node_moved_operation(node_name: String, old_position: Vector2, new_position: Vector2) -> Dictionary:
return {
"type": OperationType.NODE_MOVED,
"node_name": node_name,
"old_position": old_position,
"new_position": new_position
}
# Reverse node moved operation
func _reverse_node_moved(operation: Dictionary) -> void:
# This would move the node back to its old position in the graph editor
pass
# Create operation for node property changed
func create_node_property_changed_operation(node_name: String, property_name: String, old_value, new_value) -> Dictionary:
return {
"type": OperationType.NODE_PROPERTY_CHANGED,
"node_name": node_name,
"property_name": property_name,
"old_value": old_value,
"new_value": new_value
}
# Reverse node property changed operation
func _reverse_node_property_changed(operation: Dictionary) -> void:
# This would restore the old property value in the graph editor
pass
# Create operation for connection created
func create_connection_created_operation(from_node: String, from_port: int, to_node: String, to_port: int) -> Dictionary:
return {
"type": OperationType.CONNECTION_CREATED,
"from_node": from_node,
"from_port": from_port,
"to_node": to_node,
"to_port": to_port
}
# Reverse connection created operation
func _reverse_connection_created(operation: Dictionary) -> void:
# This would remove the connection in the graph editor
pass
# Create operation for connection removed
func create_connection_removed_operation(from_node: String, from_port: int, to_node: String, to_port: int) -> Dictionary:
return {
"type": OperationType.CONNECTION_REMOVED,
"from_node": from_node,
"from_port": from_port,
"to_node": to_node,
"to_port": to_port
}
# Reverse connection removed operation
func _reverse_connection_removed(operation: Dictionary) -> void:
# This would recreate the connection in the graph editor
pass
# Create operation for graph cleared
func create_graph_cleared_operation(nodes: Array, connections: Array) -> Dictionary:
return {
"type": OperationType.GRAPH_CLEARED,
"nodes": nodes.duplicate(true),
"connections": connections.duplicate(true)
}
# Reverse graph cleared operation
func _reverse_graph_cleared(operation: Dictionary) -> void:
# This would restore all nodes and connections in the graph editor
pass
# Get connections for a node
func _get_node_connections(node_name: String) -> Array:
# This would retrieve all connections to/from the node
return []