Example #1
0
        /// <summary>
        /// Teleport (as opposed to Move) means that the object is meant to have disappeared at its old position
        /// and instantaneously reappeared at its new position in frozen space without traversing the space in between.
        /// </summary>
        /// <remarks>
        /// This is equivalent to releasing the existing attachment point and creating a new one,
        /// except in that the attachment point reference remains valid.
        /// See <see cref="WorldLockingManager.TeleportAttachmentPoint"/>.
        /// </remarks>
        /// <param name="attachPointIface">The attachment point to teleport</param>
        /// <param name="newFrozenPosition">The position to teleport to.</param>
        /// <param name="context">The optional context.</param>
        public void TeleportAttachmentPoint(IAttachmentPoint attachPointIface, Vector3 newFrozenPosition, IAttachmentPoint context)
        {
            AttachmentPoint attachPoint = attachPointIface as AttachmentPoint;

            if (attachPoint != null)
            {
                attachPoint.ObjectPosition = newFrozenPosition;

                // Save the fragment it's currently in, in case it changes here.
                FragmentId oldFragmentId = attachPoint.FragmentId;

                // If it's not in a valid fragment, it is still pending and will get processed when the system is ready.
                if (oldFragmentId.IsKnown())
                {
                    FragmentId newFragmentId = GetTargetFragmentId(context);
                    // If there is a valid current fragment,
                    if (newFragmentId.IsKnown())
                    {
                        // Fill it in with a new one.
                        SetupAttachmentPoint(plugin, attachPoint, context);

                        if (attachPoint.FragmentId != oldFragmentId)
                        {
                            ChangeAttachmentPointFragment(oldFragmentId, attachPoint);
                        }
                    }
                    else
                    {
                        AddPendingAttachmentPoint(attachPoint, context);
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// If conditions have changed to allow finalizing creation of any pending attachment points,
        /// do it now.
        /// </summary>
        private void ProcessPendingAttachmentPoints()
        {
            if (CurrentFragmentId.IsKnown() && pendingAttachments.Count > 0)
            {
                // We have a valid destination fragment. Note that since this queue is in order of submission,
                // if an attachment point depends on a second attachment point for context,
                // that second will be either earlier in the list (because there was no valid current fragment when it was
                // created) or it will have a valid fragment. So by the time we get to the one with a dependency (pending.context != null),
                // its dependency will have a valid fragment id.
                int pendingCount = pendingAttachments.Count;
                for (int i = 0; i < pendingCount; ++i)
                {
                    AttachmentPoint  target         = pendingAttachments[i].target;
                    Vector3          frozenPosition = pendingAttachments[i].target.ObjectPosition;
                    IAttachmentPoint context        = pendingAttachments[i].context;

                    SetupAttachmentPoint(plugin, target, context);

                    FragmentId fragmentId = CurrentFragmentId;
                    if (context != null)
                    {
                        fragmentId = context.FragmentId;
                    }
                    Debug.Assert(fragmentId.IsKnown(), $"FragmentId {fragmentId.FormatStr()} invalid from {(context != null ? "context" : "head")} in processing pending");
                    Fragment fragment = EnsureFragment(fragmentId);
                    Debug.Assert(fragment != null, "Valid fragmentId but no fragment found");
                    fragment.AddAttachmentPoint(target);
                }
                // All pending must now be in a good home fragment, clear the to-do list.
                pendingAttachments.Clear();
            }
        }
Example #3
0
        /// <summary>
        /// Check existence of fragment with indicated id,
        /// and create it if it doesn't already exist.
        /// </summary>
        /// <param name="id">The fragment id</param>
        private Fragment EnsureFragment(FragmentId id)
        {
            if (!id.IsKnown())
            {
                return(null);
            }

            if (!fragments.ContainsKey(id))
            {
                fragments[id] = new Fragment(id);
            }
            return(fragments[id]);
        }
Example #4
0
        /// <summary>
        /// Create and register a new attachment point.
        /// </summary>
        /// <remarks>
        /// The attachment point itself is a fairly opaque handle. Its effects are propagated to the client via the
        /// two handlers associated with it.
        /// The optional context attachment point provides an optional contextual hint to where in the anchor
        /// graph to bind the new attachment point.
        /// See <see cref="IAttachmentPointManager.CreateAttachmentPoint"/>.
        /// </remarks>
        /// <param name="frozenPosition">The position in the frozen space at which to start the attachment point</param>
        /// <param name="context">The optional context into which to create the attachment point (may be null)</param>
        /// <param name="locationHandler">Delegate to handle WorldLocking system adjustments to position</param>
        /// <param name="stateHandler">Delegate to handle WorldLocking connectivity changes</param>
        /// <returns>The new attachment point interface.</returns>
        public IAttachmentPoint CreateAttachmentPoint(Vector3 frozenPosition, IAttachmentPoint context,
                                                      AdjustLocationDelegate locationHandler, AdjustStateDelegate stateHandler)
        {
            FragmentId      fragmentId  = GetTargetFragmentId(context);
            AttachmentPoint attachPoint = new AttachmentPoint(locationHandler, stateHandler);

            attachPoint.ObjectPosition = frozenPosition;
            if (fragmentId.IsKnown())
            {
                SetupAttachmentPoint(plugin, attachPoint, context);

                Fragment fragment = EnsureFragment(fragmentId);
                Debug.Assert(fragment != null, "Valid fragmentId but no fragment found");
                fragment.AddAttachmentPoint(attachPoint);
            }
            else
            {
                AddPendingAttachmentPoint(attachPoint, context);
            }
            return(attachPoint);
        }