Implemented priority queue
This commit is contained in:
parent
b4a6d0acee
commit
16939b80e6
5 changed files with 65 additions and 27 deletions
|
@ -68,7 +68,7 @@ our $small_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||||
$small_font->SetPointSize(11) if !&Wx::wxMSW;
|
$small_font->SetPointSize(11) if !&Wx::wxMSW;
|
||||||
our $medium_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
our $medium_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||||
$medium_font->SetPointSize(12);
|
$medium_font->SetPointSize(12);
|
||||||
our $grey = Wx::Colour->new(100,100,100);
|
our $grey = Wx::Colour->new(200,200,200);
|
||||||
|
|
||||||
sub OnInit {
|
sub OnInit {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
|
@ -429,7 +429,7 @@ sub new {
|
||||||
sort keys %{$job->filament_stats};
|
sort keys %{$job->filament_stats};
|
||||||
my $text = Wx::StaticText->new($self, -1, $filament_stats, wxDefaultPosition, wxDefaultSize);
|
my $text = Wx::StaticText->new($self, -1, $filament_stats, wxDefaultPosition, wxDefaultSize);
|
||||||
$text->SetFont($Slic3r::GUI::small_font);
|
$text->SetFont($Slic3r::GUI::small_font);
|
||||||
if ($job->printed) {
|
if ($job->printed && !$job->printing) {
|
||||||
$text->SetForegroundColour($Slic3r::GUI::grey);
|
$text->SetForegroundColour($Slic3r::GUI::grey);
|
||||||
}
|
}
|
||||||
$left_sizer->Add($text, 1, wxEXPAND | wxTOP | wxBOTTOM, 7);
|
$left_sizer->Add($text, 1, wxEXPAND | wxTOP | wxBOTTOM, 7);
|
||||||
|
|
|
@ -222,16 +222,18 @@ GCodeSender::on_read(const boost::system::error_code& error,
|
||||||
&& (boost::starts_with(line, "start")
|
&& (boost::starts_with(line, "start")
|
||||||
|| boost::starts_with(line, "Grbl "))) {
|
|| boost::starts_with(line, "Grbl "))) {
|
||||||
this->connected = true;
|
this->connected = true;
|
||||||
this->can_send = true;
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
this->can_send = true;
|
||||||
|
}
|
||||||
this->send();
|
this->send();
|
||||||
} else if (boost::starts_with(line, "ok")) {
|
} else if (boost::starts_with(line, "ok")) {
|
||||||
{
|
{
|
||||||
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
this->queue.pop();
|
this->can_send = true;
|
||||||
}
|
}
|
||||||
this->can_send = true;
|
|
||||||
this->send();
|
this->send();
|
||||||
} else if (boost::istarts_with(line, "resend")
|
} else if (boost::istarts_with(line, "resend") // Marlin uses "Resend: "
|
||||||
|| boost::istarts_with(line, "rs")) {
|
|| boost::istarts_with(line, "rs")) {
|
||||||
// extract the first number from line
|
// extract the first number from line
|
||||||
using boost::lexical_cast;
|
using boost::lexical_cast;
|
||||||
|
@ -239,8 +241,11 @@ GCodeSender::on_read(const boost::system::error_code& error,
|
||||||
boost::algorithm::trim_left_if(line, !boost::algorithm::is_digit());
|
boost::algorithm::trim_left_if(line, !boost::algorithm::is_digit());
|
||||||
size_t toresend = lexical_cast<size_t>(line.substr(0, line.find_first_not_of("0123456789")));
|
size_t toresend = lexical_cast<size_t>(line.substr(0, line.find_first_not_of("0123456789")));
|
||||||
if (toresend == this->sent) {
|
if (toresend == this->sent) {
|
||||||
this->sent--;
|
{
|
||||||
this->can_send = true;
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
this->priqueue.push(this->last_sent);
|
||||||
|
this->can_send = true;
|
||||||
|
}
|
||||||
this->send();
|
this->send();
|
||||||
} else {
|
} else {
|
||||||
printf("Cannot resend %lu (last was %lu)\n", toresend, this->sent);
|
printf("Cannot resend %lu (last was %lu)\n", toresend, this->sent);
|
||||||
|
@ -251,24 +256,33 @@ GCodeSender::on_read(const boost::system::error_code& error,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GCodeSender::send(const std::vector<std::string> &lines)
|
GCodeSender::send(const std::vector<std::string> &lines, bool priority)
|
||||||
{
|
{
|
||||||
// append lines to queue
|
// append lines to queue
|
||||||
{
|
{
|
||||||
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
for (std::vector<std::string>::const_iterator line = lines.begin(); line != lines.end(); ++line)
|
for (std::vector<std::string>::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
||||||
this->queue.push(*line);
|
if (priority) {
|
||||||
|
this->priqueue.push(*line);
|
||||||
|
} else {
|
||||||
|
this->queue.push(*line);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->send();
|
this->send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GCodeSender::send(const std::string &line)
|
GCodeSender::send(const std::string &line, bool priority)
|
||||||
{
|
{
|
||||||
// append line to queue
|
// append line to queue
|
||||||
{
|
{
|
||||||
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
this->queue.push(line);
|
if (priority) {
|
||||||
|
this->priqueue.push(line);
|
||||||
|
} else {
|
||||||
|
this->queue.push(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->send();
|
this->send();
|
||||||
}
|
}
|
||||||
|
@ -276,25 +290,46 @@ GCodeSender::send(const std::string &line)
|
||||||
void
|
void
|
||||||
GCodeSender::send()
|
GCodeSender::send()
|
||||||
{
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
|
||||||
// printer is not connected or we're still waiting for the previous ack
|
// printer is not connected or we're still waiting for the previous ack
|
||||||
if (!this->can_send) return;
|
if (!this->can_send) return;
|
||||||
if (this->queue_paused) return;
|
|
||||||
|
|
||||||
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
while (!this->priqueue.empty() || (!this->queue.empty() && !this->queue_paused)) {
|
||||||
if (this->queue.empty()) return;
|
std::string line;
|
||||||
|
if (!this->priqueue.empty()) {
|
||||||
// get line and strip any comment
|
line = this->priqueue.front();
|
||||||
std::string line = this->queue.front();
|
this->priqueue.pop();
|
||||||
if (size_t comment_pos = line.find_first_of(';') != std::string::npos)
|
} else {
|
||||||
|
line = this->queue.front();
|
||||||
|
this->queue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip comments
|
||||||
|
if (size_t comment_pos = line.find_first_of(';') != std::string::npos)
|
||||||
line.erase(comment_pos, std::string::npos);
|
line.erase(comment_pos, std::string::npos);
|
||||||
boost::algorithm::trim(line);
|
boost::algorithm::trim(line);
|
||||||
|
|
||||||
|
// if line is not empty, send it
|
||||||
|
if (!line.empty()) {
|
||||||
|
this->do_send(line);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// if line is empty, process next item in queue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// caller is responsible for holding queue_mutex
|
||||||
|
void
|
||||||
|
GCodeSender::do_send(const std::string &line)
|
||||||
|
{
|
||||||
// calculate checksum
|
// calculate checksum
|
||||||
int cs = 0;
|
int cs = 0;
|
||||||
for (std::string::const_iterator it = line.begin(); it != line.end(); ++it)
|
for (std::string::const_iterator it = line.begin(); it != line.end(); ++it)
|
||||||
cs = cs ^ *it;
|
cs = cs ^ *it;
|
||||||
|
|
||||||
sent++;
|
this->sent++;
|
||||||
|
this->last_sent = line;
|
||||||
asio::streambuf b;
|
asio::streambuf b;
|
||||||
std::ostream os(&b);
|
std::ostream os(&b);
|
||||||
os << "N" << sent << " " << line
|
os << "N" << sent << " " << line
|
||||||
|
|
|
@ -19,8 +19,8 @@ class GCodeSender : private boost::noncopyable {
|
||||||
GCodeSender();
|
GCodeSender();
|
||||||
~GCodeSender();
|
~GCodeSender();
|
||||||
bool connect(std::string devname, unsigned int baud_rate);
|
bool connect(std::string devname, unsigned int baud_rate);
|
||||||
void send(const std::vector<std::string> &lines);
|
void send(const std::vector<std::string> &lines, bool priority = false);
|
||||||
void send(const std::string &s);
|
void send(const std::string &s, bool priority = false);
|
||||||
void disconnect();
|
void disconnect();
|
||||||
bool error_status() const;
|
bool error_status() const;
|
||||||
bool is_connected() const;
|
bool is_connected() const;
|
||||||
|
@ -38,14 +38,17 @@ class GCodeSender : private boost::noncopyable {
|
||||||
bool error;
|
bool error;
|
||||||
mutable boost::mutex error_mutex;
|
mutable boost::mutex error_mutex;
|
||||||
|
|
||||||
|
// this mutex guards queue, priqueue, can_send, queue_paused, sent, last_sent
|
||||||
mutable boost::mutex queue_mutex;
|
mutable boost::mutex queue_mutex;
|
||||||
std::queue<std::string> queue;
|
std::queue<std::string> queue, priqueue;
|
||||||
bool can_send;
|
bool can_send;
|
||||||
bool queue_paused;
|
bool queue_paused;
|
||||||
size_t sent;
|
size_t sent;
|
||||||
|
std::string last_sent;
|
||||||
|
|
||||||
void set_baud_rate(unsigned int baud_rate);
|
void set_baud_rate(unsigned int baud_rate);
|
||||||
void set_error_status(bool e);
|
void set_error_status(bool e);
|
||||||
|
void do_send(const std::string &line);
|
||||||
void do_close();
|
void do_close();
|
||||||
void do_read();
|
void do_read();
|
||||||
void on_read(const boost::system::error_code& error, size_t bytes_transferred);
|
void on_read(const boost::system::error_code& error, size_t bytes_transferred);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
void disconnect();
|
void disconnect();
|
||||||
bool is_connected() const;
|
bool is_connected() const;
|
||||||
int queue_size() const;
|
int queue_size() const;
|
||||||
void send(std::string s);
|
void send(std::string s, bool priority = false);
|
||||||
void pause_queue();
|
void pause_queue();
|
||||||
void resume_queue();
|
void resume_queue();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue