///<summary> /// Removes a simulation island connection from the manager. ///</summary> ///<param name="connection">Connection to remove from the manager.</param> ///<exception cref="ArgumentException">Thrown if the connection does not belong to this manager.</exception> public void Remove(SimulationIslandConnection connection) { if (connection.DeactivationManager == this) { connection.DeactivationManager = null; //TODO: Should it remove here, or in the deferred final case? probably here, since otherwise Add-Remove-Add would throw an exception! //Try to split by examining the connections and breadth-first searching outward. //If it is determined that a split is required, grab a new island and add it. //This is a little tricky because it's a theoretically N-way split. //For two members which have the same simulation island (they will initially), try to split. //debugConnections.Remove(connection); connection.SlatedForRemoval = true; //Don't immediately do the removal. //Defer them! splitAttempts.Enqueue(connection); //connection.RemoveReferencesFromConnectedMembers(); //for (int i = 0; i < connection.members.count; i++) //{ // for (int j = i + 1; j < connection.members.count; j++) // { // //Notice that the splits are not performed immediately! They are deferred and spread over multiple frames. // //Split operations aren't cheap, and overdoing them can lead to pointless re-merging and re-splitting. // splitAttempts.Enqueue(new SplitAttempt() { a = connection.members.Elements[i], b = connection.members.Elements[j] }); // //TryToSplit(connection.ConnectedMembers[i], connection.ConnectedMembers[j]); // } //} } else { throw new ArgumentException("Cannot remove connection from activity manager; it is owned by a different or no activity manager."); } }
///<summary> /// Removes a connection reference from the member. ///</summary> ///<param name="connection">Reference to remove.</param> ///<param name="index">Index of the connection in this member's list</param> internal void RemoveConnectionReference(SimulationIslandConnection connection, int index) { if (connections.count > index) { connections.FastRemoveAt(index); if (connections.count > index) { connections.Elements[index].SetListIndex(this, index); } } }
///<summary> /// Removes a simulation island connection from the manager. ///</summary> ///<param name="connection">Connection to remove from the manager.</param> ///<exception cref="ArgumentException">Thrown if the connection does not belong to this manager.</exception> public void Remove(SimulationIslandConnection connection) { if (connection.DeactivationManager == this) { connection.DeactivationManager = null; connection.SlatedForRemoval = true; //Don't immediately do simulation island management. //Defer the splits! splitAttempts.Enqueue(connection); } else { throw new ArgumentException("Cannot remove connection from activity manager; it is owned by a different or no activity manager."); } }
///<summary> /// Adds a simulation island connection to the deactivation manager. ///</summary> ///<param name="connection">Connection to add.</param> ///<exception cref="ArgumentException">Thrown if the connection already belongs to a manager.</exception> public void Add(SimulationIslandConnection connection) { //DO A MERGE IF NECESSARY if (connection.DeactivationManager == null) { bool taken = false; addLocker.Enter(ref taken); //addLocker.Enter(); connection.DeactivationManager = this; if (connection.entries.Count > 0) { var island = connection.entries.Elements[0].Member.SimulationIsland; for (int i = 1; i < connection.entries.Count; i++) { SimulationIsland opposingIsland; if (island != (opposingIsland = connection.entries.Elements[i].Member.SimulationIsland)) { //Need to do a merge between the two islands. //Note that this merge may eliminate the need for a merge with subsequent connection if they belong to the same island. island = Merge(island, opposingIsland); } } //If it was slated for removal, that means the flush stage will try to split it. //Since it was just added back, splitting is known to be pointless. //Just set the flag and the flush will ignore the split attempt. if (connection.SlatedForRemoval) { connection.SlatedForRemoval = false; } else { //If the connection was NOT slated for removal, that means the reference don't currently exist. //(If the connection was slated for removal, that would imply the connection existed previously, so it must have had references.) connection.AddReferencesToConnectedMembers(); } } addLocker.Exit(); } else { throw new ArgumentException("Cannot add connection to deactivation manager; it already belongs to one."); } }
///<summary> /// Adds a simulation island connection to the deactivation manager. ///</summary> ///<param name="connection">Connection to add.</param> ///<exception cref="ArgumentException">Thrown if the connection already belongs to a manager.</exception> public void Add(SimulationIslandConnection connection) { //DO A MERGE IF NECESSARY if (connection.DeactivationManager == null) { connection.DeactivationManager = this; if (connection.entries.Count > 0) { var island = connection.entries.Elements[0].Member.SimulationIsland; for (int i = 1; i < connection.entries.Count; i++) { SimulationIsland opposingIsland; if (island != (opposingIsland = connection.entries.Elements[i].Member.SimulationIsland)) { //Need to do a merge between the two islands. //Note that this merge may eliminate the need for a merge with subsequent connection if they belong to the same island. island = Merge(island, opposingIsland); } } if (connection.SlatedForRemoval) { connection.SlatedForRemoval = false; //If it was slated for removal, that means connections are still present. Just set the flag and the removal system will ignore the removal order. } else { connection.AddReferencesToConnectedMembers(); } //debugConnections.Add(connection); } } else { throw new ArgumentException("Cannot add connection to deactivation manager; it already belongs to one."); } }
/// <summary> /// Returns a resource to the pool. /// </summary> /// <param name="connection">Connection to return.</param> public static void GiveBack(SimulationIslandConnection connection) { if (SimulationIslandConnections == null) SimulationIslandConnections = new UnsafeResourcePool<SimulationIslandConnection>(); connection.CleanUp(); SimulationIslandConnections.GiveBack(connection); }
///<summary> /// Adds a simulation island connection to the deactivation manager. ///</summary> ///<param name="connection">Connection to add.</param> ///<exception cref="ArgumentException">Thrown if the connection already belongs to a manager.</exception> public void Add(SimulationIslandConnection connection) { //DO A MERGE IF NECESSARY if (connection.DeactivationManager == null) { addLocker.Enter(); connection.DeactivationManager = this; if (connection.entries.Count > 0) { var island = connection.entries.Elements[0].Member.SimulationIsland; for (int i = 1; i < connection.entries.Count; i++) { SimulationIsland opposingIsland; if (island != (opposingIsland = connection.entries.Elements[i].Member.SimulationIsland)) { //Need to do a merge between the two islands. //Note that this merge may eliminate the need for a merge with subsequent connection if they belong to the same island. island = Merge(island, opposingIsland); } } //If it was slated for removal, that means the flush stage will try to split it. //Since it was just added back, splitting is known to be pointless. //Just set the flag and the flush will ignore the split attempt. if (connection.SlatedForRemoval) connection.SlatedForRemoval = false; else { //If the connection was NOT slated for removal, that means the reference don't currently exist. //(If the connection was slated for removal, that would imply the connection existed previously, so it must have had references.) connection.AddReferencesToConnectedMembers(); } } addLocker.Exit(); } else { throw new ArgumentException("Cannot add connection to deactivation manager; it already belongs to one."); } }
/// <summary> /// Returns a resource to the pool. /// </summary> /// <param name="connection">Connection to return.</param> public static void GiveBack(SimulationIslandConnection connection) { connection.CleanUp(); SimulationIslandConnections.GiveBack(connection); }
///<summary> /// Adds a connection reference to the member. ///</summary> ///<param name="connection">Reference to add.</param> internal void AddConnectionReference(SimulationIslandConnection connection) { connections.Add(connection); }
///<summary> /// Adds a simulation island connection to the deactivation manager. ///</summary> ///<param name="connection">Connection to add.</param> ///<exception cref="ArgumentException">Thrown if the connection already belongs to a manager.</exception> public void Add(SimulationIslandConnection connection) { //DO A MERGE IF NECESSARY if (connection.DeactivationManager == null) { connection.DeactivationManager = this; if (connection.entries.Count > 0) { var island = connection.entries.Elements[0].Member.SimulationIsland; for (int i = 1; i < connection.entries.Count; i++) { SimulationIsland opposingIsland; if (island != (opposingIsland = connection.entries.Elements[i].Member.SimulationIsland)) { //Need to do a merge between the two islands. //Note that this merge may eliminate the need for a merge with subsequent connection if they belong to the same island. island = Merge(island, opposingIsland); } } if (connection.SlatedForRemoval) connection.SlatedForRemoval = false; //If it was slated for removal, that means connections are still present. Just set the flag and the removal system will ignore the removal order. else connection.AddReferencesToConnectedMembers(); //debugConnections.Add(connection); } } else { throw new ArgumentException("Cannot add connection to deactivation manager; it already belongs to one."); } }
///<summary> /// Adds a connection reference to the member. ///</summary> ///<param name="connection">Reference to add.</param> ///<returns>Index of the connection in the member's list.</returns> internal int AddConnectionReference(SimulationIslandConnection connection) { connections.Add(connection); return(connections.count - 1); }
///<summary> /// Removes a connection reference from the member. ///</summary> ///<param name="connection">Reference to remove.</param> internal void RemoveConnectionReference(SimulationIslandConnection connection) { connections.FastRemove(connection); }
///<summary> /// Removes a connection reference from the member. ///</summary> ///<param name="connection">Reference to remove.</param> ///<param name="index">Index of the connection in this member's list</param> internal void RemoveConnectionReference(SimulationIslandConnection connection, int index) { if (connections.Count > index) { connections.FastRemoveAt(index); if (connections.Count > index) connections.Elements[index].SetListIndex(this, index); } }
///<summary> /// Adds a connection reference to the member. ///</summary> ///<param name="connection">Reference to add.</param> ///<returns>Index of the connection in the member's list.</returns> internal int AddConnectionReference(SimulationIslandConnection connection) { connections.Add(connection); return connections.Count - 1; }