/// <inheritdoc/>
        protected override bool CanUpdate(IAssetNode node, ContentChangeType changeType, NodeIndex index, object value)
        {
            // Check if we are in the component collection of an entity (where we actually add new components)
            if (IsComponentForComponentCollection(node, value) && changeType == ContentChangeType.CollectionAdd)
            {
                var componentType       = value.GetType();
                var attributes          = EntityComponentAttributes.Get(componentType);
                var onlySingleComponent = !attributes.AllowMultipleComponents;
                var collection          = (EntityComponentCollection)node.Retrieve();

                foreach (var existingItem in collection)
                {
                    if (ReferenceEquals(existingItem, value))
                    {
                        return(false);
                    }

                    if (onlySingleComponent && componentType == existingItem.GetType())
                    {
                        return(false);
                    }
                }
            }

            return(base.CanUpdate(node, changeType, index, value));
        }
Beispiel #2
0
        public void RegisterBaseToDerived(IAssetNode baseNode, IAssetNode derivedNode)
        {
            var baseValue = baseNode?.Retrieve();

            if (baseValue == null)
            {
                return;
            }

            if (baseValue is IIdentifiable)
            {
                baseToDerived[baseNode] = derivedNode;
                var baseMemberNode = baseNode as IAssetMemberNode;
                if (baseMemberNode?.Target != null && !propertyGraph.Definition.IsMemberTargetObjectReference(baseMemberNode, baseValue))
                {
                    baseToDerived[baseMemberNode.Target] = ((IAssetMemberNode)derivedNode).Target;
                }
            }

            var derivedObjectNode = derivedNode as IObjectNode;
            var baseObjectNode    = baseNode as IObjectNode;

            if (derivedObjectNode?.ItemReferences != null && baseObjectNode?.ItemReferences != null)
            {
                foreach (var reference in derivedObjectNode.ItemReferences)
                {
                    var target = propertyGraph.baseLinker.FindTargetReference(derivedNode, baseNode, reference);
                    if (target == null)
                    {
                        continue;
                    }

                    baseValue = target.TargetNode?.Retrieve();
                    if (!propertyGraph.Definition.IsTargetItemObjectReference(baseObjectNode, target.Index, baseNode.Retrieve(target.Index)))
                    {
                        if (baseValue is IIdentifiable)
                        {
                            baseToDerived[(IAssetNode)target.TargetNode] = (IAssetNode)derivedObjectNode.IndexedTarget(reference.Index);
                        }
                    }
                }
            }
        }
        /// <inheritdoc/>
        protected override object CloneValueFromBase(object value, IAssetNode node)
        {
            // TODO: check CloneObjectForGameSide if modifying this method, the logic should be factorized at some point.
            if (IsComponentForComponentCollection(node, value) && value is TransformComponent)
            {
                // We never clone TransformComponent, we cannot replace them. Instead, return the existing one.
                var transformComponent = (TransformComponent)node.Retrieve(new Index(0));
                // We still reset the Entity to null to make sure it works nicely with reconcilation, etc.
                transformComponent.Entity = null;
                return transformComponent;
            }

            var clone = base.CloneValueFromBase(value, node);
            var component = clone as EntityComponent;
            if (component != null)
            {
                // Components need their Entity to be cleared first because subsequent actions will try to restore it and safeguards might throw if it's not null beforehand
                component.Entity = null;
            }
            return clone;
        }
 public void Visit([NotNull] IAssetNode node, NodeIndex index)
 {
     if (index == NodeIndex.Empty)
     {
         // Normal case, no index
         Visit(node);
     }
     else if (node.IsReference)
     {
         // We have an index, and our collection is a collection of reference types, then start visit from the target item
         var target = ((IObjectNode)node).IndexedTarget(index);
         if (target != null)
         {
             Visit(target);
         }
     }
     else if (AssetRegistry.IsContentType(node.Descriptor.GetInnerCollectionType()))
     {
         // We have an index, and our collection is directly a collection of content type. Let's just collect the corresponding item.
         var gameContent = node.GetContent("Game");
         var id          = AttachedReferenceManager.GetAttachedReference(node.Retrieve(index))?.Id ?? AssetId.Empty;
         CollectContentReference(id, gameContent, index);
     }
 }