示例#1
0
 /// <summary>
 /// Enqueues commands to be processed FIRST on the next physics spin
 /// This ensures that commands that were blocked and delayed for a specific
 /// object run first before other commands that may have gotten in just after 
 /// the delay was released
 /// </summary>
 /// <param name="cmd"></param>
 private void EnqueueFreedCommand(Commands.ICommand cmd)
 {
     _freedCommands.Enqueue(cmd);
 }
示例#2
0
 public void QueueCommand(Commands.ICommand command)
 {
     _currentCommandQueue.Enqueue(command);
     _timingSignal.Set();
 }
示例#3
0
 internal void BeginDelayCommands(PhysxPrim prim, Commands.ICommand initiator)
 {
     DelayedCommandInfo info = new DelayedCommandInfo { Commands = new LinkedList<Commands.ICommand>(), Initiator = initiator };
     _delayedCommands.Add(prim, info);
 }
示例#4
0
        private bool HasSameTargets(Commands.ICommand cmd1, Commands.ICommand cmd2)
        {
            if (cmd1.AffectsMultiplePrims() != cmd2.AffectsMultiplePrims())
            {
                m_log.ErrorFormat("[InWorldz.PhysxPhysics] Asked to check command targets for different command types!");
                return false;
            }

            if (cmd1.AffectsMultiplePrims())
            {
                IEnumerator<PhysxPrim> cmd1prims = ((Commands.IMultiPrimCommand)cmd1).GetTargetPrims().GetEnumerator();
                IEnumerator<PhysxPrim> cmd2prims = ((Commands.IMultiPrimCommand)cmd2).GetTargetPrims().GetEnumerator();

                bool cmd1end = false;
                bool cmd2end = false;

                while (true)
                {
                    cmd1end = cmd1prims.MoveNext();
                    cmd2end = cmd2prims.MoveNext();

                    if (cmd1end || cmd2end) break;

                    if (cmd1prims.Current != cmd2prims.Current) return false;
                }

                return cmd1end == cmd2end;
            }
            else
            {
                return cmd1.GetTargetPrim() == cmd2.GetTargetPrim();
            }
        }
示例#5
0
        private bool CheckAddDelay(Commands.ICommand cmd, PhysxPrim target)
        {
            DelayedCommandInfo delayInfo;
            if (_delayedCommands.TryGetValue(target, out delayInfo) && delayInfo.Initiator != cmd)
            {
                //if we're already the last delayed command delayed behind the other command
                //for the given prim, we only need to be added once per command so we can safely
                //just return
                if (delayInfo.Commands.Count > 0 && delayInfo.Commands.Last.Value == cmd)
                {
                    return true;
                }

                //before adding this new command to wait, check to see if it is cullable.
                //if the command is cullable, and has the same targets, we replace it with this command
                //maintaining its position in the queue
                LinkedListNode<Commands.ICommand> cmdNode;
                if (cmd.IsCullable
                    && delayInfo.TopCullables != null && delayInfo.TopCullables.TryGetValue(cmd.GetType(), out cmdNode)
                    && HasSameTargets(cmdNode.Value, cmd))
                {
                    cmdNode.Value = cmd;
                    if (cmd.AffectsMultiplePrims()) ((Commands.IMultiPrimCommand)cmd).AddDelay();

                    return true;
                }
                else
                {
                    cmdNode = delayInfo.Commands.AddLast(cmd);
                    if (cmd.AffectsMultiplePrims()) ((Commands.IMultiPrimCommand)cmd).AddDelay();

                    if (cmd.IsCullable)
                    {
                        if (delayInfo.TopCullables == null)
                        {
                            delayInfo.TopCullables = new Dictionary<Type, LinkedListNode<Commands.ICommand>>();
                        }

                        delayInfo.TopCullables.Add(cmd.GetType(), cmdNode);
                    }

                    return true;
                }
            }

            return false;
        }
示例#6
0
        private bool CheckDelayedCommand(Commands.ICommand cmd)
        {
            if (cmd.AffectsMultiplePrims())
            {
                bool delay = false;

                Commands.IMultiPrimCommand mpCommand = (Commands.IMultiPrimCommand)cmd;

                IEnumerable<PhysxPrim> targets = mpCommand.GetTargetPrims();
                foreach (PhysxPrim target in targets)
                {
                    delay |= CheckAddDelay(cmd, target);
                }

                //if (delay) m_log.DebugFormat("[InWorldz.PhysX] Delaying physics command pending command completion");
                return delay;
            }
            else
            {
                PhysxPrim target = cmd.GetTargetPrim();
                if (target == null)
                {
                    return false;
                }

                return CheckAddDelay(cmd, target);
            }
        }
示例#7
0
 private void DelayOrExecuteCommand(Commands.ICommand cmd)
 {
     if (!this.CheckDelayedCommand(cmd))
     {
         //Util.DebugOut(cmd.ToString());
         cmd.Execute(this);
     }
 }
示例#8
0
 /// <summary>
 /// Begins delaying commands for this actor and all of its child prims. This
 /// command should be used whenever the state of this entire object is changing
 /// in a way that may be incompatible with future and pending commands
 /// </summary>
 /// <param name="initiator"></param>
 internal void BeginDelayCommands(Commands.ICommand initiator)
 {
     _scene.BeginDelayCommands(this, initiator);
     foreach (PhysxPrim prim in _childShapes.Keys)
     {
         _childPrimsDelayedByMe.Add(prim);
         _scene.BeginDelayCommands(prim, initiator);
     }
 }