OXYGENHUB
◆ main openmsx / src / events / CliConnection.hh
3.4 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef CLICONNECTION_HH
2
#define CLICONNECTION_HH
3
4
#include "AdhocCliCommParser.hh"
5
#include "CliComm.hh"
6
#include "CliListener.hh"
7
#include "EventListener.hh"
8
#include "Socket.hh"
9
10
#include "Poller.hh"
11
#include "stl.hh"
12
13
#include <mutex>
14
#include <string>
15
#include <thread>
16
17
namespace openmsx {
18
19
class CommandController;
20
class EventDistributor;
21
22
class CliConnection : public CliListener, private EventListener
23
{
24
public:
25
	void setUpdateEnable(CliComm::UpdateType type, bool value) {
26
		updateEnabled[type] = value;
27
	}
28
	[[nodiscard]] bool getUpdateEnable(CliComm::UpdateType type) const {
29
		return updateEnabled[type];
30
	}
31
32
	/** Starts the helper thread.
33
	  * Called when this CliConnection is added to GlobalCliComm (and
34
	  * after it's allowed to respond to external commands).
35
	  * Subclasses should themself send the opening tag (startOutput()).
36
	  */
37
	void start();
38
39
protected:
40
	CliConnection(CommandController& commandController,
41
	              EventDistributor& eventDistributor);
42
	~CliConnection() override;
43
44
	virtual void output(std::string_view message) = 0;
45
46
	/** End this connection by sending the closing tag
47
	  * and then closing the stream.
48
	  * Subclasses should call this method at the start of their destructor.
49
	  */
50
	void end();
51
52
	/** Close the connection. After this method is called, calls to
53
	  * output() should be ignored.
54
	  */
55
	virtual void close() = 0;
56
57
	/** Send opening XML tag, should be called exactly once by a subclass
58
	  * shortly after opening a connection. Cannot be implemented in the
59
	  * base class because some subclasses (want to send data before this
60
	  * tag).
61
	  */
62
	void startOutput();
63
64
	AdhocCliCommParser parser;
65
	Poller poller;
66
67
private:
68
	virtual void run() = 0;
69
70
	void execute(const std::string& command);
71
72
	// CliListener
73
	void log(CliComm::LogLevel level, std::string_view message, float fraction) noexcept override;
74
	void update(CliComm::UpdateType type, std::string_view machine,
75
	            std::string_view name, std::string_view value) noexcept override;
76
77
	// EventListener
78
	bool signalEvent(const Event& event) override;
79
80
	CommandController& commandController;
81
	EventDistributor& eventDistributor;
82
83
	std::thread thread;
84
85
	array_with_enum_index<CliComm::UpdateType, bool> updateEnabled;
86
};
87
88
class StdioConnection final : public CliConnection
89
{
90
public:
91
	StdioConnection(CommandController& commandController,
92
	                EventDistributor& eventDistributor);
93
	~StdioConnection() override;
94
95
	void output(std::string_view message) override;
96
97
private:
98
	void close() override;
99
	void run() override;
100
};
101
102
#ifdef _WIN32
103
class PipeConnection final : public CliConnection
104
{
105
public:
106
	PipeConnection(CommandController& commandController,
107
	               EventDistributor& eventDistributor,
108
	               std::string_view name);
109
	~PipeConnection() override;
110
111
	void output(std::string_view message) override;
112
113
private:
114
	void close() override;
115
	void run() override;
116
117
	HANDLE pipeHandle;
118
	HANDLE shutdownEvent;
119
};
120
#endif
121
122
class SocketConnection final : public CliConnection
123
{
124
public:
125
	SocketConnection(CommandController& commandController,
126
	                 EventDistributor& eventDistributor,
127
	                 SOCKET sd);
128
	~SocketConnection() override;
129
130
	void output(std::string_view message) override;
131
132
	// Closed from the client side.
133
	[[nodiscard]] bool isClosed();
134
135
private:
136
	void close() override;
137
	void run() override;
138
	void closeSocket();
139
140
	std::mutex sdMutex;
141
	SOCKET sd;
142
	bool established = false;
143
};
144
145
} // namespace openmsx
146
147
#endif