6#include <simplesquirrel/simplesquirrel.hpp>
22SQPRINTFUNCTION g_prevPrint =
nullptr;
23SQPRINTFUNCTION g_prevError =
nullptr;
27 g_prevPrint(
v,
"%s", text ? text :
"");
29 std::fputs(text ? text :
"", stdout);
35 g_prevError(
v,
"%s", text ? text :
"");
37 std::fputs(text ? text :
"", stderr);
47 vsnprintf(buf,
sizeof(buf),
s ?
s :
"", args);
57 vsnprintf(buf,
sizeof(buf),
s ?
s :
"", args);
64 switch (sq_gettype(
vm,
idx)) {
65 case OT_NULL:
return "null";
66 case OT_INTEGER:
return "integer";
67 case OT_FLOAT:
return "float";
68 case OT_BOOL:
return "bool";
69 case OT_STRING:
return "string";
70 case OT_TABLE:
return "table";
71 case OT_ARRAY:
return "array";
72 case OT_CLOSURE:
return "closure";
73 case OT_NATIVECLOSURE:
return "native";
74 case OT_USERDATA:
return "userdata";
75 case OT_CLASS:
return "class";
76 case OT_INSTANCE:
return "instance";
77 case OT_THREAD:
return "thread";
78 case OT_GENERATOR:
return "generator";
79 case OT_WEAKREF:
return "weakref";
80 default:
return "other";
85 switch (sq_gettype(
vm,
idx)) {
86 case OT_NULL:
return "null";
90 return b ?
"true" :
"false";
94 sq_getinteger(
vm,
idx, &
v);
95 return std::to_string(
static_cast<long long>(
v));
100 std::ostringstream oss;
101 oss << static_cast<double>(
v);
105 const SQChar*
s =
nullptr;
106 sq_getstring(
vm,
idx, &
s);
107 return std::string(
"\"") + (
s ?
s :
"") +
"\"";
109 case OT_TABLE:
return "<table>";
110 case OT_ARRAY:
return "<array>";
111 case OT_CLOSURE:
return "<closure>";
112 case OT_NATIVECLOSURE:
return "<native>";
113 case OT_USERDATA:
return "<userdata>";
114 case OT_INSTANCE:
return "<instance>";
115 case OT_CLASS:
return "<class>";
116 case OT_THREAD:
return "<thread>";
117 default:
return "<" + typeName(
vm,
idx) +
">";
128std::string ConsolePanel::nowStamp() {
129 using clock = std::chrono::system_clock;
130 const auto t = clock::to_time_t(clock::now());
133 localtime_s(&tm, &t);
135 localtime_r(&t, &tm);
138 std::strftime(buf,
sizeof(buf),
"%H:%M:%S", &tm);
143 std::lock_guard<std::mutex> lock(mu_);
148 std::lock_guard<std::mutex> lock(mu_);
155 std::lock_guard<std::mutex> lock(mu_);
158 line.level = std::move(level);
159 line.text = std::move(text);
160 log_.push_back(std::move(
line));
161 while (log_.size() > maxEntries_) log_.pop_front();
171 std::lock_guard<std::mutex> lock(mu_);
176 std::lock_guard<std::mutex> lock(mu_);
177 maxEntries_ =
n == 0 ? 1 :
n;
178 while (log_.size() > maxEntries_) log_.pop_front();
182 std::lock_guard<std::mutex> lock(mu_);
183 std::vector<ConsoleLine> out;
184 if (log_.empty() || max == 0)
return out;
185 const size_t start = log_.size() > max ? log_.size() - max : 0;
186 out.assign(log_.begin() +
static_cast<std::ptrdiff_t
>(start), log_.end());
192 std::ostringstream oss;
193 for (
const auto& l : lines) {
194 oss <<
'[' << l.timestamp <<
"] " << l.level <<
" | " << l.text <<
'\n';
204 if (!g_prevPrint) g_prevPrint = sq_getprintfunc(
vm);
205 if (!g_prevError) g_prevError = sq_geterrorfunc(
vm);
206 sq_setprintfunc(
vm, capturePrint, captureError);
207 addLog(
"info",
"console attached to VM");
212 sq_setprintfunc(vm_, g_prevPrint, g_prevError);
214 addLog(
"info",
"console detached from VM");
218 if (expression.empty())
return "error: empty expression";
220 if (!
vm)
return "error: no VM attached";
221 addLog(
"cmd", expression);
223 const SQInteger top = sq_gettop(
vm);
225 const std::string source =
"return (" + expression +
");";
226 if (SQ_FAILED(sq_compilebuffer(
vm, source.c_str(),
static_cast<SQInteger
>(source.size()),
227 _SC(
"console_repl.nut"), SQTrue))) {
230 const std::string err =
"error: " +
231 (ctx.
empty() ? std::string(
"compile failed")
236 sq_pushroottable(
vm);
237 if (SQ_FAILED(sq_call(
vm, 1, SQTrue, SQTrue))) {
240 const std::string err =
"error: " +
241 (ctx.
empty() ? std::string(
"runtime failed")
246 std::string result = formatValue(
vm, -1);
257 if (g_imguiDrawer) g_imguiDrawer(*
this);
struct SQVM * HSQUIRRELVM
SettlementPipeline::Stage fn
In-engine runtime console / log ring buffer for DevTools.
std::vector< ConsoleLine > recent(size_t max=128) const
static void setImGuiDrawer(ImGuiDrawer fn)
void addWarn(std::string text)
void addLog(std::string level, std::string text)
Append a leveled log line (thread-safe).
void(*)(ConsolePanel &panel) ImGuiDrawer
static ConsolePanel & instance()
std::string eval(const std::string &expression)
Evaluate a Squirrel expression against the root table and return a formatted result (or error message...
void addError(std::string text)
void setMaxEntries(size_t n)
void addInfo(std::string text)
void attach(HSQUIRRELVM vm)
Attach to a Squirrel VM: capture print/script errors into the log.
std::string format(size_t max=128) const
void drawImGui()
Optional ImGui draw hook. Default no-op: console UI is registered by the host (see setImGuiDrawer) so...
ScriptErrorContext captureCompileError(HSQUIRRELVM vm)
Captures the last compilation error recorded by the VM.
std::string formatScriptError(const ScriptErrorContext &ctx)
Formats a context into a human-readable multi-line report.
ScriptErrorContext takeLastScriptError(HSQUIRRELVM vm)
Consumes and clears the last recorded error for a VM.
static T & get()
Returns the process-lifetime instance.
Structured snapshot of a script error: message, throw site and stack.
bool empty() const noexcept
True when no error payload was captured.