diff --git a/src/libslic3r/Channel.hpp b/src/libslic3r/Channel.hpp new file mode 100644 index 000000000..8d1a07d35 --- /dev/null +++ b/src/libslic3r/Channel.hpp @@ -0,0 +1,104 @@ +#ifndef slic3r_Channel_hpp_ +#define slic3r_Channel_hpp_ + +#include +#include +#include +#include +#include + + +namespace Slic3r { + + +template class Channel +{ +private: + using UniqueLock = std::unique_lock; + using Queue = std::deque; +public: + class Guard + { + public: + Guard(UniqueLock lock, const Queue &queue) : m_lock(std::move(lock)), m_queue(queue) {} + Guard(const Guard &other) = delete; + Guard(Guard &&other) = delete; + ~Guard() {} + + // Access trampolines + size_t size() const noexcept { return m_queue.size(); } + bool empty() const noexcept { return m_queue.empty(); } + typename Queue::const_iterator begin() const noexcept { return m_queue.begin(); } + typename Queue::const_iterator end() const noexcept { return m_queue.end(); } + typename Queue::const_reference operator[](size_t i) const { return m_queue[i]; } + + Guard& operator=(const Guard &other) = delete; + Guard& operator=(Guard &&other) = delete; + private: + UniqueLock m_lock; + const Queue &m_queue; + }; + + + Channel() {} + ~Channel() {} + + void push(const T& item, bool silent = false) + { + { + UniqueLock lock(m_mutex); + m_queue.push_back(item); + } + if (! silent) { m_condition.notify_one(); } + } + + void push(T &&item, bool silent = false) + { + { + UniqueLock lock(m_mutex); + m_queue.push_back(std::forward(item)); + } + if (! silent) { m_condition.notify_one(); } + } + + T pop() + { + UniqueLock lock(m_mutex); + m_condition.wait(lock, [this]() { return !m_queue.empty(); }); + auto item = std::move(m_queue.front()); + m_queue.pop_front(); + return item; + } + + boost::optional try_pop() + { + UniqueLock lock(m_mutex); + if (m_queue.empty()) { + return boost::none; + } else { + auto item = std::move(m_queue.front()); + m_queue.pop(); + return item; + } + } + + // Unlocked observers + // Thread unsafe! Keep in mind you need to re-verify the result after acquiring lock! + size_t size() const noexcept { return m_queue.size(); } + bool empty() const noexcept { return m_queue.empty(); } + + Guard read() const + { + return Guard(UniqueLock(m_mutex), m_queue); + } + +private: + Queue m_queue; + std::mutex m_mutex; + std::condition_variable m_condition; +}; + + +} // namespace Slic3r + +#endif // slic3r_Channel_hpp_ diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 1829de959..3a34b3381 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -17,6 +17,7 @@ #include "libslic3r/GCode/PostProcessor.hpp" //#undef NDEBUG +#include // XXX #include #include #include @@ -79,6 +80,10 @@ void BackgroundSlicingProcess::process_fff() wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id)); m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); if (this->set_step_started(bspsGCodeFinalize)) { + + std::cerr << "BackgroundSlicingProcess: m_upload_job: " << !!m_upload_job << std::endl; + std::cerr << "BackgroundSlicingProcess: m_export_path: " << m_export_path << std::endl; + if (! m_export_path.empty()) { //FIXME localize the messages // Perform the final post-processing of the export path by applying the print statistics over the file name. @@ -387,7 +392,7 @@ void BackgroundSlicingProcess::schedule_upload(Slic3r::PrintHostJob upload_job) if (! m_export_path.empty()) return; - const auto path = boost::filesystem::temp_directory_path() + const boost::filesystem::path path = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(".upload.%%%%-%%%%-%%%%-%%%%.gcode"); // Guard against entering the export step before changing the export path. diff --git a/src/slic3r/Utils/PrintHost.hpp b/src/slic3r/Utils/PrintHost.hpp index 2ccd1382a..115807e9a 100644 --- a/src/slic3r/Utils/PrintHost.hpp +++ b/src/slic3r/Utils/PrintHost.hpp @@ -43,10 +43,24 @@ struct PrintHostJob std::unique_ptr printhost; PrintHostJob() {} + PrintHostJob(const PrintHostJob&) = delete; + PrintHostJob(PrintHostJob &&other) + : upload_data(std::move(other.upload_data)) + , printhost(std::move(other.printhost)) + {} + PrintHostJob(DynamicPrintConfig *config) : printhost(PrintHost::get_print_host(config)) {} + PrintHostJob& operator=(const PrintHostJob&) = delete; + PrintHostJob& operator=(PrintHostJob &&other) + { + upload_data = std::move(other.upload_data); + printhost = std::move(other.printhost); + return *this; + } + bool empty() const { return !printhost; } operator bool() const { return !!printhost; } };