diff --git a/Cluster.cs b/Cluster.cs index f922bc8..f81d190 100644 --- a/Cluster.cs +++ b/Cluster.cs @@ -202,9 +202,6 @@ public class Cluster : Nucleus { name = this.name, clusterPrefab = this.clusterPrefab, }; - // This cloned the prefab with the clusternuclei, - // but did not clone the receivers outside the cluster - RestoreExternalReceivers(clone, this.clusterPrefab, parent); return clone; } @@ -219,8 +216,7 @@ public class Cluster : Nucleus { if (sourceNucleus is not Neuron sourceNeuron) continue; - Nucleus clonedNucleus = clonedCluster.clusterNuclei[nucleusIx]; - if (clonedNucleus is not Neuron clonedNeuron) + if (clonedCluster.clusterNuclei[nucleusIx] is not Neuron clonedNeuron) continue; // copy the receivers (and thus synapses) from the source to the clone @@ -242,46 +238,10 @@ public class Cluster : Nucleus { } clonedNeuron.AddReceiver(clonedReceiver, weight); + // Debug.Log($"external: {clonedReceiver.name} receives from {clonedNeuron.name} {clonedNeuron.GetHashCode()}"); } } } - protected void RestoreExternalReceivers(Cluster clone, ClusterPrefab prefabParent, Cluster clonedParent) { - // Loop over all nuclei of this (the prefab of the clone?) - for (int nucleusIx = 0; nucleusIx < this.clusterNuclei.Count; nucleusIx++) { - Nucleus prefabNucleus = this.clusterNuclei[nucleusIx]; - if (prefabNucleus is not Neuron prefabNeuron) - continue; - - Nucleus clonedNucleus = clone.clusterNuclei[nucleusIx]; - if (clonedNucleus == null || clonedNucleus is not Neuron clonedNeuron) - continue; - - // Copy the receivers, which will also create the synapses - foreach (Nucleus receiver in prefabNeuron.receivers) { - int ix = GetNucleusIndex(prefabParent.nuclei, receiver); - if (ix < 0 || ix >= clonedParent.clusterNuclei.Count) - continue; - - //if (clone.clusterNuclei[ix] is not Nucleus clonedReceiver) - if (clonedParent.clusterNuclei[ix] is not Nucleus clonedReceiver) - continue; - - // Find the synapse for the weight - float weight = 1; - foreach (Synapse synapse in receiver.synapses) { - // Find the weight for this synapse - if (synapse.nucleus == prefabNucleus) { - weight = synapse.weight; - break; - } - } - - clonedNeuron.AddReceiver(clonedReceiver, weight); - } - } - - - } protected int GetNucleusIndex(Nucleus[] nuclei, Nucleus nucleus) { for (int i = 0; i < nuclei.Length; i++) { @@ -505,21 +465,14 @@ public class Cluster : Nucleus { foreach (Nucleus nucleus in computeOrder) { nucleus.UpdateStateIsolated(); if (startNucleus.trace) - Debug.Log($" {nucleus.name} = {nucleus.outputValue}"); + Debug.Log($" {nucleus.name}[{nucleus.GetHashCode()}] = {nucleus.outputValue}"); } this.outputValue = this.defaultOutput.outputValue; this.stale = 0; - if (this.parent != null) { - // continue in parent - this.parent.UpdateFromNucleus(this); - // continue in parent with the receivers of the last nucleus in the compute order - // if (computeOrder.Last() is Neuron lastNeuron) { - // foreach (Nucleus receiver in lastNeuron.receivers) - // this.parent?.UpdateFromNucleus(this); - // } - } + // continue in parent + this.parent?.UpdateFromNucleus(this); UpdateNuclei(); } diff --git a/ClusterReceptor.cs b/ClusterReceptor.cs index 33cba20..d6fd3bf 100644 --- a/ClusterReceptor.cs +++ b/ClusterReceptor.cs @@ -113,15 +113,19 @@ public class ClusterReceptor : Cluster, IReceptor { } public override void UpdateStateIsolated() { - float3 sum = this.bias; + // Clusters don't do anything, + // The nuclei in them do the work + // and should be called directly, not from the cluster + + // float3 sum = this.bias; - foreach (Nucleus nucleus in this.sortedNuclei) - nucleus.UpdateStateIsolated(); + // foreach (Nucleus nucleus in this.sortedNuclei) + // nucleus.UpdateStateIsolated(); - this.outputValue = this.defaultOutput.outputValue; - this.stale = 0; + // this.outputValue = this.defaultOutput.outputValue; + // this.stale = 0; - UpdateNuclei(); + // UpdateNuclei(); } public override void UpdateNuclei() { @@ -143,6 +147,8 @@ public class ClusterReceptor : Cluster, IReceptor { private Dictionary thingReceivers = new(); public virtual void ProcessStimulus(Neuron input, Vector3 inputValue, int thingId = 0, string thingName = null) { + CleanupReceivers(); + inputValue = input.Activator(inputValue); if (!thingReceivers.TryGetValue(thingId, out ClusterReceptor selectedReceiver)) @@ -208,4 +214,24 @@ public class ClusterReceptor : Cluster, IReceptor { } return selectedReceiver; } + + + private void CleanupReceivers() { + // Remove a thing-receiver connection when the nucleus is inactive + List receiversToRemove = new(); + foreach (KeyValuePair item in thingReceivers) { + if (item.Value != null && item.Value.isSleeping) + receiversToRemove.Add(item.Key); + } + foreach (int thingId in receiversToRemove) { + Nucleus selectedReceiver = thingReceivers[thingId]; + + thingReceivers.Remove(thingId); + + int colonPos = selectedReceiver.name.IndexOf(":"); + if (colonPos > 0) + selectedReceiver.name = selectedReceiver.name[..colonPos]; + + } + } } \ No newline at end of file diff --git a/Editor/ClusterInspector.cs b/Editor/ClusterInspector.cs index d35acff..572b092 100644 --- a/Editor/ClusterInspector.cs +++ b/Editor/ClusterInspector.cs @@ -507,7 +507,7 @@ public class ClusterInspector : Editor { // Draw Cluster ring if (nucleus is Cluster) { Handles.color = Color.white; - Handles.DrawWireDisc(position, Vector3.forward, size + 10); + Handles.DrawWireDisc(position, Vector3.forward, size + 5); } // Tooltip