You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.8 KiB
128 lines
3.8 KiB
#include "gui_bridge.h" |
|
|
|
#include <QObject> |
|
#include <QMetaObject> |
|
#include <QByteArray> |
|
#include <QDebug> |
|
#include <cstring> |
|
|
|
extern "C" { |
|
#include "../../../lib/u_async.h" |
|
#include "../../../lib/mem.h" |
|
} |
|
|
|
/* ── Внутренний объект-приёмник в GUI-потоке ── */ |
|
|
|
class GuiBridgeReceiver : public QObject { |
|
Q_OBJECT |
|
public: |
|
void* ua = nullptr; |
|
|
|
GuiBridgeReceiver(QObject* parent = nullptr) : QObject(parent) {} |
|
|
|
Q_INVOKABLE void processPost(int eventType, QByteArray data); |
|
}; |
|
|
|
static GuiBridgeReceiver* g_receiver = nullptr; |
|
static gui_connect_result_fn g_connect_result_cb = nullptr; |
|
static gui_msg_received_fn g_msg_received_cb = nullptr; |
|
static struct UASYNC* g_ua = nullptr; |
|
|
|
/* ── GuiBridgeReceiver implementation ── */ |
|
|
|
void GuiBridgeReceiver::processPost(int eventType, QByteArray data) { |
|
const uint8_t* d = (const uint8_t*)data.constData(); |
|
int dlen = data.size(); |
|
|
|
switch (eventType) { |
|
case GUI_EVT_MSG_RECEIVED: |
|
if (dlen >= 2) { |
|
uint8_t chLen = d[0]; |
|
if (dlen >= 1 + chLen) { |
|
QString chId = QString::fromUtf8((const char*)d + 1, chLen); |
|
qDebug("gui_bridge: MSG_RECEIVED ch=%s", qPrintable(chId)); |
|
if (g_msg_received_cb) g_msg_received_cb((const char*)d + 1, chLen); |
|
} else { |
|
qWarning("gui_bridge: MSG_RECEIVED invalid data length %d", dlen); |
|
} |
|
} else { |
|
qWarning("gui_bridge: MSG_RECEIVED data too short %d", dlen); |
|
} |
|
break; |
|
case GUI_EVT_CONNECT_RESULT: |
|
if (dlen >= 12) { |
|
uint64_t nodeId; int result; |
|
memcpy(&nodeId, d, 8); memcpy(&result, d + 8, 4); |
|
qDebug("gui_bridge: CONNECT_RESULT node=0x%016llx result=%d", |
|
(unsigned long long)nodeId, result); |
|
if (g_connect_result_cb) g_connect_result_cb(nodeId, result); |
|
} else { |
|
qWarning("gui_bridge: CONNECT_RESULT data too short %d", dlen); |
|
} |
|
break; |
|
case GUI_EVT_NEW_PEER: |
|
if (dlen >= 8) { |
|
uint64_t nodeId; memcpy(&nodeId, d, 8); |
|
qDebug("gui_bridge: NEW_PEER node=0x%016llx", (unsigned long long)nodeId); |
|
} else { |
|
qWarning("gui_bridge: NEW_PEER data too short %d", dlen); |
|
} |
|
break; |
|
case GUI_EVT_CHANNEL_UPDATED: |
|
if (dlen >= 2) { |
|
uint8_t chLen = d[0]; |
|
if (dlen >= 1 + chLen) { |
|
QString chId = QString::fromUtf8((const char*)d + 1, chLen); |
|
qDebug("gui_bridge: CHANNEL_UPDATED ch=%s", qPrintable(chId)); |
|
} |
|
} else { |
|
qWarning("gui_bridge: CHANNEL_UPDATED data too short %d", dlen); |
|
} |
|
break; |
|
default: |
|
qWarning("gui_bridge: unknown event type %d", eventType); |
|
break; |
|
} |
|
} |
|
|
|
/* ── C API ── */ |
|
|
|
extern "C" { |
|
|
|
void gui_bridge_init(void) { |
|
g_receiver = new GuiBridgeReceiver(); |
|
g_receiver->ua = g_ua; |
|
} |
|
|
|
void gui_bridge_set_uasync(struct UASYNC* ua) { |
|
g_ua = ua; |
|
if (g_receiver) g_receiver->ua = ua; |
|
} |
|
|
|
void gui_bridge_post(int event_type, const uint8_t* data, int data_len) { |
|
if (!g_receiver) return; |
|
|
|
QByteArray d; |
|
if (data_len > 0) d = QByteArray((const char*)data, data_len); |
|
|
|
QMetaObject::invokeMethod(g_receiver, "processPost", |
|
Qt::QueuedConnection, |
|
Q_ARG(int, event_type), |
|
Q_ARG(QByteArray, d)); |
|
} |
|
|
|
void gui_bridge_post_uasync_fn(void (*fn)(void*), void* arg) { |
|
if (g_ua && fn) uasync_post(g_ua, fn, arg); |
|
} |
|
|
|
void gui_bridge_set_connect_result_cb(gui_connect_result_fn cb) { |
|
g_connect_result_cb = cb; |
|
} |
|
|
|
void gui_bridge_set_msg_received_cb(gui_msg_received_fn cb) { |
|
g_msg_received_cb = cb; |
|
} |
|
|
|
} /* extern "C" */ |
|
|
|
#include "gui_bridge_impl.moc"
|
|
|