diff --git a/Source/Engine/Level/Prefabs/Prefab.Apply.cpp b/Source/Engine/Level/Prefabs/Prefab.Apply.cpp
index c10ea532d..569a7ce9b 100644
--- a/Source/Engine/Level/Prefabs/Prefab.Apply.cpp
+++ b/Source/Engine/Level/Prefabs/Prefab.Apply.cpp
@@ -22,6 +22,7 @@
#include "Engine/ContentImporters/CreateJson.h"
#include "Engine/Debug/Exceptions/ArgumentNullException.h"
#include "Engine/Profiler/ProfilerCPU.h"
+#include "Engine/Threading/MainThreadTask.h"
#include "Editor/Editor.h"
// Apply flow:
@@ -174,6 +175,12 @@ public:
/// Collection with ids of the objects (actors and scripts) from the prefab after changes apply. Used to find new objects or old objects and use this information during changes sync (eg. generate ids for the new objects to prevent ids collisions).
/// True if failed, otherwise false.
static bool SynchronizePrefabInstances(PrefabInstancesData& prefabInstancesData, Actor* defaultInstance, SceneObjectsListCacheType& sceneObjects, const Guid& prefabId, rapidjson_flax::StringBuffer& tmpBuffer, const Array& oldObjectsIds, const Array& newObjectIds);
+
+ static void DeletePrefabObject(SceneObject* obj)
+ {
+ obj->SetParent(nullptr);
+ obj->DeleteObject();
+ }
};
void PrefabInstanceData::CollectPrefabInstances(PrefabInstancesData& prefabInstancesData, const Guid& prefabId, Actor* defaultInstance, Actor* targetActor)
@@ -302,14 +309,10 @@ bool PrefabInstanceData::SynchronizePrefabInstances(PrefabInstancesData& prefabI
{
// Remove object
LOG(Info, "Removing object {0} from instance {1} (prefab: {2})", obj->GetSceneObjectId(), instance.TargetActor->ToString(), prefabId);
-
- obj->DeleteObject();
- obj->SetParent(nullptr);
-
+ DeletePrefabObject(obj);
sceneObjects.Value->RemoveAtKeepOrder(i);
existingObjectsCount--;
i--;
-
continue;
}
@@ -358,10 +361,7 @@ bool PrefabInstanceData::SynchronizePrefabInstances(PrefabInstancesData& prefabI
{
// Remove object removed from the prefab
LOG(Info, "Removing prefab instance object {0} from instance {1} (prefab object: {2}, prefab: {3})", obj->GetSceneObjectId(), instance.TargetActor->ToString(), obj->GetPrefabObjectID(), prefabId);
-
- obj->DeleteObject();
- obj->SetParent(nullptr);
-
+ DeletePrefabObject(obj);
sceneObjects.Value->RemoveAtKeepOrder(i);
deserializeSceneObjectIndex--;
existingObjectsCount--;
@@ -633,6 +633,19 @@ bool Prefab::ApplyAll(Actor* targetActor)
}
}
}
+ if (!IsInMainThread())
+ {
+ // Prefabs cannot be updated on async thread so sync it with a Main Thread
+ bool result = true;
+ Function action = [&]
+ {
+ result = ApplyAll(targetActor);
+ };
+ const auto task = Task::StartNew(New(action));
+ if (task->Wait(TimeSpan::FromSeconds(10)))
+ result = true;
+ return result;
+ }
// Prevent cyclic references
{
@@ -921,9 +934,7 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
{
// Remove object removed from the prefab
LOG(Info, "Removing object {0} from prefab default instance", obj->GetSceneObjectId());
-
- obj->DeleteObject();
- obj->SetParent(nullptr);
+ PrefabInstanceData::DeletePrefabObject(obj);
sceneObjects->At(i) = nullptr;
}
}