loom
1/**
2* @file InterprocessCommunication.cpp
3* @author your name (you@domain.com)
4* @brief
5* @version 0.1
6* @date 2024-08-02
7*
8* @copyright Copyright (c) 2024
9*
10*/
11
12#include "simodo/messaging/InterprocessCommunication.h"13
14#ifdef CROSS_WIN15#include <boost/process/windows.hpp>16#endif17
18namespace simodo::messaging19{
20InterprocessCommunication::InterprocessCommunication(21std::string process_path,22std::vector<std::string> process_args)23: _process_path(process_path)24, _process_args(process_args)25{26}27
28InterprocessCommunication::~InterprocessCommunication()29{30close();31}32
33bool InterprocessCommunication::open(std::function<void(std::string &)> receiver)34{35if (_opened)36return true;37
38try {39_server = std::make_unique<bp::child>(40_process_path
41, _process_args42, bp::std_in < _os43, bp::std_out > _is44#ifdef CROSS_WIN45, bp::windows::hide46#endif47, bp::on_exit([&](auto...)48{49_is.close();50_os.close();51_opened = false;52if (_receiver) {53std::string s;54_receiver(s);55}56}57));58
59_opened = true;60}61catch(const std::exception& e) {62_last_error = e.what();63_server.reset();64}65
66if (!_opened)67return false;68
69_receiver = receiver;70
71if (_receiver)72_response_thread = std::make_unique<std::thread>(&InterprocessCommunication::response_listener, this);73
74return true;75}76
77void InterprocessCommunication::close()78{79if (!_opened)80return;81
82_opened = false;83_server.reset();84
85if (_response_thread)86_response_thread->join();87}88
89void InterprocessCommunication::send(const std::string & s)90{91if (_server->running() && _os.good()) {92_os << s << "\n";93_os.flush();94}95}96
97/**************************************************************************98* private
99**************************************************************************/
100
101void InterprocessCommunication::response_listener()102{103assert(_receiver);104
105while(_opened && _is.good()) {106std::string line;107
108if (std::getline(_is,line))109_receiver(line);110}111}112
113
114}
115