#pragma once
#include <cstdint>
#include <iostream>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <stdexcept>
#include <QtCore/QDebug>
#include <QtCore/QMetaObject>
#include "rust/cxx.h"
namespace rust {
namespace cxxqt1 {
template<typename T>
class CxxQtGuardedPointer final
{
public:
explicit CxxQtGuardedPointer(T* ptr)
: ptr(ptr)
{
}
T* ptr;
::std::shared_mutex mutex;
};
template<typename T>
class CxxQtThread final
{
public:
CxxQtThread(::std::shared_ptr<CxxQtGuardedPointer<T>> obj)
: m_obj(obj)
{
}
~CxxQtThread() = default;
CxxQtThread(const CxxQtThread<T>& other) = default;
CxxQtThread(CxxQtThread<T>&& other) = default;
bool isDestroyed() const
{
const auto guard = ::std::shared_lock(m_obj->mutex);
return m_obj->ptr == nullptr;
}
template<typename A>
::std::uint8_t queue(::rust::Fn<void(T& self, ::rust::Box<A> arg)> func,
::rust::Box<A> arg) const
{
const static ::std::uint8_t sObjectDestroyed = 1;
const static ::std::uint8_t sInvokeMethodFailed = 2;
const auto guard = ::std::shared_lock(m_obj->mutex);
if (!m_obj->ptr) {
return sObjectDestroyed;
}
auto obj = m_obj;
auto lambda = [obj = ::std::move(obj),
func = ::std::move(func),
arg = ::std::move(arg)]() mutable {
const auto guard = ::std::shared_lock(obj->mutex);
if (obj->ptr) {
func(*obj->ptr, ::std::move(arg));
} else {
qWarning()
<< "Could not call the function pointer as object has been destroyed";
}
};
if (!QMetaObject::invokeMethod(
m_obj->ptr, ::std::move(lambda), Qt::QueuedConnection)) {
return sInvokeMethodFailed;
}
return 0;
}
private:
::std::shared_ptr<CxxQtGuardedPointer<T>> m_obj;
};
template<typename T>
CxxQtThread<T>
cxxQtThreadClone(const CxxQtThread<T>& cxxQtThread)
{
return CxxQtThread<T>(cxxQtThread);
}
template<typename T>
void
cxxQtThreadDrop(CxxQtThread<T>& cxxQtThread)
{
cxxQtThread.~CxxQtThread<T>();
}
template<typename A, typename T>
::std::uint8_t
cxxQtThreadQueue(const CxxQtThread<T>& cxxQtThread,
::rust::Fn<void(T& self, ::rust::Box<A> arg)> func,
::rust::Box<A> arg)
{
return cxxQtThread.queue(::std::move(func), ::std::move(arg));
}
template<typename T>
bool
cxxQtThreadIsDestroyed(const CxxQtThread<T>& cxxQtThread)
{
return cxxQtThread.isDestroyed();
}
} }
namespace rust {
template<typename T>
struct IsRelocatable<::rust::cxxqt1::CxxQtThread<T>> : ::std::true_type
{};
}