# ReenterLock.gd extends Node class_name PlayerReenterLock #### 目前无需全局,仅需跟随 ground #### 因此无需在 exit 时重置锁,也无需推迟计数 #### 因为 PlayerReenterLock 生命周期与 ground 一致 ####### PlayerReenterLock 系统提供了以下特性 ############# # 可重入性:每个事件可以多次锁定/解锁,通过计数器管理 # 全局状态追踪:使用静态变量追踪整体锁定状态 [无需启用] # 生命周期管理:自动处理节点进入/退出场景树的情况 [无需启用] # 错误保护:防止过度释放,并在出现问题时发出警告 # 调试支持:可选的调试模式输出详细信息 # 便捷方法:提供同时锁定/解锁两种状态的方法 ################################################# signal freeze_changed(count: int, is_add: bool) signal hold_changed(count: int, is_add: bool) # 实例级别的锁定请求追踪 var _freeze_requests: int = 0 var _hold_requests: int = 0 # 调试模式 var debug_mode := GlobalConfig.DEBUG func _exit_tree() -> void: if _freeze_requests > 0: if debug_mode: push_warning( "[ReenterLock] Remains %d freeze requests on exit_tree. parent=" % _freeze_requests, get_parent() ) if _hold_requests > 0: if debug_mode: print( "[ReenterLock] Remains %d hold requests on exit_tree. parent=" % _hold_requests, get_parent() ) func _create_timer(duration: float, callable: Callable): if duration > 0 and callable: get_tree().create_timer(duration).timeout.connect(callable) # Freeze 相关方法 func freeze(duration := 0.0) -> void: if duration > 0: _create_timer(duration, release) _freeze_requests += 1 if debug_mode: print("[ReenterLock] Freeze applied: ", _freeze_requests) freeze_changed.emit(_freeze_requests, true) func release() -> void: if _freeze_requests <= 0: push_warning( ( "[ReenterLock] Attempting to release more times than frozen! Current local count: %d" % _freeze_requests ) ) return _freeze_requests -= 1 if debug_mode: print("[ReenterLock] Release applied: ", _freeze_requests) freeze_changed.emit(_freeze_requests, false) # Hold 相关方法 func hold(duration := 0.0) -> void: if duration > 0: _create_timer(duration, unhold) _hold_requests += 1 if debug_mode: print("[ReenterLock] Hold applied: ", _hold_requests) hold_changed.emit(_hold_requests, true) func unhold() -> void: if _hold_requests <= 0: push_warning( ( "[ReenterLock] Attempting to unhold more times than held! Current local count: %d" % _hold_requests ) ) return _hold_requests -= 1 if debug_mode: print("[ReenterLock] Unhold applied: ", _hold_requests) hold_changed.emit(_hold_requests, false) # 静态方法:查询当前状态 func is_frozen() -> bool: return _freeze_requests > 0 func is_held() -> bool: return _hold_requests > 0 func get_freeze_count() -> int: return _freeze_requests func get_hold_count() -> int: return _hold_requests # 便捷方法:同时锁定移动和输入 func lock_all(duration := 0.0) -> void: if duration > 0: _create_timer(duration, unlock_all) _hold_requests += 1 _freeze_requests += 1 if debug_mode: prints("[ReenterLock] LockAll applied (hold, freeze): ", _hold_requests, _freeze_requests) hold_changed.emit(_hold_requests, true) freeze_changed.emit(_freeze_requests, true) func unlock_all() -> void: release() unhold() func _to_string() -> String: return "[ReenterLock] Freeze: %d, Hold: %d" % [_freeze_requests, _hold_requests]