11#ifndef BML_SCRIPTING_SCRIPT_EXCEPTION_HELPER_H
22#define BML_SCRIPTING_SCRIPT_EXCEPTION_HELPER_H
33
4+ #include < cstdlib>
5+ #include < cstring>
46#include < cstdio>
7+ #include < string_view>
58
69#include < angelscript.h>
710
11+ #include " bml_console.h"
812#include " bml_logging.h"
913#include " bml_topics.h"
1014#include " ModuleScope.h"
1115#include " ScriptInstance.h"
1216
1317namespace BML ::Scripting {
1418
19+ inline void PublishConsoleOutputMessage (BML_Mod owner, std::string_view message, uint32_t flags) {
20+ if (!g_Services || !g_Services->ImcBus || !g_Services->ImcBus ->PublishBuffer || !owner || message.empty ()) {
21+ return ;
22+ }
23+
24+ BML_TopicId topicId = BML_TOPIC_ID_INVALID ;
25+ if (g_Services->ImcBus ->GetTopicId (
26+ g_Services->ImcBus ->Context ,
27+ BML_TOPIC_CONSOLE_OUTPUT ,
28+ &topicId) != BML_RESULT_OK ) {
29+ return ;
30+ }
31+
32+ const size_t textSize = message.size () + 1 ;
33+ const size_t totalSize = sizeof (BML_ConsoleOutputEvent) + textSize;
34+ auto *storage = static_cast <char *>(std::malloc (totalSize));
35+ if (!storage) {
36+ return ;
37+ }
38+
39+ auto *event = reinterpret_cast <BML_ConsoleOutputEvent *>(storage);
40+ *event = BML_CONSOLE_OUTPUT_EVENT_INIT ;
41+ event->message_utf8 = storage + sizeof (BML_ConsoleOutputEvent);
42+ event->flags = flags;
43+
44+ std::memcpy (const_cast <char *>(event->message_utf8 ), message.data (), message.size ());
45+ const_cast <char *>(event->message_utf8 )[message.size ()] = ' \0 ' ;
46+
47+ BML_ImcBuffer buffer = BML_IMC_BUFFER_INIT ;
48+ buffer.data = event;
49+ buffer.size = totalSize;
50+ buffer.cleanup = [](const void *, size_t , void *userData) {
51+ std::free (userData);
52+ };
53+ buffer.cleanup_user_data = storage;
54+ (void ) g_Services->ImcBus ->PublishBuffer (owner, topicId, &buffer);
55+ }
56+
1557// Log an AngelScript exception with full context (function, file, line).
1658// Must be called before ReleaseContext because the context holds exception info.
1759inline void LogScriptException (asIScriptContext *ctx, const ScriptInstance &inst) {
@@ -36,24 +78,13 @@ inline void LogScriptException(asIScriptContext *ctx, const ScriptInstance &inst
3678 exception_str);
3779
3880 // Also forward to console output
39- if (g_Services->ImcBus && g_Services->ImcBus ->Publish ) {
81+ if (g_Services->ImcBus && g_Services->ImcBus ->PublishBuffer ) {
4082 char buf[512 ];
4183 int n = std::snprintf (buf, sizeof (buf),
4284 " \x1b [31m[%s] %s (%s:%d): %s\x1b [0m" ,
4385 inst.mod_id .c_str (), func_decl, section, line, exception_str);
4486 if (n > 0 && static_cast <size_t >(n) < sizeof (buf)) {
45- BML_TopicId topic_id = BML_TOPIC_ID_INVALID ;
46- if (g_Services->ImcBus ->GetTopicId (
47- g_Services->ImcBus ->Context ,
48- BML_TOPIC_CONSOLE_OUTPUT ,
49- &topic_id) == BML_RESULT_OK ) {
50- struct {
51- size_t struct_size;
52- const char *msg;
53- uint32_t flags;
54- } event{sizeof (event), buf, 0 };
55- g_Services->ImcBus ->Publish (inst.mod_handle , topic_id, &event, sizeof (event));
56- }
87+ PublishConsoleOutputMessage (inst.mod_handle , std::string_view (buf, static_cast <size_t >(n)), 0 );
5788 }
5889 }
5990}
0 commit comments