carb/assets/AssetsUtils.h
File members: carb/assets/AssetsUtils.h
// Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#include "IAssets.h"
namespace carb
{
namespace assets
{
template <class Type>
class ScopedSnapshot
{
public:
ScopedSnapshot() = default;
ScopedSnapshot(std::nullptr_t)
{
}
ScopedSnapshot(IAssets* assets, Id assetId) : m_assets(assets)
{
m_snapshot = assets->acquireSnapshot(assetId, getAssetType<Type>(), m_reason);
m_value = reinterpret_cast<Type*>(assets->getDataFromSnapshot(m_snapshot));
}
~ScopedSnapshot()
{
release();
}
ScopedSnapshot(ScopedSnapshot&& other)
{
m_value = other.m_value;
m_assets = other.m_assets;
m_snapshot = other.m_snapshot;
m_reason = other.m_reason;
other.m_assets = nullptr;
other.m_value = nullptr;
other.m_snapshot = kInvalidSnapshot;
other.m_reason = Reason::eFailed;
}
ScopedSnapshot& operator=(ScopedSnapshot&& other)
{
// This assert should never happen, but it is possible to accidentally write this
// code, though one has to contort themselves to do it. It is considered
// invalid nonetheless.
CARB_ASSERT(this != &other);
release();
m_value = other.m_value;
m_assets = other.m_assets;
m_snapshot = other.m_snapshot;
m_reason = other.m_reason;
other.m_assets = nullptr;
other.m_value = nullptr;
other.m_snapshot = kInvalidSnapshot;
other.m_reason = Reason::eFailed;
return *this;
}
CARB_PREVENT_COPY(ScopedSnapshot);
Type* get()
{
return m_value;
}
const Type* get() const
{
return m_value;
}
Type* operator->()
{
return get();
}
const Type* operator->() const
{
return get();
}
Type& operator*()
{
return *get();
}
const Type& operator*() const
{
return *get();
}
constexpr explicit operator bool() const noexcept
{
return m_value != nullptr;
}
Reason getReason() const
{
return m_reason;
}
private:
void release()
{
if (m_assets && m_snapshot)
{
m_assets->releaseSnapshot(m_snapshot);
}
m_value = nullptr;
m_assets = nullptr;
m_snapshot = kInvalidSnapshot;
m_reason = Reason::eFailed;
}
// Note this member is first to help in debugging.
Type* m_value = nullptr;
carb::assets::IAssets* m_assets = nullptr;
Snapshot m_snapshot = kInvalidSnapshot;
Reason m_reason = Reason::eFailed;
};
template <class Type>
bool operator==(const carb::assets::ScopedSnapshot<Type>& a, const carb::assets::ScopedSnapshot<Type>& b)
{
return a.get() == b.get();
}
template <class Type>
bool operator!=(const carb::assets::ScopedSnapshot<Type>& a, const carb::assets::ScopedSnapshot<Type>& b)
{
return a.get() != b.get();
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <class Type>
bool operator==(const carb::assets::ScopedSnapshot<Type>& a, std::nullptr_t)
{
return a.get() == nullptr;
}
template <class Type>
bool operator==(std::nullptr_t, const carb::assets::ScopedSnapshot<Type>& a)
{
return a.get() == nullptr;
}
template <class Type>
bool operator!=(const carb::assets::ScopedSnapshot<Type>& a, std::nullptr_t)
{
return a.get() != nullptr;
}
template <class Type>
bool operator!=(std::nullptr_t, const carb::assets::ScopedSnapshot<Type>& a)
{
return a.get() != nullptr;
}
#endif
} // namespace assets
} // namespace carb