电源管理子系统(CategoryPower)
SDL 提供了轻量的电源管理接口,核心功能是获取设备的电源状态信息,尤其适用于移动设备(如笔记本、平板、手机)上的游戏/应用开发。
该子系统仅包含一个核心函数:SDL_GetPowerInfo()。
典型应用场景
- 检测设备是否使用电池供电,若电池电量低,可降低游戏帧率、关闭特效以减少功耗,延长续航;
- 全屏运行时显示电池电量指示器;
- 电量极低时提醒用户保存游戏进度,避免数据丢失。
函数
- SDL_GetPowerInfo:获取系统电源状态信息,返回 SDL_PowerState 枚举值;同时通过输出参数返回「剩余电池使用时间(秒)」和「电池电量百分比」(不支持的平台/设备返回对应无效值)
数据类型
- (无)
结构体
- (无)
枚举
- SDL_PowerState:电源状态枚举,包含以下取值:
- SDL_POWERSTATE_UNKNOWN:无法确定电源状态(如无电池的台式机、不支持的系统)
- SDL_POWERSTATE_ON_BATTERY:设备正在使用电池供电(未插电)
- SDL_POWERSTATE_NO_BATTERY:设备无电池(如台式机)
- SDL_POWERSTATE_CHARGING:电池正在充电
- SDL_POWERSTATE_CHARGED:电池已充满电
宏
- (无)
FreeBASIC 示例代码
' 引入 SDL 相关声明(需确保 FreeBASIC 已链接 SDL3 库)
#Include "SDL.bi"
' 补充枚举和函数声明(FreeBASIC 绑定可能缺失)
Enum SDL_PowerState
SDL_POWERSTATE_UNKNOWN = 0 ' 未知状态
SDL_POWERSTATE_ON_BATTERY = 1 ' 电池供电
SDL_POWERSTATE_NO_BATTERY = 2 ' 无电池
SDL_POWERSTATE_CHARGING = 3 ' 充电中
SDL_POWERSTATE_CHARGED = 4 ' 已充满
End Enum
Declare Function SDL_GetPowerInfo CDecl (ByRef seconds As Integer, ByRef percent As Integer) As SDL_PowerState
' 转换电源状态枚举为可读字符串
Function PowerStateToString(ByVal state As SDL_PowerState) As ZString Ptr
Select Case state
Case SDL_POWERSTATE_UNKNOWN: Return StrPtr("未知状态")
Case SDL_POWERSTATE_ON_BATTERY: Return StrPtr("电池供电(未插电)")
Case SDL_POWERSTATE_NO_BATTERY: Return StrPtr("无电池(台式机等)")
Case SDL_POWERSTATE_CHARGING: Return StrPtr("充电中")
Case SDL_POWERSTATE_CHARGED: Return StrPtr("电池已充满")
Case Else: Return StrPtr("无效状态")
End Select
End Function
' 获取并打印电源信息
Sub PrintPowerInfo()
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "【当前电源状态信息】")
' 定义输出参数:剩余使用时间(秒)、电量百分比
Dim As Integer remainingSeconds, batteryPercent
Dim As SDL_PowerState powerState = SDL_GetPowerInfo(remainingSeconds, batteryPercent)
' 打印电源状态
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "电源状态:%s", *PowerStateToString(powerState))
' 打印剩余时间(-1 表示无法获取)
If (remainingSeconds = -1) Then
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "剩余使用时间:无法获取")
ElseIf (remainingSeconds = -2) Then
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "剩余使用时间:无限(插电状态)")
Else
Dim As Integer hours = remainingSeconds \ 3600
Dim As Integer minutes = (remainingSeconds Mod 3600) \ 60
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "剩余使用时间:%d小时%d分钟", hours, minutes)
End If
' 打印电量百分比(-1 表示无法获取)
If (batteryPercent = -1) Then
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "电池电量:无法获取")
Else
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "电池电量:%d%%", batteryPercent)
End If
End Sub
' 根据电源状态调整应用配置(节能逻辑)
Sub AdjustAppForPower()
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "【根据电源状态调整应用配置】")
Dim As Integer remainingSeconds, batteryPercent
Dim As SDL_PowerState powerState = SDL_GetPowerInfo(remainingSeconds, batteryPercent)
' 仅在电池供电时执行节能逻辑
If (powerState = SDL_POWERSTATE_ON_BATTERY) Then
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "当前为电池供电模式,执行节能策略")
' 电量 > 50%:正常运行
If (batteryPercent > 50 And batteryPercent <> -1) Then
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "电量充足(%d%%):保持默认配置", batteryPercent)
' 电量 20% ~ 50%:降低帧率
ElseIf (batteryPercent >= 20 And batteryPercent <= 50) Then
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "电量中等(%d%%):帧率降低至 30 FPS", batteryPercent)
' 模拟设置帧率
' SDL_SetWindowDisplayMode(window, &displayMode);
' displayMode.refresh_rate = 30;
' 电量 < 20%:深度节能
ElseIf (batteryPercent > 0 And batteryPercent < 20) Then
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "电量低(%d%%):关闭特效 + 帧率降至 15 FPS", batteryPercent)
' 模拟关闭特效
' DisableSpecialEffects();
' 电量极低(< 10%):提醒保存
ElseIf (batteryPercent > 0 And batteryPercent < 10) Then
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "电量极低(%d%%):请立即保存数据!", batteryPercent)
End If
Else
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "当前为插电/无电池模式:使用高性能配置")
End If
End Sub
' 定时监控电源状态(模拟实时检测)
Sub MonitorPowerState()
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "【实时监控电源状态(5秒)】")
Const MONITOR_DURATION As Integer = 5 ' 监控5秒
Const CHECK_INTERVAL As Integer = 1000 ' 每秒检测一次
For i As Integer = 1 To MONITOR_DURATION
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "=== 第 %d 秒检测 ===", i)
PrintPowerInfo()
SDL_Delay(CHECK_INTERVAL)
Next
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "监控结束")
End Sub
' 主程序
Sub Main()
' 初始化 SDL
If (SDL_Init(0) < 0) Then
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL 初始化失败:%s", SDL_GetError())
Exit Sub
End If
' 运行示例
PrintPowerInfo()
AdjustAppForPower()
MonitorPowerState()
' 清理 SDL
SDL_Quit()
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "程序正常退出")
End Sub
' 运行主程序
Main()
核心知识点补充
-
SDL_GetPowerInfo 返回值规则: 输出参数 无效值 含义说明 remainingSeconds -1 无法获取剩余时间(如设备不支持) remainingSeconds -2 剩余时间无限(设备插电、无电池) batteryPercent -1 无法获取电量百分比(如设备不支持、无电池) -
平台支持说明:
- ✅ Windows/macOS/Linux:支持大部分笔记本/移动设备的电源状态检测;
- ✅ 移动平台(Android/iOS):完善支持电池状态、剩余时间、电量百分比;
- ❌ 无电池设备(台式机、服务器):返回
SDL_POWERSTATE_NO_BATTERY,电量/时间参数返回 -1; - ❌ 部分嵌入式系统:可能返回
SDL_POWERSTATE_UNKNOWN(无电源管理接口)。
-
节能策略设计建议: 电量区间 建议操作 > 50% 高性能模式(满帧率、全特效) 20%~50% 平衡模式(降低帧率至 30 FPS、关闭部分特效) 10%~20% 节能模式(帧率降至 15 FPS、关闭所有特效) < 10% 紧急模式(提醒保存、暂停非核心功能) -
调用频率建议:
- 无需高频调用(电源状态变化缓慢),建议 1~5 秒检测一次即可;
- 避免在游戏主循环中每帧调用,减少系统开销。
总结
-
核心优势:
- 跨平台统一的电源状态检测接口,无需适配不同系统的原生电源 API(如 Windows 的 GetSystemPowerStatus、Android 的 BatteryManager);
- 轻量易用,仅一个核心函数即可获取电源状态、剩余时间、电量百分比;
- 返回值规则清晰,边界条件(如无效值)处理明确,便于容错。
-
使用建议:
- 移动应用/游戏必须接入电源状态检测,根据电量动态调整性能配置,提升用户体验;
- 对返回的无效值(-1/-2)做好容错处理,避免程序崩溃;
- 电量极低时优先提醒用户保存数据,再执行节能逻辑;
- 插电状态下恢复高性能配置,保证体验。
-
关键点回顾:
SDL_GetPowerInfo是电源管理的核心函数,返回电源状态枚举,同时输出剩余时间和电量百分比;- 仅
SDL_POWERSTATE_ON_BATTERY状态下需要执行节能逻辑,其他状态可使用高性能配置; - 无效值(-1/-2)需特殊处理,避免数值异常导致的逻辑错误;
- 检测频率建议 1~5 秒一次,无需高频调用。
评论一下?