I would solve this by turning each chain into a linked list with each node having a reference to the next node in the chain. So you can find out it a node is connected by following that chain of references until you find a node which is either a hub (then it is connected) or a node which doesn't have a next node (then it is not connected).
That means we have two kinds of nodes, ConnectionHub
and ConnectionNode
which both inherit from an abstract base class Connectable
.
The abstract base class for both would define the method needed to find out if there is a hub connection:
public abstract class Connectable : MonoBehavior {
public abstract bool isConnectedToHub();
}
The regular nodes have a public variable connectedTo
. This variable needs to be assigned to the next Connectable, which can be a hub, another node or nothing if the node is disconnected. If you call the isConnectedToHub()
method on a regular node, it would return false if it isn't connected. If it is connected, it would delegate the response to the next node up the chain:
public class ConnectionNode : Connectable {
public Connectable connectedTo;
public override bool isConnectedToHub() {
if (connectedTo == null) {
return false;
} else {
return connectedTo.isConnectedToHub();
}
}
}
The connection hub has no next node. It would return true
. That result would then get passed down the call chain and back to the original caller:
public class ConnectionHub : Connectable {
public override bool isConnectedToHub() {
return true;
}
}
Alternative solution:
When link changes are relatively rare events but checking if a node is connected happens a lot, then the above solution might get unperformant. Especially if you have very long chains and keep checking different members of the same chain over and over again. It would be better if each node would know whether or not it is connected right now, so you don't need to reevaluate it all the time.
In that case you could also do it the other way around: Nodes don't know their parent, they know their descendant. When a node gets disconnected, then it propagates this status down the chain to set all its descendants to disconnected.
When a node gets a new descendant, then it first disconnects the old descendant as previously described and then passes on its own connection status (connected or not) down the new descendant chain.
public class ConnectionNode : MonoBehaviour {
private ConnectionNode descendant;
private bool isConnectedToHub;
public void DisconnectDescendant() {
if (descendant != null) {
descendant.SetConnected(false);
descentant = null:
}
}
public void ConnectNewDescendant(ConnectionNode newDescendant) {
DisconnectDescendant();
descendant = newDescendant;
descendant.SetConnected(isConnectedToHub);
}
private void SetConnected(bool newConnectionStatus) {
isConnectedToHub = newConnectionStatus;
if (descendant != null) descendant.SetConnected(newConnectionStatus);
}
}
If you want to turn a node into a hub node, you just need to call SetConnected(true)
on that node. That will make all its descendants connected nodes and also cause the node to mark any future descendants it receives as connected.