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; }
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(); } }
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); } }