private async Task UpdateGameSideReference([NotNull] AssetCompositeEditorViewModel editor, [NotNull] IGraphNode gameSideNode, ContentChangeType changeType, object oldValue, object newValue, NodeIndex index) { if (editor == null) { throw new ArgumentNullException(nameof(editor)); } if (!AssetRegistry.IsContentType(gameSideNode.Descriptor.GetInnerCollectionType())) { return; } // Grab the old referenced object if it's not null AttachedReference reference = null; if (!ReferenceEquals(oldValue, null)) { reference = AttachedReferenceManager.GetAttachedReference(oldValue); } // Switch to game thread to actually update objects await editor.Controller.InvokeTask(() => { // For references, push null instead of the real value, the editor asset loader will set the actual value later switch (changeType) { case ContentChangeType.ValueChange: ((IMemberNode)gameSideNode).Update(null); break; case ContentChangeType.CollectionUpdate: ((IObjectNode)gameSideNode).Update(null, index); break; case ContentChangeType.CollectionAdd: ((IObjectNode)gameSideNode).Add(null, index); break; case ContentChangeType.CollectionRemove: var oldValueGameSide = gameSideNode.Retrieve(index); ((IObjectNode)gameSideNode).Remove(oldValueGameSide, index); break; default: throw new ArgumentOutOfRangeException(nameof(changeType), changeType, null); } if (oldValue == newValue) { return(Task.CompletedTask); } // Unregister the previous value if (reference != null) { return(editor.Controller.Loader.Manager.ClearContentReference(Owner.Id, reference.Id, gameSideNode, index)); } return(Task.CompletedTask); }); }
public GameEditorChangePropagator([NotNull] AssetCompositeEditorViewModel editor, [NotNull] TItemViewModel owner, [NotNull] TAssetPart assetSidePart) { Editor = editor; Owner = owner; // We want to start listening to change right away, in case a change occurs immedately after creating/adding the entity var rootNode = (IAssetNode)Editor.NodeContainer.GetNode(assetSidePart); listener = new AssetGraphNodeChangeListener(rootNode, owner.Asset.PropertyGraph.Definition); listener.Initialize(); listener.ValueChanged += AssetSideNodeChanged; listener.ItemChanged += AssetSideNodeChanged; gameObjectLinker = new AssetGraphNodeLinker(owner.Asset.PropertyGraph.Definition) { LinkAction = LinkNode }; Task.Run(() => PropagatorTask(assetSidePart)); }