| 824 | } |
| 825 | |
| 826 | bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPrefab, PrefabInstancesData& prefabInstancesData) |
| 827 | { |
| 828 | PROFILE_CPU_NAMED("Prefab.Apply"); |
| 829 | ScopeLock lock(Locker); |
| 830 | const auto prefabId = GetID(); |
| 831 | const auto oldRootId = GetRootObjectId(); |
| 832 | const auto newRootId = targetActor->GetPrefabObjectID(); |
| 833 | |
| 834 | // Gather all scene objects in target instance (reused later) |
| 835 | CollectionPoolCache<ActorsCache::SceneObjectsListType>::ScopeCache targetObjects = ActorsCache::SceneObjectsListCache.Get(); |
| 836 | targetObjects->EnsureCapacity(ObjectsCount * 4); |
| 837 | SceneQuery::GetAllSerializableSceneObjects(targetActor, *targetObjects.Value); |
| 838 | if (PrefabManager::FilterPrefabInstancesToSave(prefabId, *targetObjects.Value)) |
| 839 | return true; |
| 840 | LOG(Info, "Applying prefab changes from actor {0} (total objects count: {2}) to {1}...", targetActor->ToString(), ToString(), targetObjects->Count()); |
| 841 | Array<Guid> oldObjectsIds = ObjectsIds; |
| 842 | |
| 843 | // Serialize to json data |
| 844 | rapidjson_flax::StringBuffer dataBuffer; |
| 845 | { |
| 846 | CompactJsonWriter writerObj(dataBuffer); |
| 847 | JsonWriter& writer = writerObj; |
| 848 | writer.StartArray(); |
| 849 | for (int32 i = 0; i < targetObjects->Count(); i++) |
| 850 | { |
| 851 | SceneObject* obj = targetObjects.Value->At(i); |
| 852 | |
| 853 | // Check the whole chain of prefab references to be valid for this object |
| 854 | bool brokenPrefab = false; |
| 855 | Guid nestedPrefabId = obj->GetPrefabID(), nestedPrefabObjectId = obj->GetPrefabObjectID(); |
| 856 | while (!brokenPrefab && nestedPrefabId.IsValid() && nestedPrefabObjectId.IsValid()) |
| 857 | { |
| 858 | auto prefab = Content::Load<Prefab>(nestedPrefabId); |
| 859 | if (prefab) |
| 860 | { |
| 861 | prefab->GetNestedObject(nestedPrefabObjectId, nestedPrefabId, nestedPrefabObjectId); |
| 862 | } |
| 863 | else |
| 864 | { |
| 865 | LOG(Warning, "Missing prefab {0}.", nestedPrefabId); |
| 866 | brokenPrefab = true; |
| 867 | } |
| 868 | } |
| 869 | if (brokenPrefab) |
| 870 | { |
| 871 | LOG(Warning, "Broken prefab reference on object {0}. Breaking linkage to inline object inside prefab.", GetObjectName(obj)); |
| 872 | obj->BreakPrefabLink(); |
| 873 | } |
| 874 | |
| 875 | writer.SceneObject(obj); |
| 876 | } |
| 877 | writer.EndArray(); |
| 878 | } |
| 879 | |
| 880 | // Parse json document and modify serialized data to extract only modified properties |
| 881 | rapidjson_flax::Document diffDataDocument; |
| 882 | Dictionary<Guid, int32> diffPrefabObjectIdToDataIndex; // Maps Prefab Object Id -> Actor Data index in diffDataDocument json array (for actors/scripts to modify prefab) |
| 883 | Dictionary<Guid, int32> newPrefabInstanceIdToDataIndex; // Maps Prefab Instance Id -> Actor Data index in diffDataDocument json array (for new actors/scripts to add to prefab), maps to -1 for scripts |
nothing calls this directly
no test coverage detected