Skip to content

Commit

Permalink
perf: Optimize interest management
Browse files Browse the repository at this point in the history
  • Loading branch information
paulpach committed Apr 16, 2019
1 parent 92b3e98 commit f1ceb0c
Showing 1 changed file with 31 additions and 44 deletions.
75 changes: 31 additions & 44 deletions Assets/Mirror/Runtime/NetworkIdentity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -812,16 +812,19 @@ internal void AddObserver(NetworkConnection conn)
conn.AddToVisList(this);
}

// Only one thread at a time can use RebuildObservers, so
// we can recycle the temp observer list for all of them
static readonly HashSet<NetworkConnection> newObservers = new HashSet<NetworkConnection>();
static readonly HashSet<NetworkConnection> toRemove = new HashSet<NetworkConnection>();

public void RebuildObservers(bool initialize)
{
if (observers == null)
return;

bool changed = false;
bool result = false;
HashSet<NetworkConnection> oldObservers = new HashSet<NetworkConnection>(observers.Values);
HashSet<NetworkConnection> newObservers = new HashSet<NetworkConnection>();

newObservers.Clear();
// call OnRebuildObservers function in components
foreach (NetworkBehaviour comp in NetworkBehaviours)
{
Expand All @@ -838,58 +841,49 @@ public void RebuildObservers(bool initialize)
}

// if no component implemented OnRebuildObservers, then add all
// connections.
// connections that are ready
if (!result)
{
if (initialize)
foreach (KeyValuePair<int, NetworkConnection> kvp in NetworkServer.connections)
{
foreach (NetworkConnection conn in NetworkServer.connections.Values)
{
if (conn.isReady)
AddObserver(conn);
}

if (NetworkServer.localConnection != null && NetworkServer.localConnection.isReady)
{
AddObserver(NetworkServer.localConnection);
}
if (kvp.Value.isReady)
newObservers.Add(kvp.Value);
}
return;
}

// apply changes from rebuild
foreach (NetworkConnection conn in newObservers)
// special case for host mode
/*if (initialize && NetworkServer.localConnection != null && NetworkServer.localConnection.isReady)
{
if (conn == null)
{
continue;
}
AddObserver(NetworkServer.localConnection);
}*/

if (!conn.isReady)
{
if (LogFilter.Debug) Debug.Log("Observer is not ready for " + gameObject + " " + conn);
// our list is fully built,
// spawn this object for every new observer
foreach (NetworkConnection conn in newObservers)
{
if (conn == null || !conn.isReady)
continue;
}

if (initialize || !oldObservers.Contains(conn))
if (initialize || !observers.ContainsKey(conn.connectionId))
{
// new observer
conn.AddToVisList(this);
if (LogFilter.Debug) Debug.Log("New Observer for " + gameObject + " " + conn);
changed = true;
AddObserver(conn);
}
}

foreach (NetworkConnection conn in oldObservers)
// destroy this object for every observer we no longer have
toRemove.Clear();
foreach (KeyValuePair<int, NetworkConnection> kvp in observers)
{
if (!newObservers.Contains(conn))
if (!kvp.Value.isReady || !newObservers.Contains(kvp.Value))
{
// removed observer
conn.RemoveFromVisList(this, false);
if (LogFilter.Debug) Debug.Log("Removed Observer for " + gameObject + " " + conn);
changed = true;
toRemove.Add(kvp.Value);
}
}
foreach (NetworkConnection conn in toRemove)
{
conn.RemoveFromVisList(this, false);
observers.Remove(conn.connectionId);
}

// special case for local client.
if (initialize)
Expand All @@ -900,13 +894,6 @@ public void RebuildObservers(bool initialize)
}
}

if (changed)
{
observers =
newObservers.
Where(conn => conn.isReady).
ToDictionary(conn => conn.connectionId, conn => conn);
}
}

public bool RemoveClientAuthority(NetworkConnection conn)
Expand Down

0 comments on commit f1ceb0c

Please sign in to comment.