mirror of
https://github.com/NohamR/RMHook.git
synced 2026-04-08 07:59:58 +00:00
Add MessageBroker for QML and native communication
Introduces MessageBroker to enable communication between the dylib and QML via signals. Updates CMakeLists.txt to include Qml components and conditionally add MessageBroker sources in qmlrebuild mode. reMarkable.m is updated to register the QML type, set up native callbacks, and demonstrate broadcasting signals.
This commit is contained in:
63
src/utils/MessageBroker.h
Normal file
63
src/utils/MessageBroker.h
Normal file
@@ -0,0 +1,63 @@
|
||||
// Credits: asivery/rm-xovi-extensions
|
||||
// (https://github.com/asivery/rm-xovi-extensions/blob/master/xovi-message-broker/src/XoviMessageBroker.h)
|
||||
// Simplified for RMHook dylib <-> QML communication
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
#include <QtQml/QQmlEngine>
|
||||
|
||||
// Forward declaration
|
||||
class MessageBroker;
|
||||
|
||||
// Native callback type for C++ listeners
|
||||
typedef void (*NativeSignalCallback)(const char *signal, const char *value);
|
||||
|
||||
namespace messagebroker {
|
||||
void addBroadcastListener(MessageBroker *ref);
|
||||
void removeBroadcastListener(MessageBroker *ref);
|
||||
void broadcast(const char *signal, const char *value);
|
||||
void registerQmlType();
|
||||
|
||||
// Register a native C++ callback to receive all signals
|
||||
void setNativeCallback(NativeSignalCallback callback);
|
||||
}
|
||||
|
||||
class MessageBroker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QStringList listeningFor READ getListeningFor WRITE setListeningFor)
|
||||
|
||||
public:
|
||||
explicit MessageBroker(QObject *parent = nullptr) : QObject(parent) {
|
||||
messagebroker::addBroadcastListener(this);
|
||||
}
|
||||
|
||||
~MessageBroker() {
|
||||
messagebroker::removeBroadcastListener(this);
|
||||
}
|
||||
|
||||
// Send a signal from QML to all listeners (including C++ side)
|
||||
Q_INVOKABLE void sendSignal(const QString &signal, const QString &message) {
|
||||
QByteArray signalUtf8 = signal.toUtf8();
|
||||
QByteArray messageUtf8 = message.toUtf8();
|
||||
messagebroker::broadcast(signalUtf8.constData(), messageUtf8.constData());
|
||||
}
|
||||
|
||||
void setListeningFor(const QStringList &l) {
|
||||
_listeningFor = l;
|
||||
}
|
||||
|
||||
const QStringList& getListeningFor() const {
|
||||
return _listeningFor;
|
||||
}
|
||||
|
||||
signals:
|
||||
void signalReceived(const QString &signal, const QString &message);
|
||||
|
||||
private:
|
||||
QStringList _listeningFor;
|
||||
};
|
||||
58
src/utils/MessageBroker.mm
Normal file
58
src/utils/MessageBroker.mm
Normal file
@@ -0,0 +1,58 @@
|
||||
// Credits: asivery/rm-xovi-extensions
|
||||
// (https://github.com/asivery/rm-xovi-extensions/blob/master/xovi-message-broker/src/XoviMessageBroker.h)
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include "MessageBroker.h"
|
||||
#include "Logger.h"
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
static std::vector<MessageBroker *> brokers;
|
||||
static NativeSignalCallback nativeCallback = nullptr;
|
||||
|
||||
void messagebroker::setNativeCallback(NativeSignalCallback callback) {
|
||||
nativeCallback = callback;
|
||||
NSLogger(@"[MessageBroker] Native callback registered");
|
||||
}
|
||||
|
||||
void messagebroker::addBroadcastListener(MessageBroker *ref) {
|
||||
// Cannot have more than one.
|
||||
if(std::find(brokers.begin(), brokers.end(), ref) == brokers.end()) {
|
||||
brokers.push_back(ref);
|
||||
NSLogger(@"[MessageBroker] Added broadcast listener, total: %zu", brokers.size());
|
||||
}
|
||||
}
|
||||
|
||||
void messagebroker::removeBroadcastListener(MessageBroker *ref) {
|
||||
std::vector<MessageBroker *>::iterator iter;
|
||||
if((iter = std::find(brokers.begin(), brokers.end(), ref)) != brokers.end()) {
|
||||
brokers.erase(iter);
|
||||
NSLogger(@"[MessageBroker] Removed broadcast listener, remaining: %zu", brokers.size());
|
||||
}
|
||||
}
|
||||
|
||||
void messagebroker::broadcast(const char *signal, const char *value) {
|
||||
QString qSignal(signal), qValue(value);
|
||||
NSLogger(@"[MessageBroker] Broadcasting signal '%s' with value '%s'", signal, value);
|
||||
|
||||
// Call native C++ callback if registered
|
||||
if (nativeCallback) {
|
||||
nativeCallback(signal, value);
|
||||
}
|
||||
|
||||
// Notify QML listeners
|
||||
for(auto &ref : brokers) {
|
||||
if(ref->getListeningFor().contains(qSignal)) {
|
||||
emit ref->signalReceived(qSignal, qValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void messagebroker::registerQmlType() {
|
||||
qmlRegisterType<MessageBroker>("net.noham.MessageBroker", 1, 0, "MessageBroker");
|
||||
NSLogger(@"[MessageBroker] Registered QML type net.noham.MessageBroker");
|
||||
}
|
||||
|
||||
// Include MOC output for MessageBroker class (generated by Qt's Meta-Object Compiler)
|
||||
#include "moc_MessageBroker.cpp"
|
||||
Reference in New Issue
Block a user