Skip to content

Commit b752bd5

Browse files
committed
Catch exceptions in UnityPrepareRendererResources::free.
These often happen after AppDomain reloads.
1 parent e610fb5 commit b752bd5

File tree

1 file changed

+42
-34
lines changed

1 file changed

+42
-34
lines changed

native~/Runtime/src/UnityPrepareRendererResources.cpp

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,45 +1716,53 @@ void UnityPrepareRendererResources::free(
17161716
Cesium3DTilesSelection::Tile& tile,
17171717
void* pLoadThreadResult,
17181718
void* pMainThreadResult) noexcept {
1719-
if (pLoadThreadResult) {
1720-
LoadThreadResult* pTyped =
1721-
static_cast<LoadThreadResult*>(pLoadThreadResult);
1722-
for (int32_t i = 0, len = pTyped->meshes.Length(); i < len; ++i) {
1723-
CesiumForUnity::CesiumObjectPools::MeshPool().Release(pTyped->meshes[i]);
1719+
try {
1720+
if (pLoadThreadResult) {
1721+
LoadThreadResult* pTyped =
1722+
static_cast<LoadThreadResult*>(pLoadThreadResult);
1723+
for (int32_t i = 0, len = pTyped->meshes.Length(); i < len; ++i) {
1724+
CesiumForUnity::CesiumObjectPools::MeshPool().Release(
1725+
pTyped->meshes[i]);
1726+
}
1727+
delete pTyped;
17241728
}
1725-
delete pTyped;
1726-
}
17271729

1728-
if (pMainThreadResult) {
1729-
std::unique_ptr<CesiumGltfGameObject> pCesiumGameObject(
1730-
static_cast<CesiumGltfGameObject*>(pMainThreadResult));
1731-
1732-
// It's possible that the game object has already been destroyed. In which
1733-
// case Unity will throw a MissingReferenceException if we try to use it. So
1734-
// don't do that.
1735-
if (*pCesiumGameObject->pGameObject != nullptr) {
1736-
auto metadataComponent =
1737-
pCesiumGameObject->pGameObject
1738-
->GetComponentInParent<DotNet::CesiumForUnity::CesiumMetadata>();
1739-
1740-
UnityEngine::Transform parentTransform =
1741-
pCesiumGameObject->pGameObject->transform();
1742-
1743-
// Destroying primitives will remove them from the child list, so
1744-
// work backwards.
1745-
for (int32_t i = parentTransform.childCount() - 1; i >= 0; --i) {
1746-
UnityEngine::GameObject primitiveGameObject =
1747-
parentTransform.GetChild(i).gameObject();
1748-
freePrimitiveGameObject(primitiveGameObject, metadataComponent);
1749-
UnityLifetime::Destroy(primitiveGameObject);
1750-
}
1730+
if (pMainThreadResult) {
1731+
std::unique_ptr<CesiumGltfGameObject> pCesiumGameObject(
1732+
static_cast<CesiumGltfGameObject*>(pMainThreadResult));
1733+
1734+
// It's possible that the game object has already been destroyed. In which
1735+
// case Unity will throw a MissingReferenceException if we try to use it.
1736+
// So don't do that.
1737+
if (*pCesiumGameObject->pGameObject != nullptr) {
1738+
auto metadataComponent =
1739+
pCesiumGameObject->pGameObject->GetComponentInParent<
1740+
DotNet::CesiumForUnity::CesiumMetadata>();
1741+
1742+
UnityEngine::Transform parentTransform =
1743+
pCesiumGameObject->pGameObject->transform();
1744+
1745+
// Destroying primitives will remove them from the child list, so
1746+
// work backwards.
1747+
for (int32_t i = parentTransform.childCount() - 1; i >= 0; --i) {
1748+
UnityEngine::GameObject primitiveGameObject =
1749+
parentTransform.GetChild(i).gameObject();
1750+
freePrimitiveGameObject(primitiveGameObject, metadataComponent);
1751+
UnityLifetime::Destroy(primitiveGameObject);
1752+
}
17511753

1752-
if (metadataComponent == nullptr) {
1753-
freeModelMetadata(*pCesiumGameObject->pGameObject);
1754-
}
1754+
if (metadataComponent == nullptr) {
1755+
freeModelMetadata(*pCesiumGameObject->pGameObject);
1756+
}
17551757

1756-
UnityLifetime::Destroy(*pCesiumGameObject->pGameObject);
1758+
UnityLifetime::Destroy(*pCesiumGameObject->pGameObject);
1759+
}
17571760
}
1761+
} catch (...) {
1762+
// This function is a hotspot for crashes caused by AppDomain reloads.
1763+
UnityEngine::Debug::Log(
1764+
System::String("A tile was not cleaned up properly, probably due to an "
1765+
"AppDomain reload."));
17581766
}
17591767
}
17601768

0 commit comments

Comments
 (0)