Merge remote-tracking branch 'origin/master' into 1.12

# Conflicts:
#	Content/Editor/MaterialTemplates/Deformable.shader
#	Flax.flaxproj
#	Source/Engine/Content/Content.h
#	Source/Engine/Serialization/JsonTools.cpp
This commit is contained in:
Wojtek Figat
2026-04-01 17:14:21 +02:00
115 changed files with 2933 additions and 1074 deletions

View File

@@ -98,6 +98,9 @@ namespace
DateTime LastWorkspaceDiscovery;
CriticalSection WorkspaceDiscoveryLocker;
#endif
#if USE_EDITOR
Dictionary<Guid, HashSet<BinaryAsset*>> PendingDependencies;
#endif
}
#if ENABLE_ASSETS_DISCOVERY
@@ -184,6 +187,9 @@ void ContentService::Update()
{
auto asset = LoadedAssetsToInvoke.Dequeue();
asset->onLoaded_MainThread();
#if USE_EDITOR
Content::onAddDependencies(asset);
#endif
}
LoadedAssetsToInvokeLocker.Unlock();
}
@@ -1091,10 +1097,17 @@ bool Content::CloneAssetFile(const StringView& dstPath, const StringView& srcPat
FileSystem::DeleteFile(tmpPath);
// Reload storage
if (auto storage = ContentStorageManager::GetStorage(dstPath, false))
auto storage = ContentStorageManager::GetStorage(dstPath, false);
if (storage && storage->IsLoaded())
{
storage->Reload();
}
else if (auto dependencies = PendingDependencies.TryGet(dstId))
{
// Destination storage is not loaded but there are other assets that depend on it so update them
for (const auto& e : *dependencies)
e.Item->OnDependencyModified(nullptr);
}
}
}
else
@@ -1311,6 +1324,9 @@ void Content::tryCallOnLoaded(Asset* asset)
{
LoadedAssetsToInvoke.RemoveAtKeepOrder(index);
asset->onLoaded_MainThread();
#if USE_EDITOR
onAddDependencies(asset);
#endif
}
}
@@ -1328,6 +1344,10 @@ void Content::onAssetUnload(Asset* asset)
Assets.Remove(asset->GetID());
UnloadQueue.Remove(asset);
LoadedAssetsToInvoke.Remove(asset);
#if USE_EDITOR
for (auto& e : PendingDependencies)
e.Value.Remove(asset);
#endif
}
void Content::onAssetChangeId(Asset* asset, const Guid& oldId, const Guid& newId)
@@ -1335,8 +1355,42 @@ void Content::onAssetChangeId(Asset* asset, const Guid& oldId, const Guid& newId
ScopeLock locker(AssetsLocker);
Assets.Remove(oldId);
Assets.Add(newId, asset);
#if USE_EDITOR
if (PendingDependencies.ContainsKey(oldId))
{
auto deps = MoveTemp(PendingDependencies[oldId]);
PendingDependencies.Remove(oldId);
PendingDependencies.Add(newId, MoveTemp(deps));
}
#endif
}
#if USE_EDITOR
void Content::onAssetDepend(BinaryAsset* asset, const Guid& otherId)
{
ScopeLock locker(AssetsLocker);
PendingDependencies[otherId].Add(asset);
}
void Content::onAddDependencies(Asset* asset)
{
auto it = PendingDependencies.Find(asset->GetID());
if (it.IsNotEnd())
{
auto& dependencies = it->Value;
auto binaryAsset = Asset::Cast<BinaryAsset>(asset);
if (binaryAsset)
{
for (const auto& e : dependencies)
binaryAsset->_dependantAssets.Add(e.Item);
}
PendingDependencies.Remove(it);
}
}
#endif
bool Content::IsAssetTypeIdInvalid(const ScriptingTypeHandle& type, const ScriptingTypeHandle& assetType)
{
// Skip if no restrictions for the type