UCILoader 1.1.2
Small C++ library that allows user to connect to a chess engines via UCI protocol.
Loading...
Searching...
No Matches
ProcessWrapper.h
1#pragma once
2
3#include "AbstractPipe.h"
4
5#include <thread>
6#include <memory>
7#include <cassert>
8#include <cstring>
9#include <functional>
10
11namespace UCILoader {
21 class CanNotOpenProcessException : std::exception {
22
23 std::string reason;
24 public:
25
31 CanNotOpenProcessException(const std::string& reason) : reason(reason) {};
32
38 const char* what() const noexcept override {
39 return reason.c_str();
40 }
41 };
42
89
90 std::unique_ptr<std::thread> listener = nullptr;
91 bool healthCheckFailed = false;
92
93 protected:
105 virtual std::shared_ptr<AbstractPipeReader> getReader() = 0;
106
107 public:
108
112 virtual ~ProcessWrapper() = default;
113
125 virtual std::shared_ptr<AbstractPipeWriter> getWriter() = 0;
126
134 virtual void kill() = 0;
145 virtual bool isAlive() const = 0;
158 virtual bool healthCheck() {
159 if (!healthCheckFailed && !isAlive()) {
160 kill();
161 healthCheckFailed = true;
162 }
163 return !healthCheckFailed;
164 }
165
200 void listen(std::function<void(std::string)> lineReceiver, std::function<void()> onCrash = [](){}) {
201 assert(listener == nullptr);
202
203 PipeScanner* scanner = new PipeScanner(std::move(getReader()));
204
205 listener = std::make_unique<std::thread>(
206 [scanner, lineReceiver, onCrash]() {
207 while (true) {
208 try {
209 lineReceiver(scanner->getLine());
210 }
211 catch (PipeClosedException) {
212 onCrash();
213 break;
214 }
215 }
216
217 delete scanner;
218 }
219 );
220 listener->detach(); // Listener will stop on its own when engine kills itself
221 };
222 };
223
254 ProcessWrapper* openProcess(const std::vector<std::string>& args, const std::string& workingDirectory);
255}
256
Exception thrown when a process cannot be opened or started.
Definition: ProcessWrapper.h:21
const char * what() const noexcept override
Get the exception message explaining the failure.
Definition: ProcessWrapper.h:38
CanNotOpenProcessException(const std::string &reason)
Constructor for the exception.
Definition: ProcessWrapper.h:31
Blocking line-oriented reader built on top of AbstractPipeReader.
Definition: AbstractPipe.h:202
std::string getLine()
Read the next complete line from the pipe.
Definition: AbstractPipe.cpp:36
Cross-platform wrapper for managing a chess engine process.
Definition: ProcessWrapper.h:88
void listen(std::function< void(std::string)> lineReceiver, std::function< void()> onCrash=[](){})
Start a background listening thread for reading process output lines.
Definition: ProcessWrapper.h:200
virtual void kill()=0
Immediately terminate the underlying process.
virtual std::shared_ptr< AbstractPipeReader > getReader()=0
Get the pipe reader for the process's standard output.
virtual std::shared_ptr< AbstractPipeWriter > getWriter()=0
Get the pipe writer for the process's standard input.
virtual bool isAlive() const =0
Check if the process is alive using OS calls.
virtual ~ProcessWrapper()=default
Virtual destructor that ensures listening thread is properly joined.
virtual bool healthCheck()
Perform a safe health check of the process.
Definition: ProcessWrapper.h:158