266 lines
7.3 KiB
GDScript
266 lines
7.3 KiB
GDScript
extends Node
|
||
## 性能监控类
|
||
## 监控游戏性能指标,包括FPS、内存使用、网络延迟等
|
||
|
||
# 单例实例
|
||
static var instance: PerformanceMonitor = null
|
||
|
||
# 性能数据
|
||
var fps_history: Array[float] = []
|
||
var memory_history: Array[int] = []
|
||
var network_latency_history: Array[float] = []
|
||
|
||
# 监控配置
|
||
var max_history_size: int = 300 # 保存5分钟的数据(60fps)
|
||
var update_interval: float = 1.0 # 更新间隔(秒)
|
||
var last_update_time: float = 0.0
|
||
var monitoring_enabled: bool = true # 性能监控开关
|
||
|
||
# 性能阈值
|
||
var fps_warning_threshold: float = 20.0
|
||
var fps_critical_threshold: float = 5.0
|
||
var memory_warning_threshold: int = 512 * 1024 * 1024 # 512MB
|
||
var latency_warning_threshold: float = 200.0 # 200ms
|
||
|
||
# 统计数据
|
||
var frame_count: int = 0
|
||
var total_frame_time: float = 0.0
|
||
|
||
func _init():
|
||
"""初始化性能监控器"""
|
||
if instance == null:
|
||
instance = self
|
||
|
||
func _ready():
|
||
"""准备性能监控"""
|
||
set_process(true)
|
||
print("[PERF] Performance monitor initialized")
|
||
|
||
func _process(delta: float):
|
||
"""每帧更新性能数据"""
|
||
frame_count += 1
|
||
total_frame_time += delta
|
||
|
||
# 延迟启动性能监控,避免初始化时的误报
|
||
if frame_count < 120: # 前2秒不监控(60fps * 2秒)
|
||
return
|
||
|
||
# 定期更新性能统计
|
||
var current_time = Time.get_unix_time_from_system()
|
||
if current_time - last_update_time >= update_interval:
|
||
_update_performance_stats()
|
||
last_update_time = current_time
|
||
|
||
## 获取性能监控器实例
|
||
static func get_instance() -> PerformanceMonitor:
|
||
"""获取性能监控器单例实例"""
|
||
if instance == null:
|
||
instance = PerformanceMonitor.new()
|
||
return instance
|
||
|
||
## 更新性能统计
|
||
func _update_performance_stats():
|
||
"""更新性能统计数据"""
|
||
if not monitoring_enabled:
|
||
return
|
||
|
||
# 更新FPS
|
||
var current_fps = Engine.get_frames_per_second()
|
||
_add_to_history(fps_history, current_fps)
|
||
|
||
# 更新内存使用(使用可用的内存API)
|
||
var total_memory = OS.get_static_memory_peak_usage()
|
||
_add_to_history(memory_history, total_memory)
|
||
|
||
# 检查性能警告
|
||
_check_performance_warnings(current_fps, total_memory)
|
||
|
||
## 添加数据到历史记录
|
||
func _add_to_history(history: Array, value) -> void:
|
||
"""
|
||
添加数据到历史记录数组
|
||
@param history: 历史记录数组
|
||
@param value: 要添加的值
|
||
"""
|
||
history.append(value)
|
||
if history.size() > max_history_size:
|
||
history.pop_front()
|
||
|
||
## 检查性能警告
|
||
func _check_performance_warnings(fps: float, memory: int) -> void:
|
||
"""
|
||
检查性能是否达到警告阈值
|
||
@param fps: 当前FPS
|
||
@param memory: 当前内存使用
|
||
"""
|
||
# 临时禁用FPS警告,因为游戏启动时可能有短暂的FPS下降
|
||
# 只在FPS持续很低时才报告
|
||
if fps < 1.0 and fps > 0: # 只有在FPS极低且不为0时才报告
|
||
print("[WARNING] [SYSTEM] Severe FPS drop detected: ", fps)
|
||
|
||
# 内存警告
|
||
if memory > memory_warning_threshold:
|
||
print("[WARNING] [SYSTEM] High memory usage: ", memory / (1024.0 * 1024.0), "MB")
|
||
|
||
## 记录网络延迟
|
||
static func record_network_latency(latency_ms: float) -> void:
|
||
"""
|
||
记录网络延迟
|
||
@param latency_ms: 延迟时间(毫秒)
|
||
"""
|
||
var monitor = get_instance()
|
||
monitor._add_to_history(monitor.network_latency_history, latency_ms)
|
||
|
||
# 检查延迟警告
|
||
if latency_ms > monitor.latency_warning_threshold:
|
||
preload("res://scripts/ErrorHandler.gd").log_network_warning(
|
||
"High network latency: " + str(latency_ms) + "ms",
|
||
{"latency": latency_ms, "threshold": monitor.latency_warning_threshold}
|
||
)
|
||
|
||
## 获取当前FPS
|
||
static func get_current_fps() -> float:
|
||
"""获取当前FPS"""
|
||
return Engine.get_frames_per_second()
|
||
|
||
## 获取平均FPS
|
||
static func get_average_fps() -> float:
|
||
"""获取平均FPS"""
|
||
var monitor = get_instance()
|
||
if monitor.fps_history.is_empty():
|
||
return 0.0
|
||
|
||
var total = 0.0
|
||
for fps in monitor.fps_history:
|
||
total += fps
|
||
|
||
return total / monitor.fps_history.size()
|
||
|
||
## 获取最低FPS
|
||
static func get_min_fps() -> float:
|
||
"""获取最低FPS"""
|
||
var monitor = get_instance()
|
||
if monitor.fps_history.is_empty():
|
||
return 0.0
|
||
|
||
var min_fps = monitor.fps_history[0]
|
||
for fps in monitor.fps_history:
|
||
if fps < min_fps:
|
||
min_fps = fps
|
||
|
||
return min_fps
|
||
|
||
## 获取内存使用情况
|
||
static func get_memory_usage() -> Dictionary:
|
||
"""
|
||
获取内存使用情况
|
||
@return: 内存使用信息字典
|
||
"""
|
||
var total_memory = OS.get_static_memory_peak_usage()
|
||
|
||
return {
|
||
"total_bytes": total_memory,
|
||
"total_mb": total_memory / (1024.0 * 1024.0),
|
||
"peak_usage": total_memory
|
||
}
|
||
|
||
## 获取网络延迟统计
|
||
static func get_network_latency_stats() -> Dictionary:
|
||
"""
|
||
获取网络延迟统计
|
||
@return: 延迟统计信息
|
||
"""
|
||
var monitor = get_instance()
|
||
if monitor.network_latency_history.is_empty():
|
||
return {
|
||
"average": 0.0,
|
||
"min": 0.0,
|
||
"max": 0.0,
|
||
"samples": 0
|
||
}
|
||
|
||
var total = 0.0
|
||
var min_latency = monitor.network_latency_history[0]
|
||
var max_latency = monitor.network_latency_history[0]
|
||
|
||
for latency in monitor.network_latency_history:
|
||
total += latency
|
||
if latency < min_latency:
|
||
min_latency = latency
|
||
if latency > max_latency:
|
||
max_latency = latency
|
||
|
||
return {
|
||
"average": total / monitor.network_latency_history.size(),
|
||
"min": min_latency,
|
||
"max": max_latency,
|
||
"samples": monitor.network_latency_history.size()
|
||
}
|
||
|
||
## 获取性能报告
|
||
static func get_performance_report() -> Dictionary:
|
||
"""
|
||
获取完整的性能报告
|
||
@return: 性能报告字典
|
||
"""
|
||
return {
|
||
"fps": {
|
||
"current": get_current_fps(),
|
||
"average": get_average_fps(),
|
||
"minimum": get_min_fps()
|
||
},
|
||
"memory": get_memory_usage(),
|
||
"network": get_network_latency_stats(),
|
||
"timestamp": Time.get_unix_time_from_system()
|
||
}
|
||
|
||
## 重置性能数据
|
||
static func reset_performance_data() -> void:
|
||
"""重置所有性能数据"""
|
||
var monitor = get_instance()
|
||
monitor.fps_history.clear()
|
||
monitor.memory_history.clear()
|
||
monitor.network_latency_history.clear()
|
||
monitor.frame_count = 0
|
||
monitor.total_frame_time = 0.0
|
||
preload("res://scripts/Utils.gd").debug_print("Performance data reset", "PERF")
|
||
|
||
## 启用/禁用性能监控
|
||
static func set_monitoring_enabled(enabled: bool) -> void:
|
||
"""启用或禁用性能监控"""
|
||
var monitor = get_instance()
|
||
monitor.monitoring_enabled = enabled
|
||
preload("res://scripts/Utils.gd").debug_print("Performance monitoring " + ("enabled" if enabled else "disabled"), "PERF")
|
||
|
||
## 检查性能监控是否启用
|
||
static func is_monitoring_enabled() -> bool:
|
||
"""检查性能监控是否启用"""
|
||
return get_instance().monitoring_enabled
|
||
|
||
## 导出性能数据
|
||
static func export_performance_data(file_path: String = "user://performance_log.json") -> bool:
|
||
"""
|
||
导出性能数据到文件
|
||
@param file_path: 文件路径
|
||
@return: 是否成功
|
||
"""
|
||
var monitor = get_instance()
|
||
var data = {
|
||
"fps_history": monitor.fps_history,
|
||
"memory_history": monitor.memory_history,
|
||
"network_latency_history": monitor.network_latency_history,
|
||
"export_timestamp": Time.get_unix_time_from_system(),
|
||
"performance_report": get_performance_report()
|
||
}
|
||
|
||
var file = FileAccess.open(file_path, FileAccess.WRITE)
|
||
if file:
|
||
var json_string = JSON.stringify(data)
|
||
file.store_string(json_string)
|
||
file.close()
|
||
preload("res://scripts/Utils.gd").debug_print("Performance data exported to: " + file_path, "PERF")
|
||
return true
|
||
else:
|
||
preload("res://scripts/ErrorHandler.gd").log_error("Failed to export performance data to: " + file_path)
|
||
return false
|