OrcaSlicer/src/slic3r/GUI/Jobs/ThreadSafeQueue.hpp
Noisyfox 933aa3050b
Port Emboss & SVG gizmo from PrusaSlicer (#2819)
* Rework UI jobs to make them more understandable and flexible.

* Update Orca specific jobs

* Fix progress issue

* Fix dark mode and window radius

* Update cereal version from 1.2.2 to 1.3.0

(cherry picked from commit prusa3d/PrusaSlicer@057232a275)

* Initial port of Emboss gizmo

* Bump up CGAL version to 5.4

(cherry picked from commit prusa3d/PrusaSlicer@1bf9dee3e7)

* Fix text rotation

* Fix test dragging

* Add text gizmo to right click menu

* Initial port of SVG gizmo

* Fix text rotation

* Fix Linux build

* Fix "from surface"

* Fix -90 rotation

* Fix icon path

* Fix loading font with non-ascii name

* Fix storing non-utf8 font descriptor in 3mf file

* Fix filtering with non-utf8 characters

* Emboss: Use Orca style input dialog

* Fix build on macOS

* Fix tooltip color in light mode

* InputText: fixed incorrect padding when FrameBorder > 0. (ocornut/imgui#4794, ocornut/imgui#3781)
InputTextMultiline: fixed vertical tracking with large values of FramePadding.y. (ocornut/imgui#3781, ocornut/imgui#4794)

(cherry picked from commit ocornut/imgui@072caa4a90)
(cherry picked from commit ocornut/imgui@bdd2a94315)

* SVG: Use Orca style input dialog

* Fix job progress update

* Fix crash when select editing text in preview screen

* Use Orca checkbox style

* Fix issue that toolbar icons are kept regenerated

* Emboss: Fix text & icon alignment

* SVG: Fix text & icon alignment

* Emboss: fix toolbar icon mouse hover state

* Add a simple subtle outline effect by drawing back faces using wireframe mode

* Disable selection outlines

* Show outline in white if the model color is too dark

* Make the outline algorithm more reliable

* Enable cull face, which fix render on Linux

* Fix `disable_cullface`

* Post merge fix

* Optimize selection rendering

* Fix scale gizmo

* Emboss: Fix text rotation if base object is scaled

* Fix volume synchronize

* Fix emboss rotation

* Emboss: Fix advance toggle

* Fix text position after reopened the project

* Make font style preview darker

* Make font style preview selector height shorter

---------

Co-authored-by: tamasmeszaros <meszaros.q@gmail.com>
Co-authored-by: ocornut <omarcornut@gmail.com>
Co-authored-by: SoftFever <softfeverever@gmail.com>
2023-12-09 22:46:18 +08:00

128 lines
3.4 KiB
C++

///|/ Copyright (c) Prusa Research 2021 Tomáš Mészáros @tamasmeszaros
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#ifndef THREADSAFEQUEUE_HPP
#define THREADSAFEQUEUE_HPP
#include <type_traits>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
namespace Slic3r { namespace GUI {
// Helper structure for overloads of ThreadSafeQueueSPSC::consume_one()
// to block if the queue is empty.
struct BlockingWait
{
// Timeout to wait for the arrival of new element into the queue.
unsigned timeout_ms = 0;
// An optional atomic flag to set true if an incoming element gets
// consumed. The flag will be atomically set to true when popping the
// front of the queue.
std::atomic<bool> *pop_flag = nullptr;
};
// A thread safe queue for one producer and one consumer.
template<class T,
template<class, class...> class Container = std::deque,
class... ContainerArgs>
class ThreadSafeQueueSPSC
{
std::queue<T, Container<T, ContainerArgs...>> m_queue;
mutable std::mutex m_mutex;
std::condition_variable m_cond_var;
public:
// Consume one element, block if the queue is empty.
template<class Fn> bool consume_one(const BlockingWait &blkw, Fn &&fn)
{
static_assert(!std::is_reference_v<T>, "");
static_assert(std::is_default_constructible_v<T>, "");
static_assert(std::is_move_assignable_v<T> || std::is_copy_assignable_v<T>, "");
T el;
{
std::unique_lock lk{m_mutex};
auto pred = [this]{ return !m_queue.empty(); };
if (blkw.timeout_ms > 0) {
auto timeout = std::chrono::milliseconds(blkw.timeout_ms);
if (!m_cond_var.wait_for(lk, timeout, pred))
return false;
}
else
m_cond_var.wait(lk, pred);
if constexpr (std::is_move_assignable_v<T>)
el = std::move(m_queue.front());
else
el = m_queue.front();
m_queue.pop();
if (blkw.pop_flag)
// The optional flag is set before the lock us unlocked.
blkw.pop_flag->store(true);
}
fn(el);
return true;
}
// Consume one element, return true if consumed, false if queue was empty.
template<class Fn> bool consume_one(Fn &&fn)
{
T el;
{
std::unique_lock lk{m_mutex};
if (!m_queue.empty()) {
if constexpr (std::is_move_assignable_v<T>)
el = std::move(m_queue.front());
else
el = m_queue.front();
m_queue.pop();
} else
return false;
}
fn(el);
return true;
}
// Push element into the queue.
template<class...TArgs> void push(TArgs&&...el)
{
std::lock_guard lk{m_mutex};
m_queue.emplace(std::forward<TArgs>(el)...);
m_cond_var.notify_one();
}
bool empty() const
{
std::lock_guard lk{m_mutex};
return m_queue.empty();
}
size_t size() const
{
std::lock_guard lk{m_mutex};
return m_queue.size();
}
void clear()
{
std::lock_guard lk{m_mutex};
while (!m_queue.empty())
m_queue.pop();
}
};
}} // namespace Slic3r::GUI
#endif // THREADSAFEQUEUE_HPP