Ejemplo n.º 1
0
 /// <summary>
 /// Add a new attachment point to the pending list to be processed when the system is ready.
 /// </summary>
 /// <param name="attachPoint">Attachment point to process later.</param>
 /// <param name="context">Optional spawning attachment point, may be null.</param>
 private void AddPendingAttachmentPoint(AttachmentPoint attachPoint, IAttachmentPoint context)
 {
     // Flag as being in an invalid state
     attachPoint.HandleStateChange(AttachmentPointStateType.Pending);
     pendingAttachments.Add(
         new PendingAttachmentPoint
     {
         target  = attachPoint,
         context = context
     }
         );
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Add an existing attachment point to this fragment.
 /// </summary>
 /// <remarks>
 /// The attachment point might currently belong to another fragment, if
 /// it is being moved from the other to this.
 /// Since this is only used internally, it operates directly on an AttachmentPoint
 /// rather than an interface to avoid an unnecessary downcast.
 /// </remarks>
 /// <param name="attachPoint"></param>
 public void AddAttachmentPoint(AttachmentPoint attachPoint)
 {
     if (attachPoint != null)
     {
         if (attachPoint.StateHandler != null)
         {
             updateStateAllAttachments += attachPoint.StateHandler;
         }
         attachPoint.HandleStateChange(State);
         attachmentList.Add(attachPoint);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Absorb the contents of another fragment, emptying it.
        /// </summary>
        /// <param name="other">The fragment to lose all its contents to this.</param>
        public void AbsorbOtherFragment(Fragment other)
        {
            Debug.Assert(other != this, $"Trying to merge to and from the same fragment {FragmentId}");
            int otherCount = other.attachmentList.Count;

            for (int i = 0; i < otherCount; ++i)
            {
                AttachmentPoint att = other.attachmentList[i];
                att.Set(FragmentId, att.CachedPosition, att.AnchorId, att.LocationFromAnchor);
                if (att.StateHandler != null)
                {
                    updateStateAllAttachments += att.StateHandler;
                }
                att.HandleStateChange(State);
                attachmentList.Add(att);
            }
            other.ReleaseAll();
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Notify system attachment point is no longer needed. See <see cref="IAttachmentPointManager.ReleaseAttachmentPoint"/>
        /// </summary>
        /// <param name="attachmentPoint"></param>
        public void ReleaseAttachmentPoint(IAttachmentPoint attachmentPoint)
        {
            AttachmentPoint attachPoint = attachmentPoint as AttachmentPoint;

            if (attachPoint != null)
            {
                if (attachPoint.StateHandler != null)
                {
                    updateStateAllAttachments -= attachPoint.StateHandler;
                }
                attachPoint.HandleStateChange(AttachmentPointStateType.Released);
                attachmentList.Remove(attachPoint);
            }
            else
            {
                Debug.LogError("On release, IAttachmentPoint isn't AttachmentPoint");
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Release an attachment point for disposal. The attachment point is no longer valid after this call.
        /// </summary>
        /// <remarks>
        /// In the unlikely circumstance that another attachment point has been spawned from this one
        /// but has not yet been processed (is still in the pending queue),
        /// that relationship is broken on release of this one, and when the other attachment point is
        /// finally processed, it will be as if it was created with a null context.
        /// </remarks>
        /// <param name="attachPointIface">The attachment point to release.</param>
        public void ReleaseAttachmentPoint(IAttachmentPoint attachPointIface)
        {
            AttachmentPoint attachPoint = attachPointIface as AttachmentPoint;

            if (attachPoint != null)
            {
                Fragment fragment = EnsureFragment(attachPoint.FragmentId);
                if (fragment != null)
                {
                    // Fragment handles notification.
                    fragment.ReleaseAttachmentPoint(attachPoint);
                }
                else
                {
                    // Notify of the state change to released.
                    attachPoint.HandleStateChange(AttachmentPointStateType.Released);
                    // The list of pending attachments is expected to be small, and release of an attachment
                    // point while there are pending attachments is expected to be rare. So brute force it here.
                    // If the attachment point being released is a target in the pending list, remove it.
                    // If it is the context of another pending target, set that context to null.
                    // Proceed through the list in reverse order, because context fixes will only be found
                    // later in the list than the original, and once the original is found we are done.
                    int pendingCount = pendingAttachments.Count;
                    for (int i = pendingCount - 1; i >= 0; --i)
                    {
                        if (pendingAttachments[i].context == attachPoint)
                        {
                            var p = pendingAttachments[i];
                            p.context             = null;
                            pendingAttachments[i] = p;
                        }
                        else if (pendingAttachments[i].target == attachPoint)
                        {
                            pendingAttachments.RemoveAt(i);
                            break;
                        }
                    }
                }
            }
        }