mirror of
https://github.com/leozide/leocad.git
synced 2026-10-27 06:20:55 +00:00
Move sparse piece load errors and registry locking into lcPieceManager so registry access, reference bookkeeping and copied worker metadata share one owner. Release registry and error locks before resource teardown, recursive project deletion or loader cancellation; remove library lock scopes around UI source resolution and worker-drained settings changes. Add HasOtherReferences to the shared asset reference for piece and texture consumer checks, removing the library/manager consumer-query wrappers. Keep the post-release cancellation count check and existing lifetime policies. Rename the sparse error map to mPieceDataLoadErrors and document the completed manager boundary and thread/teardown contracts. Validation: warning-free macOS Qt 6.10 Debug build and all 43 offscreen lifecycle checks pass, including concurrent metadata/error reads, settings changes with pending requests and shared reference queries. Qt 5, ASan and successful GPU rendering were not tested.
150 lines
3.3 KiB
C++
150 lines
3.3 KiB
C++
#include "lc_global.h"
|
|
#include "lc_assettypes.h"
|
|
#include "lc_library.h"
|
|
#include "lc_application.h"
|
|
#include "lc_mesh.h"
|
|
#include "lc_piecedata.h"
|
|
#include "lc_texture.h"
|
|
|
|
template<>
|
|
void lcAssetRef<lcPieceData>::Retain(lcPieceData* Asset, lcPiecesLibrary* Library)
|
|
{
|
|
Library->AddPieceDataReference(Asset);
|
|
}
|
|
|
|
template<>
|
|
void lcAssetRef<lcPieceData>::Release(lcPieceData* Asset, lcPiecesLibrary* Library)
|
|
{
|
|
Library->ReleasePieceData(Asset);
|
|
}
|
|
|
|
template<>
|
|
void lcAssetRef<lcTexture>::Retain(lcTexture* Asset, lcPiecesLibrary* Library)
|
|
{
|
|
Library->AddTextureReference(Asset);
|
|
}
|
|
|
|
template<>
|
|
void lcAssetRef<lcTexture>::Release(lcTexture* Asset, lcPiecesLibrary* Library)
|
|
{
|
|
Library->ReleaseTexture(Asset);
|
|
}
|
|
|
|
template<typename T>
|
|
lcAssetRef<T>::lcAssetRef(T* Asset)
|
|
: lcAssetRef(Asset, Asset ? lcGetPiecesLibrary() : nullptr)
|
|
{
|
|
}
|
|
|
|
template<typename T>
|
|
lcAssetRef<T>::lcAssetRef(T* Asset, lcPiecesLibrary* Library)
|
|
: mAsset(Asset), mLibrary(Library)
|
|
{
|
|
if (mAsset)
|
|
{
|
|
Q_ASSERT(mLibrary && QThread::currentThread() == mLibrary->thread());
|
|
Retain(mAsset, mLibrary);
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
lcAssetRef<T>::lcAssetRef(const lcAssetRef& OtherRef)
|
|
: lcAssetRef(OtherRef.mAsset, OtherRef.mLibrary)
|
|
{
|
|
}
|
|
|
|
template<typename T>
|
|
lcAssetRef<T>::lcAssetRef(lcAssetRef&& OtherRef) noexcept
|
|
: mAsset(std::exchange(OtherRef.mAsset, nullptr)), mLibrary(std::exchange(OtherRef.mLibrary, nullptr))
|
|
{
|
|
}
|
|
|
|
template<typename T>
|
|
lcAssetRef<T>::~lcAssetRef()
|
|
{
|
|
if (mAsset)
|
|
{
|
|
Q_ASSERT(mLibrary && QThread::currentThread() == mLibrary->thread());
|
|
Release(mAsset, mLibrary);
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
lcAssetRef<T>& lcAssetRef<T>::operator=(const lcAssetRef& OtherRef)
|
|
{
|
|
if (this != &OtherRef)
|
|
{
|
|
lcAssetRef CopyRef(OtherRef);
|
|
Swap(CopyRef);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
lcAssetRef<T>& lcAssetRef<T>::operator=(lcAssetRef&& OtherRef) noexcept
|
|
{
|
|
if (this != &OtherRef)
|
|
{
|
|
lcAssetRef MovedRef(std::move(OtherRef));
|
|
Swap(MovedRef);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
bool lcAssetRef<T>::HasOtherReferences() const
|
|
{
|
|
Q_ASSERT(!mAsset || (mLibrary && QThread::currentThread() == mLibrary->thread()));
|
|
|
|
return mAsset && mAsset->GetRefCount() > 1;
|
|
}
|
|
|
|
template<typename T>
|
|
void lcAssetRef<T>::Reset()
|
|
{
|
|
lcAssetRef EmptyRef;
|
|
Swap(EmptyRef);
|
|
}
|
|
|
|
template<typename T>
|
|
T* lcAssetRef<T>::Release()
|
|
{
|
|
mLibrary = nullptr;
|
|
return std::exchange(mAsset, nullptr);
|
|
}
|
|
|
|
template<typename T>
|
|
void lcAssetRef<T>::Swap(lcAssetRef& OtherRef) noexcept
|
|
{
|
|
std::swap(mAsset, OtherRef.mAsset);
|
|
std::swap(mLibrary, OtherRef.mLibrary);
|
|
}
|
|
|
|
template<typename T>
|
|
lcAssetRef<T> lcAssetRef<T>::Adopt(T* Asset, lcPiecesLibrary* Library)
|
|
{
|
|
Q_ASSERT(!Asset || (Library && QThread::currentThread() == Library->thread()));
|
|
|
|
lcAssetRef AssetRef;
|
|
AssetRef.mAsset = Asset;
|
|
AssetRef.mLibrary = Library;
|
|
return AssetRef;
|
|
}
|
|
|
|
template class lcAssetRef<lcPieceData>;
|
|
template class lcAssetRef<lcTexture>;
|
|
|
|
lcPieceSourceSnapshot::lcPieceSourceSnapshot()
|
|
: ZipFileType(lcZipFileType::Count), StudStyle(lcStudStyle::Plain)
|
|
{
|
|
}
|
|
|
|
lcPieceBuildResult::lcPieceBuildResult() = default;
|
|
lcPieceBuildResult::~lcPieceBuildResult() = default;
|
|
lcPieceBuildResult::lcPieceBuildResult(lcPieceBuildResult&&) noexcept = default;
|
|
lcPieceBuildResult& lcPieceBuildResult::operator=(lcPieceBuildResult&&) noexcept = default;
|
|
|
|
lcTextureBuildResult::~lcTextureBuildResult() = default;
|