GCodePostProcessor - use C files instead of C++ streams, C files are faster.
Also fixed a regression - crashes on undefined cancellation callback.
This commit is contained in:
parent
51df3cd163
commit
e30ff22b8a
1 changed files with 28 additions and 20 deletions
|
@ -347,17 +347,25 @@ void GCodeProcessor::TimeProcessor::reset()
|
||||||
machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].enabled = true;
|
machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FilePtr {
|
||||||
|
FilePtr(FILE *f) : f(f) {}
|
||||||
|
~FilePtr() { this->close(); }
|
||||||
|
void close() { if (f) ::fclose(f); }
|
||||||
|
FILE* f = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, std::vector<MoveVertex>& moves)
|
void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, std::vector<MoveVertex>& moves)
|
||||||
{
|
{
|
||||||
boost::nowide::ifstream in(filename);
|
FilePtr in{ boost::nowide::fopen(filename.c_str(), "rb") };
|
||||||
if (!in.good())
|
if (in.f == nullptr)
|
||||||
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for reading.\n"));
|
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for reading.\n"));
|
||||||
|
|
||||||
// temporary file to contain modified gcode
|
// temporary file to contain modified gcode
|
||||||
std::string out_path = filename + ".postprocess";
|
std::string out_path = filename + ".postprocess";
|
||||||
FILE* out = boost::nowide::fopen(out_path.c_str(), "wb");
|
FilePtr out{ boost::nowide::fopen(out_path.c_str(), "wb") };
|
||||||
if (out == nullptr)
|
if (out.f == nullptr) {
|
||||||
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for writing.\n"));
|
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for writing.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
auto time_in_minutes = [](float time_in_seconds) {
|
auto time_in_minutes = [](float time_in_seconds) {
|
||||||
assert(time_in_seconds >= 0.f);
|
assert(time_in_seconds >= 0.f);
|
||||||
|
@ -559,11 +567,10 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper function to write to disk
|
// helper function to write to disk
|
||||||
auto write_string = [&](const std::string& str) {
|
auto write_string = [&export_line, &out, &out_path](const std::string& str) {
|
||||||
fwrite((const void*)export_line.c_str(), 1, export_line.length(), out);
|
fwrite((const void*)export_line.c_str(), 1, export_line.length(), out.f);
|
||||||
if (ferror(out)) {
|
if (ferror(out.f)) {
|
||||||
in.close();
|
out.close();
|
||||||
fclose(out);
|
|
||||||
boost::nowide::remove(out_path.c_str());
|
boost::nowide::remove(out_path.c_str());
|
||||||
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nIs the disk full?\n"));
|
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nIs the disk full?\n"));
|
||||||
}
|
}
|
||||||
|
@ -575,25 +582,23 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st
|
||||||
|
|
||||||
{
|
{
|
||||||
// Read the input stream 64kB at a time, extract lines and process them.
|
// Read the input stream 64kB at a time, extract lines and process them.
|
||||||
in.sync_with_stdio(false);
|
|
||||||
std::vector<char> buffer(65536 * 10, 0);
|
std::vector<char> buffer(65536 * 10, 0);
|
||||||
// Line buffer.
|
// Line buffer.
|
||||||
assert(gcode_line.empty());
|
assert(gcode_line.empty());
|
||||||
while (! in.eof()) {
|
for (;;) {
|
||||||
in.read(buffer.data(), buffer.size());
|
size_t cnt_read = ::fread(buffer.data(), 1, buffer.size(), in.f);
|
||||||
if (! in.eof() && ! in.good()) {
|
if (::ferror(in.f))
|
||||||
fclose(out);
|
|
||||||
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nError while reading from file.\n"));
|
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nError while reading from file.\n"));
|
||||||
}
|
bool eof = cnt_read == 0;
|
||||||
auto it = buffer.begin();
|
auto it = buffer.begin();
|
||||||
auto it_bufend = buffer.begin() + in.gcount();
|
auto it_bufend = buffer.begin() + cnt_read;
|
||||||
while (it != it_bufend) {
|
while (it != it_bufend || (eof && ! gcode_line.empty())) {
|
||||||
// Find end of line.
|
// Find end of line.
|
||||||
bool eol = false;
|
bool eol = false;
|
||||||
auto it_end = it;
|
auto it_end = it;
|
||||||
for (; it_end != it_bufend && ! (eol = *it_end == '\r' || *it_end == '\n'); ++ it_end) ;
|
for (; it_end != it_bufend && ! (eol = *it_end == '\r' || *it_end == '\n'); ++ it_end) ;
|
||||||
// End of line is indicated also if end of file was reached.
|
// End of line is indicated also if end of file was reached.
|
||||||
eol |= in.eof() && it_end == it_bufend;
|
eol |= eof && it_end == it_bufend;
|
||||||
gcode_line.insert(gcode_line.end(), it, it_end);
|
gcode_line.insert(gcode_line.end(), it, it_end);
|
||||||
if (eol) {
|
if (eol) {
|
||||||
++line_id;
|
++line_id;
|
||||||
|
@ -622,13 +627,15 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st
|
||||||
if (it != it_bufend && *it == '\n')
|
if (it != it_bufend && *it == '\n')
|
||||||
++ it;
|
++ it;
|
||||||
}
|
}
|
||||||
|
if (eof)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!export_line.empty())
|
if (!export_line.empty())
|
||||||
write_string(export_line);
|
write_string(export_line);
|
||||||
|
|
||||||
fclose(out);
|
out.close();
|
||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
// updates moves' gcode ids which have been modified by the insertion of the M73 lines
|
// updates moves' gcode ids which have been modified by the insertion of the M73 lines
|
||||||
|
@ -1234,6 +1241,7 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr
|
||||||
if (-- parse_line_callback_cntr == 0) {
|
if (-- parse_line_callback_cntr == 0) {
|
||||||
// Don't call the cancel_callback() too often, do it every at every 10000'th line.
|
// Don't call the cancel_callback() too often, do it every at every 10000'th line.
|
||||||
parse_line_callback_cntr = 10000;
|
parse_line_callback_cntr = 10000;
|
||||||
|
if (cancel_callback)
|
||||||
cancel_callback();
|
cancel_callback();
|
||||||
}
|
}
|
||||||
this->process_gcode_line(line);
|
this->process_gcode_line(line);
|
||||||
|
|
Loading…
Reference in a new issue