implement running LAMMPS asynchonously in a separate thread
This commit is contained in:
@ -69,6 +69,8 @@ set(PROJECT_SOURCES
|
||||
lammpsgui.cpp
|
||||
lammpsgui.h
|
||||
lammpsgui.ui
|
||||
lammpsrunner.cpp
|
||||
lammpsrunner.h
|
||||
stdcapture.cpp
|
||||
${PLUGIN_LOADER_SRC}
|
||||
)
|
||||
|
||||
@ -7,7 +7,7 @@ LAMMPS-GUI TODO list:
|
||||
- add "Help" entry to menu bar. Should open a popup window with a one page description of how to use it. Use HTML or Markdown text.
|
||||
- add "View" entry to menu bar, where dialog windows may be enabled/disabled (e.g. Render)
|
||||
- add dialog when exiting asking if file should be saved when it is modified
|
||||
- add CTRL-q hotkey to log windows so you can exit the entire application
|
||||
- add CTRL-q hotkey to log windows so you can exit the entire application (add do you really want to? dialog to this)
|
||||
- add "render" dialog where a "write_dump image" can be triggered. dialog should offer options for size, zoom, rotation, colors(?)
|
||||
- add "syntax check" with enabled "-skiprun" flag.
|
||||
- add settings dialog where certain properties can be set through customizing the LAMMPS command line
|
||||
@ -19,7 +19,6 @@ LAMMPS-GUI TODO list:
|
||||
|
||||
# Long term ideas
|
||||
- support single stepping, i.e. process input line by line (need to detect continuation chars!) with highlighting active line(s)
|
||||
- run LAMMMPS instance in a separate thread, modify capture to regularly poll pipe and retrieve/append output while job is running
|
||||
- have command text input file in/above status bar where individual commands can be tested. have insert button to copy line into file at the current point
|
||||
- support text completion as done with lammps-shell
|
||||
- have context menu for known commands to offer retrieving help by dispatching URL to webbrowser (process index from sphinx for that purpose)
|
||||
|
||||
@ -12,18 +12,24 @@
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "lammpsgui.h"
|
||||
|
||||
#include "highlighter.h"
|
||||
#include "lammpsrunner.h"
|
||||
#include "stdcapture.h"
|
||||
#include "ui_lammpsgui.h"
|
||||
|
||||
//#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QFont>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QProgressBar>
|
||||
#include <QShortcut>
|
||||
#include <QStatusBar>
|
||||
#include <QTextStream>
|
||||
#include <QTimer>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
@ -33,7 +39,9 @@
|
||||
#endif
|
||||
|
||||
LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
|
||||
QMainWindow(parent), ui(new Ui::LammpsGui), lammps_handle(nullptr), plugin_handle(nullptr)
|
||||
QMainWindow(parent), ui(new Ui::LammpsGui), highlighter(nullptr), capturer(nullptr),
|
||||
status(nullptr), logwindow(nullptr), logupdater(nullptr), progress(nullptr),
|
||||
lammps_handle(nullptr), plugin_handle(nullptr), is_running(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setCentralWidget(ui->textEdit);
|
||||
@ -74,17 +82,21 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
|
||||
status = new QLabel("Ready.");
|
||||
status->setFixedWidth(300);
|
||||
ui->statusbar->addWidget(status);
|
||||
progress = new QProgressBar();
|
||||
progress->setRange(0, 1000);
|
||||
progress->setFixedWidth(500);
|
||||
ui->statusbar->addWidget(progress);
|
||||
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
liblammpsplugin_t *plugin = liblammpsplugin_load("liblammps.so");
|
||||
if (!plugin) plugin = liblammpsplugin_load("liblammps.dylib");
|
||||
if (!plugin) plugin = liblammpsplugin_load("liblammps.dll");
|
||||
bool do_exit = !plugin || (plugin && plugin->abiversion != LAMMPSPLUGIN_ABI_VERSION);
|
||||
if (!plugin) QMessageBox::critical(this, "Warning", "Cannot open LAMMPS shared library file");
|
||||
if (plugin && (plugin->abiversion != LAMMPSPLUGIN_ABI_VERSION))
|
||||
liblammpsplugin_t *lammps = liblammpsplugin_load("liblammps.so");
|
||||
if (!lammps) lammps = liblammpsplugin_load("liblammps.dylib");
|
||||
if (!lammps) lammps = liblammpsplugin_load("liblammps.dll");
|
||||
bool do_exit = !lammps || (lammps && lammps->abiversion != LAMMPSPLUGIN_ABI_VERSION);
|
||||
if (!lammps) QMessageBox::critical(this, "Warning", "Cannot open LAMMPS shared library file");
|
||||
if (lammps && (lammps->abiversion != LAMMPSPLUGIN_ABI_VERSION))
|
||||
QMessageBox::critical(this, "Warning",
|
||||
"ERROR: LAMMPS lib plugin ABI version does not match");
|
||||
plugin_handle = plugin;
|
||||
plugin_handle = lammps;
|
||||
if (do_exit) exit(1);
|
||||
#endif
|
||||
}
|
||||
@ -95,6 +107,7 @@ LammpsGui::~LammpsGui()
|
||||
delete highlighter;
|
||||
delete capturer;
|
||||
delete status;
|
||||
delete logwindow;
|
||||
}
|
||||
|
||||
void LammpsGui::new_document()
|
||||
@ -176,11 +189,11 @@ void LammpsGui::quit()
|
||||
{
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
if (lammps_handle) {
|
||||
liblammpsplugin_t *plugin = (liblammpsplugin_t *)plugin_handle;
|
||||
plugin->close(lammps_handle);
|
||||
plugin->mpi_finalize();
|
||||
plugin->kokkos_finalize();
|
||||
plugin->python_finalize();
|
||||
liblammpsplugin_t *lammps = (liblammpsplugin_t *)plugin_handle;
|
||||
lammps->close(lammps_handle);
|
||||
lammps->mpi_finalize();
|
||||
lammps->kokkos_finalize();
|
||||
lammps->python_finalize();
|
||||
}
|
||||
#else
|
||||
if (lammps_handle) {
|
||||
@ -224,6 +237,79 @@ void LammpsGui::redo()
|
||||
ui->textEdit->redo();
|
||||
}
|
||||
|
||||
void LammpsGui::logupdate()
|
||||
{
|
||||
double t_elapsed, t_remain, t_total;
|
||||
int completed = 1000;
|
||||
|
||||
if (is_running) {
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
liblammpsplugin_t *lammps = (liblammpsplugin_t *)plugin_handle;
|
||||
if (lammps->is_running(lammps_handle)) {
|
||||
t_elapsed = lammps->get_thermo(lammps_handle, "cpu");
|
||||
t_remain = lammps->get_thermo(lammps_handle, "cpuremain");
|
||||
t_total = t_elapsed + t_remain + 1.0e-10;
|
||||
completed = t_elapsed / t_total * 1000.0;
|
||||
}
|
||||
#else
|
||||
if (lammps_is_running(lammps_handle)) {
|
||||
t_elapsed = lammps_get_thermo(lammps_handle, "cpu");
|
||||
t_remain = lammps_get_thermo(lammps_handle, "cpuremain");
|
||||
t_total = t_elapsed + t_remain + 1.0e-10;
|
||||
completed = t_elapsed / t_total * 1000.0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
progress->setValue(completed);
|
||||
if (logwindow) {
|
||||
const auto text = capturer->GetChunk();
|
||||
if (text.size() > 0) {
|
||||
logwindow->insertPlainText(text.c_str());
|
||||
logwindow->moveCursor(QTextCursor::End);
|
||||
logwindow->textCursor().deleteChar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LammpsGui::run_done()
|
||||
{
|
||||
logupdater->stop();
|
||||
delete logupdater;
|
||||
logupdater = nullptr;
|
||||
progress->setValue(1000);
|
||||
|
||||
capturer->EndCapture();
|
||||
auto log = capturer->GetCapture();
|
||||
logwindow->insertPlainText(log.c_str());
|
||||
logwindow->moveCursor(QTextCursor::End);
|
||||
|
||||
bool success = true;
|
||||
constexpr int BUFLEN = 1024;
|
||||
char errorbuf[BUFLEN];
|
||||
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
liblammpsplugin_t *lammps = (liblammpsplugin_t *)plugin_handle;
|
||||
if (lammps->has_error(lammps_handle)) {
|
||||
lammps->get_last_error_message(lammps_handle, errorbuf, BUFLEN);
|
||||
success = false;
|
||||
}
|
||||
#else
|
||||
if (lammps_has_error(lammps_handle)) {
|
||||
lammps_get_last_error_message(lammps_handle, errorbuf, BUFLEN);
|
||||
success = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (success) {
|
||||
status->setText("Ready.");
|
||||
} else {
|
||||
status->setText("Failed.");
|
||||
QMessageBox::critical(this, "LAMMPS-GUI Error",
|
||||
QString("Error running LAMMPS:\n\n") + errorbuf);
|
||||
}
|
||||
is_running = false;
|
||||
}
|
||||
|
||||
void LammpsGui::run_buffer()
|
||||
{
|
||||
status->setText("Running LAMMPS. Please wait...");
|
||||
@ -232,51 +318,38 @@ void LammpsGui::run_buffer()
|
||||
if (!lammps_handle) return;
|
||||
clear();
|
||||
capturer->BeginCapture();
|
||||
std::string buffer = ui->textEdit->toPlainText().toStdString();
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
liblammpsplugin_t *plugin = (liblammpsplugin_t *)plugin_handle;
|
||||
plugin->commands_string(lammps_handle, buffer.c_str());
|
||||
#else
|
||||
lammps_commands_string(lammps_handle, buffer.c_str());
|
||||
#endif
|
||||
capturer->EndCapture();
|
||||
auto log = capturer->GetCapture();
|
||||
status->setText("Ready.");
|
||||
|
||||
auto box = new QPlainTextEdit();
|
||||
box->document()->setPlainText(log.c_str());
|
||||
box->setReadOnly(true);
|
||||
box->setWindowTitle("LAMMPS-GUI - Output from running LAMMPS on buffer - " + current_file);
|
||||
std::string buffer = ui->textEdit->toPlainText().toStdString();
|
||||
char *input = new char[buffer.size() + 1];
|
||||
memcpy(input, buffer.c_str(), buffer.size() + 1);
|
||||
|
||||
is_running = true;
|
||||
LammpsRunner *runner = new LammpsRunner(this);
|
||||
runner->setup_run(lammps_handle, input, plugin_handle);
|
||||
connect(runner, &LammpsRunner::resultReady, this, &LammpsGui::run_done);
|
||||
connect(runner, &LammpsRunner::finished, runner, &QObject::deleteLater);
|
||||
runner->start();
|
||||
|
||||
logwindow = new QPlainTextEdit();
|
||||
logwindow->setReadOnly(true);
|
||||
logwindow->setCenterOnScroll(true);
|
||||
logwindow->moveCursor(QTextCursor::End);
|
||||
logwindow->setWindowTitle("LAMMPS-GUI - Output from running LAMMPS on buffer - " +
|
||||
current_file);
|
||||
QFont text_font;
|
||||
text_font.setFamilies(QStringList({"Consolas", "Monospace", "Sans", "Courier"}));
|
||||
text_font.setFixedPitch(true);
|
||||
text_font.setStyleHint(QFont::TypeWriter);
|
||||
box->document()->setDefaultFont(text_font);
|
||||
box->setLineWrapMode(QPlainTextEdit::NoWrap);
|
||||
box->setMinimumSize(800, 600);
|
||||
QShortcut *shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), box);
|
||||
QObject::connect(shortcut, &QShortcut::activated, box, &QPlainTextEdit::close);
|
||||
box->show();
|
||||
logwindow->document()->setDefaultFont(text_font);
|
||||
logwindow->setLineWrapMode(QPlainTextEdit::NoWrap);
|
||||
logwindow->setMinimumSize(800, 600);
|
||||
QShortcut *shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), logwindow);
|
||||
QObject::connect(shortcut, &QShortcut::activated, logwindow, &QPlainTextEdit::close);
|
||||
logwindow->show();
|
||||
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
if (plugin->has_error(lammps_handle)) {
|
||||
constexpr int BUFLEN = 1024;
|
||||
char errorbuf[BUFLEN];
|
||||
plugin->get_last_error_message(lammps_handle, errorbuf, BUFLEN);
|
||||
|
||||
QMessageBox::critical(this, "LAMMPS-GUI Error",
|
||||
QString("Error running LAMMPS:\n\n") + errorbuf);
|
||||
}
|
||||
#else
|
||||
if (lammps_has_error(lammps_handle)) {
|
||||
constexpr int BUFLEN = 1024;
|
||||
char errorbuf[BUFLEN];
|
||||
lammps_get_last_error_message(lammps_handle, errorbuf, BUFLEN);
|
||||
|
||||
QMessageBox::critical(this, "LAMMPS-GUI Error",
|
||||
QString("Error running LAMMPS:\n\n") + errorbuf);
|
||||
}
|
||||
#endif
|
||||
logupdater = new QTimer(this);
|
||||
connect(logupdater, &QTimer::timeout, this, &LammpsGui::logupdate);
|
||||
logupdater->start(1000);
|
||||
}
|
||||
|
||||
void LammpsGui::clear()
|
||||
@ -293,23 +366,29 @@ void LammpsGui::clear()
|
||||
|
||||
void LammpsGui::about()
|
||||
{
|
||||
start_lammps();
|
||||
|
||||
std::string version = "This is LAMMPS-GUI version 0.1";
|
||||
capturer->BeginCapture();
|
||||
std::string info = "LAMMPS is currently running. LAMMPS config info not available.";
|
||||
|
||||
// LAMMPS is not re-entrant, so we can only query LAMMPS when it is not running
|
||||
if (!is_running) {
|
||||
start_lammps();
|
||||
capturer->BeginCapture();
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
((liblammpsplugin_t *)plugin_handle)->commands_string(lammps_handle, "info config");
|
||||
((liblammpsplugin_t *)plugin_handle)->commands_string(lammps_handle, "info config");
|
||||
#else
|
||||
lammps_commands_string(lammps_handle, "info config");
|
||||
lammps_commands_string(lammps_handle, "info config");
|
||||
#endif
|
||||
capturer->EndCapture();
|
||||
std::string info = capturer->GetCapture();
|
||||
auto start = info.find("LAMMPS version:");
|
||||
auto end = info.find("Info-Info-Info", start);
|
||||
capturer->EndCapture();
|
||||
info = capturer->GetCapture();
|
||||
auto start = info.find("LAMMPS version:");
|
||||
auto end = info.find("Info-Info-Info", start);
|
||||
info = std::string(info, start, end - start);
|
||||
}
|
||||
|
||||
QMessageBox msg;
|
||||
msg.setWindowTitle("About LAMMPS-GUI");
|
||||
msg.setText(version.c_str());
|
||||
msg.setInformativeText(std::string(info, start, end - start).c_str());
|
||||
msg.setInformativeText(info.c_str());
|
||||
msg.setIcon(QMessageBox::NoIcon);
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
QFont font;
|
||||
@ -328,14 +407,14 @@ void LammpsGui::start_lammps()
|
||||
int nargs = sizeof(args) / sizeof(char *);
|
||||
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
liblammpsplugin_t *plugin = (liblammpsplugin_t *)plugin_handle;
|
||||
liblammpsplugin_t *lammps = (liblammpsplugin_t *)plugin_handle;
|
||||
|
||||
// Create LAMMPS instance if not already present
|
||||
if (!lammps_handle) lammps_handle = plugin->open_no_mpi(nargs, args, nullptr);
|
||||
if (plugin->has_error(lammps_handle)) {
|
||||
if (!lammps_handle) lammps_handle = lammps->open_no_mpi(nargs, args, nullptr);
|
||||
if (lammps->has_error(lammps_handle)) {
|
||||
constexpr int BUFLEN = 1024;
|
||||
char errorbuf[BUFLEN];
|
||||
plugin->get_last_error_message(lammps_handle, errorbuf, BUFLEN);
|
||||
lammps->get_last_error_message(lammps_handle, errorbuf, BUFLEN);
|
||||
|
||||
QMessageBox::critical(this, "LAMMPS-GUI Error",
|
||||
QString("Error launching LAMMPS:\n\n") + errorbuf);
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QString>
|
||||
#include <QLabel>
|
||||
|
||||
// forward declarations
|
||||
|
||||
@ -26,6 +25,11 @@ class LammpsGui;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class QLabel;
|
||||
class QPlainTextEdit;
|
||||
class QProgressBar;
|
||||
class QTimer;
|
||||
|
||||
class Highlighter;
|
||||
class StdCapture;
|
||||
|
||||
@ -40,6 +44,7 @@ protected:
|
||||
void open_file(const QString &filename);
|
||||
void write_file(const QString &filename);
|
||||
void start_lammps();
|
||||
void run_done();
|
||||
|
||||
private slots:
|
||||
void new_document();
|
||||
@ -55,17 +60,22 @@ private slots:
|
||||
void clear();
|
||||
void run_buffer();
|
||||
void about();
|
||||
void logupdate();
|
||||
|
||||
private:
|
||||
Ui::LammpsGui *ui;
|
||||
Highlighter *highlighter;
|
||||
StdCapture *capturer;
|
||||
QLabel *status;
|
||||
QPlainTextEdit *logwindow;
|
||||
QTimer *logupdater;
|
||||
QProgressBar *progress;
|
||||
|
||||
QString current_file;
|
||||
QString current_dir;
|
||||
void *lammps_handle;
|
||||
void *plugin_handle;
|
||||
bool is_running;
|
||||
};
|
||||
|
||||
#endif // LAMMPSGUI_H
|
||||
|
||||
44
tools/lammps-gui/lammpsrunner.cpp
Normal file
44
tools/lammps-gui/lammpsrunner.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, Sandia National Laboratories
|
||||
LAMMPS development team: developers@lammps.org
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "lammpsrunner.h"
|
||||
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
#include "liblammpsplugin.h"
|
||||
#else
|
||||
#include "library.h"
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
LammpsRunner::LammpsRunner(QObject *parent) :
|
||||
QThread(parent), handle(nullptr), plugin(nullptr), input(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void LammpsRunner::run()
|
||||
{
|
||||
if (handle) {
|
||||
#if defined(LAMMPS_GUI_USE_PLUGIN)
|
||||
liblammpsplugin_t *lammps = (liblammpsplugin_t *)plugin;
|
||||
lammps->commands_string(handle, input);
|
||||
#else
|
||||
lammps_commands_string(handle, input);
|
||||
#endif
|
||||
}
|
||||
emit resultReady();
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// c-basic-offset: 4
|
||||
// End:
|
||||
48
tools/lammps-gui/lammpsrunner.h
Normal file
48
tools/lammps-gui/lammpsrunner.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, Sandia National Laboratories
|
||||
LAMMPS development team: developers@lammps.org
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LAMMPSRUNNER_H
|
||||
#define LAMMPSRUNNER_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
class LammpsRunner : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LammpsRunner(QObject *parent = nullptr);
|
||||
~LammpsRunner() = default;
|
||||
|
||||
// execute LAMMPS run in runner thread
|
||||
void run() override;
|
||||
|
||||
// transfer info to worker thread
|
||||
void setup_run(void *_handle, const char *_input, void *_plugin = nullptr)
|
||||
{
|
||||
handle = _handle;
|
||||
plugin = _plugin;
|
||||
input = _input;
|
||||
}
|
||||
|
||||
signals:
|
||||
void resultReady();
|
||||
|
||||
private:
|
||||
void *handle, *plugin;
|
||||
const char *input;
|
||||
};
|
||||
|
||||
#endif
|
||||
// Local Variables:
|
||||
// c-basic-offset: 4
|
||||
// End:
|
||||
@ -24,7 +24,6 @@
|
||||
#define dup2 _dup2
|
||||
#define fileno _fileno
|
||||
#define close _close
|
||||
#define pipe _pipe
|
||||
#define read _read
|
||||
#define eof _eof
|
||||
#else
|
||||
@ -44,9 +43,9 @@ StdCapture::StdCapture() : m_oldStdOut(0), m_capturing(false)
|
||||
m_pipe[READ] = 0;
|
||||
m_pipe[WRITE] = 0;
|
||||
#if _WIN32
|
||||
if (pipe(m_pipe, 65536, O_BINARY) == -1) return;
|
||||
if (_pipe(m_pipe, 65536, O_BINARY) == -1) return;
|
||||
#else
|
||||
if (pipe(m_pipe) == -1) return;
|
||||
if (pipe2(m_pipe, O_NONBLOCK) == -1) return;
|
||||
#endif
|
||||
m_oldStdOut = dup(fileno(stdout));
|
||||
if (m_oldStdOut == -1) return;
|
||||
@ -75,8 +74,6 @@ bool StdCapture::EndCapture()
|
||||
dup2(m_oldStdOut, fileno(stdout));
|
||||
m_captured.clear();
|
||||
|
||||
constexpr int bufSize = 1025;
|
||||
char buf[bufSize];
|
||||
int bytesRead;
|
||||
bool fd_blocked;
|
||||
|
||||
@ -104,7 +101,26 @@ bool StdCapture::EndCapture()
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string StdCapture::GetCapture() const
|
||||
std::string StdCapture::GetChunk()
|
||||
{
|
||||
if (!m_capturing) return std::string();
|
||||
int bytesRead = 0;
|
||||
buf[0] = '\0';
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!eof(m_pipe[READ])) {
|
||||
bytesRead = read(m_pipe[READ], buf, bufSize - 1);
|
||||
}
|
||||
#else
|
||||
bytesRead = read(m_pipe[READ], buf, bufSize - 1);
|
||||
#endif
|
||||
if (bytesRead > 0) {
|
||||
buf[bytesRead] = '\0';
|
||||
}
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
std::string StdCapture::GetCapture()
|
||||
{
|
||||
std::string::size_type idx = m_captured.find_last_not_of("\r\n");
|
||||
if (idx == std::string::npos) {
|
||||
|
||||
@ -23,7 +23,8 @@ public:
|
||||
|
||||
void BeginCapture();
|
||||
bool EndCapture();
|
||||
std::string GetCapture() const;
|
||||
std::string GetCapture();
|
||||
std::string GetChunk();
|
||||
|
||||
private:
|
||||
enum PIPES { READ, WRITE };
|
||||
@ -32,6 +33,9 @@ private:
|
||||
bool m_capturing;
|
||||
bool m_init;
|
||||
std::string m_captured;
|
||||
|
||||
static constexpr int bufSize = 1025;
|
||||
char buf[bufSize];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user