载入中...
搜索中...
未找到
AiPanel.cpp
浏览该文件的文档.
3
4#include <chrono>
5#include <ctime>
6#include <sstream>
7
8namespace eve::dev {
9namespace {
10
11AiPanel::ImGuiDrawer g_imguiDrawer = nullptr;
12
13} // namespace
14
16 // Process-immortal singleton: McpServer's detached stdio reader and the
17 // other DevTools singletons may still touch AiPanel during teardown, so
18 // destroying it would let them lock a destroyed mutex (libc++ aborts).
19 // See devtools/Immortal.hpp for the shared contract.
21}
22
23std::string AiPanel::nowStamp() {
24 using clock = std::chrono::system_clock;
25 const auto t = clock::to_time_t(clock::now());
26 std::tm tm{};
27#if defined(_WIN32)
28 localtime_s(&tm, &t);
29#else
30 localtime_r(&t, &tm);
31#endif
32 char buf[32];
33 std::strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
34 return buf;
35}
36
37void AiPanel::setVisible(bool on) {
38 std::lock_guard<std::mutex> lock(mu_);
39 visible_ = on;
40}
41
42bool AiPanel::isVisible() const {
43 std::lock_guard<std::mutex> lock(mu_);
44 return visible_;
45}
46
48
49void AiPanel::setMcpPort(int port) {
50 std::lock_guard<std::mutex> lock(mu_);
51 mcpPort_ = port;
52}
53
54int AiPanel::mcpPort() const {
55 std::lock_guard<std::mutex> lock(mu_);
56 return mcpPort_;
57}
58
60 std::lock_guard<std::mutex> lock(mu_);
61 mcpConnected_ = on;
62}
63
65 std::lock_guard<std::mutex> lock(mu_);
66 return mcpConnected_;
67}
68
69void AiPanel::setClientName(std::string name) {
70 std::lock_guard<std::mutex> lock(mu_);
71 clientName_ = std::move(name);
72}
73
74std::string AiPanel::clientName() const {
75 std::lock_guard<std::mutex> lock(mu_);
76 return clientName_;
77}
78
80 std::lock_guard<std::mutex> lock(mu_);
81 log_.clear();
82}
83
84void AiPanel::addLog(std::string kind, std::string title, std::string detail) {
85 std::lock_guard<std::mutex> lock(mu_);
86 AiLogEntry e;
87 e.timestamp = nowStamp();
88 e.kind = std::move(kind);
89 e.title = std::move(title);
90 e.detail = std::move(detail);
91 log_.push_back(std::move(e));
92 while (log_.size() > maxEntries_) log_.pop_front();
93}
94
95void AiPanel::addNote(std::string text) { addLog("note", "note", std::move(text)); }
96
97std::vector<AiLogEntry> AiPanel::recentLog(size_t max) const {
98 std::lock_guard<std::mutex> lock(mu_);
99 std::vector<AiLogEntry> out;
100 if (log_.empty() || max == 0) return out;
101 const size_t start = log_.size() > max ? log_.size() - max : 0;
102 out.assign(log_.begin() + static_cast<std::ptrdiff_t>(start), log_.end());
103 return out;
104}
105
106std::string AiPanel::formatLog(size_t max) const {
107 auto entries = recentLog(max);
108 std::ostringstream oss;
109 for (const auto& e : entries) {
110 oss << '[' << e.timestamp << "] " << e.kind << " | " << e.title;
111 if (!e.detail.empty()) oss << " — " << e.detail;
112 oss << '\n';
113 }
114 return oss.str();
115}
116
117std::string AiPanel::statusLine() const {
118 std::lock_guard<std::mutex> lock(mu_);
119 std::ostringstream oss;
120 oss << "MCP ";
121 if (mcpPort_ > 0) {
122 oss << "127.0.0.1:" << mcpPort_;
123 oss << (mcpConnected_ ? " connected" : " listening");
124 if (!clientName_.empty()) oss << " (" << clientName_ << ")";
125 } else {
126 oss << "off";
127 }
128 oss << " | log " << log_.size();
129 return oss.str();
130}
131
133 std::lock_guard<std::mutex> lock(mu_);
134 maxEntries_ = n == 0 ? 1 : n;
135 while (log_.size() > maxEntries_) log_.pop_front();
136}
137
138void AiPanel::setImGuiDrawer(ImGuiDrawer fn) { g_imguiDrawer = fn; }
139
141 // ImGui UI lives in eve_imgui (ImGuiBackend) so EVDevTools does not
142 // instantiate imgui.h inlines — that blew the MSVC 65535 export limit.
143 if (g_imguiDrawer) g_imguiDrawer(*this);
144}
145
146} // namespace eve::dev
Tok kind
std::string title
glm::vec3 n
Definition Grass.cpp:64
const char * name
Definition RockMesh.cpp:21
SettlementPipeline::Stage fn
In-engine AI / MCP session surface for DevTools.
Definition AiPanel.hpp:27
void addNote(std::string text)
Definition AiPanel.cpp:95
void setVisible(bool on)
Definition AiPanel.cpp:37
std::string statusLine() const
Compact status line for overlays / MCP resources.
Definition AiPanel.cpp:117
std::string formatLog(size_t max=64) const
Definition AiPanel.cpp:106
std::string clientName() const
Definition AiPanel.cpp:74
std::vector< AiLogEntry > recentLog(size_t max=64) const
Definition AiPanel.cpp:97
void setMcpPort(int port)
Definition AiPanel.cpp:49
void addLog(std::string kind, std::string title, std::string detail={})
Definition AiPanel.cpp:84
bool mcpConnected() const
Definition AiPanel.cpp:64
void toggleVisible()
Definition AiPanel.cpp:47
static AiPanel & instance()
Definition AiPanel.cpp:15
void setMcpConnected(bool on)
Definition AiPanel.cpp:59
void setMaxEntries(size_t n)
Definition AiPanel.cpp:132
int mcpPort() const
Definition AiPanel.cpp:54
void(*)(AiPanel &panel) ImGuiDrawer
Definition AiPanel.hpp:61
static void setImGuiDrawer(ImGuiDrawer fn)
Definition AiPanel.cpp:138
void drawImGui()
Optional ImGui draw hook. Default no-op: in-engine AI status is exposed via MCP / eve....
Definition AiPanel.cpp:140
void setClientName(std::string name)
Definition AiPanel.cpp:69
bool isVisible() const
Definition AiPanel.cpp:42
std::string detail
Definition AiPanel.hpp:17
std::string timestamp
Definition AiPanel.hpp:14
std::string kind
Definition AiPanel.hpp:15
std::string title
Definition AiPanel.hpp:16
static T & get()
Returns the process-lifetime instance.
Definition Immortal.hpp:21