forked from quickshell/quickshell
refactor: move socket and datastream types to Io module
This commit is contained in:
parent
f45d298b66
commit
14e1d2d162
12 changed files with 26 additions and 13 deletions
143
src/io/socket.hpp
Normal file
143
src/io/socket.hpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
#pragma once
|
||||
|
||||
#include <qlocalserver.h>
|
||||
#include <qlocalsocket.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmlcomponent.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qtclasshelpermacros.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
#include "datastream.hpp"
|
||||
#include "../core/reload.hpp"
|
||||
|
||||
///! Unix socket listener.
|
||||
class Socket: public DataStream {
|
||||
Q_OBJECT;
|
||||
/// Returns if the socket is currently connected.
|
||||
///
|
||||
/// Writing to this property will set the target connection state and will not
|
||||
/// update the property immediately. Setting the property to false will begin disconnecting
|
||||
/// the socket, and setting it to true will begin connecting the socket if path is not empty.
|
||||
Q_PROPERTY(bool connected READ isConnected WRITE setConnected NOTIFY connectionStateChanged);
|
||||
/// The path to connect this socket to when `connected` is set to true.
|
||||
///
|
||||
/// Changing this property will have no effect while the connection is active.
|
||||
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged);
|
||||
QML_ELEMENT;
|
||||
|
||||
public:
|
||||
explicit Socket(QObject* parent = nullptr): DataStream(parent) {}
|
||||
|
||||
/// Write data to the socket. Does nothing if not connected.
|
||||
Q_INVOKABLE void write(const QString& data);
|
||||
|
||||
// takes ownership
|
||||
void setSocket(QLocalSocket* socket);
|
||||
|
||||
[[nodiscard]] bool isConnected() const;
|
||||
void setConnected(bool connected);
|
||||
|
||||
[[nodiscard]] QString path() const;
|
||||
void setPath(QString path);
|
||||
|
||||
signals:
|
||||
/// This signal is sent whenever a socket error is encountered.
|
||||
void error(QLocalSocket::LocalSocketError error);
|
||||
|
||||
void connectionStateChanged();
|
||||
void pathChanged();
|
||||
|
||||
protected:
|
||||
[[nodiscard]] QIODevice* ioDevice() const override;
|
||||
|
||||
private slots:
|
||||
void onSocketConnected();
|
||||
void onSocketDisconnected();
|
||||
|
||||
private:
|
||||
void connectPathSocket();
|
||||
|
||||
QLocalSocket* socket = nullptr;
|
||||
bool connected = false;
|
||||
bool disconnecting = false;
|
||||
bool targetConnected = false;
|
||||
QString mPath;
|
||||
};
|
||||
|
||||
///! Unix socket server.
|
||||
/// #### Example
|
||||
/// ```qml
|
||||
/// SocketServer {
|
||||
/// active: true
|
||||
/// path: "/path/too/socket.sock"
|
||||
/// handler: Socket {
|
||||
/// onConnectedChanged: {
|
||||
/// console.log(connected ? "new connection!" : "connection dropped!")
|
||||
/// }
|
||||
/// parser: SplitParser {
|
||||
/// onRead: message => console.log(`read message from socket: ${message}`)
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
class SocketServer
|
||||
: public QObject
|
||||
, public PostReloadHook {
|
||||
Q_OBJECT;
|
||||
/// If the socket server is currently active. Defaults to false.
|
||||
///
|
||||
/// Setting this to false will destory all active connections and delete
|
||||
/// the socket file on disk.
|
||||
///
|
||||
/// If path is empty setting this property will have no effect.
|
||||
Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeStatusChanged);
|
||||
/// The path to create the socket server at.
|
||||
///
|
||||
/// Setting this property while the server is active will have no effect.
|
||||
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged);
|
||||
/// Connection handler component. Must creeate a `Socket`.
|
||||
///
|
||||
/// The created socket should not set `connected` or `path` or the incoming
|
||||
/// socket connection will be dropped (they will be set by the socket server.)
|
||||
/// Setting `connected` to false on the created socket after connection will
|
||||
/// close and delete it.
|
||||
Q_PROPERTY(QQmlComponent* handler READ handler WRITE setHandler NOTIFY handlerChanged);
|
||||
QML_ELEMENT;
|
||||
|
||||
public:
|
||||
explicit SocketServer(QObject* parent = nullptr): QObject(parent) {}
|
||||
~SocketServer() override;
|
||||
Q_DISABLE_COPY_MOVE(SocketServer);
|
||||
|
||||
void onPostReload() override;
|
||||
|
||||
[[nodiscard]] bool isActive() const;
|
||||
void setActive(bool active);
|
||||
|
||||
[[nodiscard]] QString path() const;
|
||||
void setPath(QString path);
|
||||
|
||||
[[nodiscard]] QQmlComponent* handler() const;
|
||||
void setHandler(QQmlComponent* handler);
|
||||
|
||||
signals:
|
||||
void activeStatusChanged();
|
||||
void pathChanged();
|
||||
void handlerChanged();
|
||||
|
||||
private slots:
|
||||
void onNewConnection();
|
||||
|
||||
private:
|
||||
bool isActivatable();
|
||||
void enableServer();
|
||||
void disableServer();
|
||||
|
||||
QLocalServer* server = nullptr;
|
||||
QQmlComponent* mHandler = nullptr;
|
||||
QList<Socket*> mSockets;
|
||||
bool activeTarget = false;
|
||||
bool postReload = false;
|
||||
QString mPath;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue