/// <summary> /// Refresh ObjectReferences, throws NPE for broken ObjectReferences. /// /// An ObjectReference is considered broken if it's object has been deleted. /// </summary> /// <param name="instance"></param> private void doRemap(GameObject instance) { Stack <IPropertyContainer> toVisit = new Stack <IPropertyContainer>(); toVisit.Push(instance); while (toVisit.Any()) { IPropertyContainer currentInstance = toVisit.Pop(); foreach (IProperty property in currentInstance.Properties) { switch (property) { case PropertyObject po: { ObjectReference reference = po.Value; if (reference.IsId && reference.ObjectId >= startIndex) { reference.ObjectId = MappedObjects[reference.ObjectId].Id; } break; } case PropertyArray pa: { IArkArray <IStruct> structList = pa.GetTypedValue <IStruct>(); IArkArray <ObjectReference> objectReferenceList = pa.GetTypedValue <ObjectReference>(); if (structList != null) { foreach (IStruct aStruct in structList) { if (aStruct is IPropertyContainer container) { toVisit.Push(container); } } } else if (objectReferenceList != null) { foreach (ObjectReference reference in objectReferenceList) { if (reference.IsId && reference.ObjectId >= startIndex) { reference.ObjectId = MappedObjects[reference.ObjectId].Id; } } } break; } case PropertyStruct ps: { IStruct aStruct = ps.Value; if (aStruct is IPropertyContainer container) { toVisit.Push(container); } break; } } } } }
private void visit(Stack <IPropertyContainer> toVisit, GameObjectContainer container, bool followReferences, bool withComponents) { while (toVisit.Any()) { IPropertyContainer currentInstance = toVisit.Pop(); if (followReferences) { foreach (IProperty property in currentInstance.Properties) { if (property is PropertyObject po) { ObjectReference reference = po.Value; GameObject referenced = reference.GetObject(container); if (referenced != null && !MappedObjects.ContainsKey(referenced.Id)) { MappedObjects[referenced.Id] = referenced; toVisit.Push(referenced); } } else if (property is PropertyArray pa) { IArkArray <IStruct> structList = pa.GetTypedValue <IStruct>(); IArkArray <ObjectReference> objectReferenceList = pa.GetTypedValue <ObjectReference>(); if (structList != null) { foreach (IStruct aStruct in structList) { if (aStruct is IPropertyContainer propertyContainer) { toVisit.Push(propertyContainer); } } } else if (objectReferenceList != null) { foreach (ObjectReference reference in objectReferenceList) { GameObject referenced = reference.GetObject(container); if (referenced != null && !MappedObjects.ContainsKey(referenced.Id)) { MappedObjects[referenced.Id] = referenced; toVisit.Push(referenced); } } } } else if (property is PropertyStruct ps) { IStruct aStruct = ps.Value; if (aStruct is IPropertyContainer propertyContainer) { toVisit.Push(propertyContainer); } } } } if (withComponents && currentInstance is GameObject) { GameObject gameObject = (GameObject)currentInstance; foreach (GameObject component in gameObject.Components.Values) { if (!MappedObjects.ContainsKey(component.Id)) { MappedObjects[component.Id] = component; toVisit.Push(component); } } } } }