mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-09-23 06:33:59 +08:00
Allow using move-only types with wxMessageQueue
Add Post() overload taking r-value reference and a unit test showing that we can use it with a non-copyable type.
This commit is contained in:
+19
-2
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "wx/beforestd.h"
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
#include "wx/afterstd.h"
|
||||
|
||||
enum wxMessageQueueError
|
||||
@@ -58,6 +59,8 @@ public:
|
||||
// Add a message to this queue and signal the threads waiting for messages.
|
||||
//
|
||||
// This method is safe to call from multiple threads in parallel.
|
||||
//
|
||||
// This overload relies on Message being copyable.
|
||||
wxMessageQueueError Post(const Message& msg)
|
||||
{
|
||||
wxMutexLocker locker(m_mutex);
|
||||
@@ -71,6 +74,20 @@ public:
|
||||
return wxMSGQUEUE_NO_ERROR;
|
||||
}
|
||||
|
||||
// Overload for move-only types.
|
||||
wxMessageQueueError Post(Message&& msg)
|
||||
{
|
||||
wxMutexLocker locker(m_mutex);
|
||||
|
||||
wxCHECK( locker.IsOk(), wxMSGQUEUE_MISC_ERROR );
|
||||
|
||||
m_messages.push(std::move(msg));
|
||||
|
||||
m_conditionNotEmpty.Signal();
|
||||
|
||||
return wxMSGQUEUE_NO_ERROR;
|
||||
}
|
||||
|
||||
// Remove all messages from the queue.
|
||||
//
|
||||
// This method is meant to be called from the same thread(s) that call
|
||||
@@ -117,7 +134,7 @@ public:
|
||||
wxASSERT(timeout > 0);
|
||||
}
|
||||
|
||||
msg = m_messages.front();
|
||||
msg = std::move(m_messages.front());
|
||||
m_messages.pop();
|
||||
|
||||
return wxMSGQUEUE_NO_ERROR;
|
||||
@@ -140,7 +157,7 @@ public:
|
||||
wxCHECK( result == wxCOND_NO_ERROR, wxMSGQUEUE_MISC_ERROR );
|
||||
}
|
||||
|
||||
msg = m_messages.front();
|
||||
msg = std::move(m_messages.front());
|
||||
m_messages.pop();
|
||||
|
||||
return wxMSGQUEUE_NO_ERROR;
|
||||
|
||||
@@ -86,6 +86,16 @@ public:
|
||||
*/
|
||||
wxMessageQueueError Post(T const& msg);
|
||||
|
||||
/**
|
||||
Post a message of move-only type.
|
||||
|
||||
This function has the same semantics as the other overload but can be
|
||||
used for non-copyable (but movable) types.
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
wxMessageQueueError Post(T&& msg);
|
||||
|
||||
/**
|
||||
Block until a message becomes available in the queue.
|
||||
Waits indefinitely long or until an error occurs.
|
||||
|
||||
@@ -191,3 +191,27 @@ void *MyThread::Entry()
|
||||
|
||||
return (wxThread::ExitCode)wxMSGQUEUE_NO_ERROR;
|
||||
}
|
||||
|
||||
TEST_CASE("wxMessageQueue::NonCopyable", "[msgqueue]")
|
||||
{
|
||||
struct NonCopyable
|
||||
{
|
||||
explicit NonCopyable(int n) : m_n(new int(n)) { }
|
||||
|
||||
NonCopyable(NonCopyable&& other) = default;
|
||||
NonCopyable& operator=(NonCopyable&& other) = default;
|
||||
|
||||
std::unique_ptr<int> m_n;
|
||||
};
|
||||
|
||||
wxMessageQueue<NonCopyable> queue;
|
||||
|
||||
NonCopyable nc(17);
|
||||
CHECK( queue.Post(std::move(nc)) == wxMSGQUEUE_NO_ERROR );
|
||||
|
||||
NonCopyable nc2(0);
|
||||
CHECK( queue.Receive(nc2) == wxMSGQUEUE_NO_ERROR );
|
||||
CHECK( *nc2.m_n == 17 );
|
||||
|
||||
CHECK( queue.ReceiveTimeout(0, nc2) == wxMSGQUEUE_TIMEOUT );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user