载入中...
搜索中...
未找到
OS.cpp
浏览该文件的文档.
1#include "os/OS.h"
2
3#include "common/Exception.h"
4#include "common/Module.h"
5#include "common/Capability.h"
6#include "common/GpuInfo.h"
7#include "common/config.h"
8
9#include <simplesquirrel/simplesquirrel.hpp>
10
11#include <SDL2/SDL.h>
12#include <SDL2/SDL_clipboard.h>
13#include <SDL2/SDL_cpuinfo.h>
14#include <SDL2/SDL_power.h>
15
16#include <chrono>
17#include <cstdio>
18#include <cstring>
19#include <fstream>
20#include <string>
21
22#if defined(EVENGINE_WINDOWS) || defined(_WIN32)
23#ifndef NOMINMAX
24#define NOMINMAX
25#endif
26#include <windows.h>
27#include <psapi.h>
28#elif defined(__APPLE__)
29#include <mach/mach.h>
30#endif
31
32namespace eve::os {
33namespace {
34
36eve::caps::IGpuInfo *gpuInfoOrNull() {
37 auto *info = eve::cap::query<eve::caps::IGpuInfo>();
38 return (info && info->gpuReady()) ? info : nullptr;
39}
40
41} // namespace
42
44
46 SDL_InitSubSystem(SDL_INIT_TIMER);
47 cap::provide<IFramePacing>(this);
48}
49
50OS::~OS() { cap::revoke<IFramePacing>(this); }
51
53 if (count < 0 || count > 2)
55 "VSync count must be in [0,2]", "count",
56 {}, "os.framePacing"));
57 verticalSyncCount_ = count;
58 lastFrameCounter_ = 0;
59 return Result<void>::success();
60}
61
63 if (target < -1 || target > 240)
65 "target FPS must be in [-1,240]", "target",
66 {}, "os.framePacing"));
67 targetFramesPerSecond_ = target;
68 lastFrameCounter_ = 0;
69 return Result<void>::success();
70}
71
73 const uint64_t now = SDL_GetPerformanceCounter();
74 const uint64_t frequency = SDL_GetPerformanceFrequency();
75 if (lastFrameCounter_ == 0 || frequency == 0) {
76 lastFrameCounter_ = now;
77 return;
78 }
79 if (verticalSyncCount_ == 0 && targetFramesPerSecond_ > 0) {
80 const double target = static_cast<double>(frequency) / static_cast<double>(targetFramesPerSecond_);
81 const double elapsed = static_cast<double>(now - lastFrameCounter_);
82 if (elapsed < target) {
83 const uint32_t milliseconds =
84 static_cast<uint32_t>((target - elapsed) * 1000.0 / static_cast<double>(frequency));
85 if (milliseconds > 0) SDL_Delay(milliseconds);
86 }
87 }
88 lastFrameCounter_ = SDL_GetPerformanceCounter();
89}
90
91std::string OS::getEngineVersion() const { return EVENGINE_VERSION; }
92
93std::string OS::getPlatform() const {
94 const char *p = SDL_GetPlatform();
95 return p ? p : "Unknown";
96}
97
98std::string OS::getOS() const {
99#if defined(EVENGINE_WINDOWS)
100 return "Windows";
101#elif defined(EVENGINE_IOS)
102 return "iOS";
103#elif defined(EVENGINE_MACOSX)
104 return "OS X";
105#elif defined(EVENGINE_ANDROID)
106 return "Android";
107#elif defined(EVENGINE_LINUX)
108 return "Linux";
109#else
110 return getPlatform();
111#endif
112}
113
115 int n = SDL_GetCPUCount();
116 return n > 0 ? n : 1;
117}
118
120 int n = SDL_GetCPUCacheLineSize();
121 return n > 0 ? n : 0;
122}
123
124int OS::getSystemRAM() const {
125 int mb = SDL_GetSystemRAM();
126 return mb > 0 ? mb : 0;
127}
128
130#if defined(EVENGINE_WINDOWS) || defined(_WIN32)
131 PROCESS_MEMORY_COUNTERS pmc{};
132 if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
133 return static_cast<int>(pmc.WorkingSetSize / (1024ull * 1024ull));
134 return 0;
135#elif defined(__APPLE__)
136 task_vm_info_data_t info{};
137 mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
138 if (task_info(mach_task_self(), TASK_VM_INFO, reinterpret_cast<task_info_t>(&info), &count) ==
139 KERN_SUCCESS) {
140 return static_cast<int>(info.phys_footprint / (1024ull * 1024ull));
141 }
142 return 0;
143#elif defined(__linux__) || defined(EVENGINE_ANDROID) || defined(EVENGINE_LINUX)
144 std::ifstream in("/proc/self/status");
145 if (!in) return 0;
146 std::string key;
147 while (in >> key) {
148 if (key == "VmRSS:") {
149 long kb = 0;
150 in >> kb;
151 return static_cast<int>(kb / 1024);
152 }
153 std::string rest;
154 std::getline(in, rest);
155 }
156 return 0;
157#else
158 return 0;
159#endif
160}
161
162float OS::getWallTime() const {
163 using clock = std::chrono::system_clock;
164 auto tp = clock::now().time_since_epoch();
165 auto us = std::chrono::duration_cast<std::chrono::microseconds>(tp).count();
166 return float(double(us) / 1'000'000.0);
167}
168
170 if (ms < 0) throw Exception("OS.sleepMilliseconds: ms must be >= 0");
171 if (ms == 0) return;
172 SDL_Delay(static_cast<Uint32>(ms));
173}
174
175std::string OS::getPowerState() const {
176 int secs = 0, pct = 0;
177 SDL_PowerState st = SDL_GetPowerInfo(&secs, &pct);
178 switch (st) {
179 case SDL_POWERSTATE_ON_BATTERY: return "on_battery";
180 case SDL_POWERSTATE_NO_BATTERY: return "no_battery";
181 case SDL_POWERSTATE_CHARGING: return "charging";
182 case SDL_POWERSTATE_CHARGED: return "charged";
183 default: return "unknown";
184 }
185}
186
188 int secs = -1, pct = -1;
189 SDL_GetPowerInfo(&secs, &pct);
190 return secs;
191}
192
194 int secs = -1, pct = -1;
195 SDL_GetPowerInfo(&secs, &pct);
196 return pct;
197}
198
199std::string OS::getClipboardText() const {
200 if (!SDL_HasClipboardText()) return {};
201 char *t = SDL_GetClipboardText();
202 if (!t) return {};
203 std::string out(t);
204 SDL_free(t);
205 return out;
206}
207
208void OS::setClipboardText(const std::string &text) {
209 if (SDL_SetClipboardText(text.c_str()) != 0)
210 throw Exception("OS.setClipboardText failed: %s", SDL_GetError());
211}
212
213std::string OS::getGpuName() const {
214 auto *info = gpuInfoOrNull();
215 return info ? info->gpuName() : std::string();
216}
217
218std::string OS::getGpuVendor() const {
219 auto *info = gpuInfoOrNull();
220 return info ? info->gpuVendor() : std::string();
221}
222
223std::string OS::getGpuDeviceType() const {
224 auto *info = gpuInfoOrNull();
225 return info ? info->gpuDeviceType() : std::string();
226}
227
229 auto *info = gpuInfoOrNull();
230 return info ? info->gpuMemoryTotalMB() : 0;
231}
232
233void OS::expose(ssq::Table &table) {
234 auto cls = table.addClass("OS", OS::create, false);
235 expose(cls);
236}
237
238void OS::expose(ssq::Class &cls) {
239 cls.addFunc("getName", &OS::getName);
240 cls.addFunc("getEngineVersion", &OS::getEngineVersion);
241 cls.addFunc("getPlatform", &OS::getPlatform);
242 cls.addFunc("getOS", &OS::getOS);
243 cls.addFunc("getProcessorCount", &OS::getProcessorCount);
244 cls.addFunc("getCPUCacheLineSize", &OS::getCPUCacheLineSize);
245 cls.addFunc("getSystemRAM", &OS::getSystemRAM);
246 cls.addFunc("getProcessMemoryMB", &OS::getProcessMemoryMB);
247 cls.addFunc("getWallTime", &OS::getWallTime);
248 cls.addFunc("sleepMilliseconds", &OS::sleepMilliseconds);
249 cls.addFunc("limitFrame", &OS::limitFrame);
250 cls.addFunc("getVerticalSyncCount", [](const OS* os) { return os->getVerticalSyncCount(); });
251 cls.addFunc("getTargetFramesPerSecond", [](const OS* os) { return os->getTargetFramesPerSecond(); });
252 cls.addFunc("setTargetFramesPerSecond", [](OS* os, int target) {
253 auto result = os->setTargetFramesPerSecond(target);
254 if (!result.ok()) throw Exception("OS.setTargetFramesPerSecond: target must be in [-1,240]");
255 });
256 cls.addFunc("getPowerState", &OS::getPowerState);
257 cls.addFunc("getPowerSecondsLeft", &OS::getPowerSecondsLeft);
258 cls.addFunc("getPowerPercent", &OS::getPowerPercent);
259 cls.addFunc("getClipboardText", &OS::getClipboardText);
260 cls.addFunc("setClipboardText", &OS::setClipboardText);
261 cls.addFunc("getGpuName", &OS::getGpuName);
262 cls.addFunc("getGpuVendor", &OS::getGpuVendor);
263 cls.addFunc("getGpuDeviceType", &OS::getGpuDeviceType);
264 cls.addFunc("getGpuMemoryTotalMB", &OS::getGpuMemoryTotalMB);
265}
266
267} // namespace eve::os
LogicalId target
glm::vec4 p[6]
HSQOBJECT cls
Definition ECS.cpp:21
std::uint32_t key
glm::vec3 n
Definition Grass.cpp:63
std::string text
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:26
double & milliseconds
Definition OnnxGpgpu.cpp:19
float t
std::uint32_t count
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
virtual std::string getName() const =0
Returns the name.
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
EVENGINE_API_FOUNDATION_INLINE public API.
Definition GpuInfo.h:18
OS module — host OS / hardware / wall-clock / clipboard / optional GPU info. Frame timing stays on Ti...
Definition OS.h:19
std::string getOS() const
Normalized OS id for games: "Windows" | "OS X" | "Linux" | "Android" | "iOS" | "Unknown"
Definition OS.cpp:98
std::string getPowerState() const
Power state string: "unknown" | "on_battery" | "no_battery" | "charging" | "charged"
Definition OS.cpp:175
int getGpuMemoryTotalMB() const
Sum of DEVICE_LOCAL heap sizes in MB (0 if unknown / not ready).
Definition OS.cpp:228
Result< void > setVerticalSyncCount(int count) override
Sets the vertical sync count.
Definition OS.cpp:52
int getSystemRAM() const
System RAM in megabytes (0 if unknown).
Definition OS.cpp:124
int getPowerPercent() const
Battery percent 0–100, or -1 if unknown.
Definition OS.cpp:193
void limitFrame() override
Limit frame.
Definition OS.cpp:72
std::string getGpuDeviceType() const
"discrete" | "integrated" | "virtual" | "cpu" | "other" | ""
Definition OS.cpp:223
int getPowerSecondsLeft() const
Estimated seconds of battery left (-1 if unknown).
Definition OS.cpp:187
void sleepMilliseconds(int ms)
Sleep milliseconds.
Definition OS.cpp:169
int getCPUCacheLineSize() const
CPU L1 cache line size in bytes (0 if unknown).
Definition OS.cpp:119
float getWallTime() const
UTC wall-clock seconds since Unix epoch (float for script).
Definition OS.cpp:162
std::string getGpuVendor() const
Returns the gpu vendor.
Definition OS.cpp:218
int getProcessMemoryMB() const
Current process resident memory in megabytes (0 if unknown).
Definition OS.cpp:129
std::string getPlatform() const
Raw SDL platform string (e.g. "Mac OS X", "Windows").
Definition OS.cpp:93
std::string getGpuName() const
GPU queries — empty/0 if Graphics not initialized yet.
Definition OS.cpp:213
std::string getEngineVersion() const
Engine version string (e.g. "v0.1.0").
Definition OS.cpp:91
int getProcessorCount() const
Returns the processor count.
Definition OS.cpp:114
void setClipboardText(const std::string &text)
Sets the clipboard text.
Definition OS.cpp:208
Result< void > setTargetFramesPerSecond(int target) override
Sets the target frames per second.
Definition OS.cpp:62
OS()
Os.
Definition OS.cpp:45
~OS() override
Os.
Definition OS.cpp:50
std::string getClipboardText() const
Returns the clipboard text.
Definition OS.cpp:199
Definition OS.cpp:32
glm::uvec4 info