diff --git a/Cluster.cs b/Cluster.cs index fc8f88f..6bc11aa 100644 --- a/Cluster.cs +++ b/Cluster.cs @@ -7,22 +7,61 @@ using static Unity.Mathematics.math; [System.Serializable] public class Cluster : INucleus { // The ScriptableObject asset from which the runtime object has been created + + [SerializeField] + protected string _name; + public virtual string name { + get => _name; + set => _name = value; + } + public ClusterPrefab storedPrefab; //public ClusterPrefab prefab; - public Cluster() { - } - public Cluster(Cluster parent) { + // public Cluster() { + // } + public Cluster(Cluster parent, ClusterPrefab realPrefab) { + this.storedPrefab = realPrefab; this.parent = parent; + this.parent?.nuclei.Add(this); + + ClonePrefab(); } - public Cluster(ClusterPrefab prefab) { - this.storedPrefab = prefab; + public Cluster(ClusterPrefab realPrefab) { + this.storedPrefab = realPrefab; //this.prefab = prefab.Clone(); - this.name = prefab.name; + this.name = realPrefab.name; this.cluster = null; if (this.cluster != null) this.cluster.nuclei.Add(this); + + ClonePrefab(); + // IReceptor[] nucleiArray = this.storedPrefab.nuclei.ToArray(); + // // first clone the nuclei without their connections + // foreach (IReceptor nucleus in this.storedPrefab.nuclei) + // nucleus.ShallowCloneTo(this); + // IReceptor[] clonedNuclei = this.nuclei.ToArray(); + + // // Now clone the connections + // for (int nucleusIx = 0; nucleusIx < nucleiArray.Length; nucleusIx++) { + // //IReceptor receptor = nucleiArray[nucleusIx]; + // IReceptor clonedReceptor = clonedNuclei[nucleusIx]; + // if (clonedReceptor == null) + // continue; + + // // Copy the receivers, which will also create the synapses + // foreach (INucleus receiver in nucleiArray[nucleusIx].receivers) { + // int ix = GetNucleusIndex(nucleiArray, receiver); + // if (ix < 0) + // continue; + + // if (clonedNuclei[ix] is not INucleus clonedReceiver) + // continue; + + // clonedReceptor.AddReceiver(clonedReceiver); + // } + // } } public Cluster(ClusterPrefab parent, ClusterPrefab realPrefab) { @@ -32,6 +71,61 @@ public class Cluster : INucleus { this.cluster = parent; if (this.cluster != null) this.cluster.nuclei.Add(this); + + ClonePrefab(); + // IReceptor[] nucleiArray = this.storedPrefab.nuclei.ToArray(); + // // first clone the nuclei without their connections + // foreach (IReceptor nucleus in this.storedPrefab.nuclei) + // nucleus.ShallowCloneTo(this); + // IReceptor[] clonedNuclei = this.nuclei.ToArray(); + + // // Now clone the connections + // for (int nucleusIx = 0; nucleusIx < nucleiArray.Length; nucleusIx++) { + // IReceptor receptor = nucleiArray[nucleusIx]; + // IReceptor clonedReceptor = clonedNuclei[nucleusIx]; + // if (clonedReceptor == null) + // continue; + + // // Copy the receivers, which will also create the synapses + // foreach (INucleus receiver in nucleiArray[nucleusIx].receivers) { + // int ix = GetNucleusIndex(nucleiArray, receiver); + // if (ix < 0) + // continue; + + // if (clonedNuclei[ix] is not INucleus clonedReceiver) + // continue; + + // clonedReceptor.AddReceiver(clonedReceiver); + // } + // } + } + + private void ClonePrefab() { + IReceptor[] nucleiArray = this.storedPrefab.nuclei.ToArray(); + // first clone the nuclei without their connections + foreach (IReceptor nucleus in this.storedPrefab.nuclei) + nucleus.ShallowCloneTo(this); + IReceptor[] clonedNuclei = this.nuclei.ToArray(); + + // Now clone the connections + for (int nucleusIx = 0; nucleusIx < nucleiArray.Length; nucleusIx++) { + IReceptor receptor = nucleiArray[nucleusIx]; + IReceptor clonedReceptor = clonedNuclei[nucleusIx]; + if (clonedReceptor == null) + continue; + + // Copy the receivers, which will also create the synapses + foreach (INucleus receiver in nucleiArray[nucleusIx].receivers) { + int ix = GetNucleusIndex(nucleiArray, receiver); + if (ix < 0) + continue; + + if (clonedNuclei[ix] is not INucleus clonedReceiver) + continue; + + clonedReceptor.AddReceiver(clonedReceiver); + } + } } public virtual IReceptor Clone() { @@ -55,7 +149,9 @@ public class Cluster : INucleus { // } public IReceptor ShallowCloneTo(Cluster parent) { - Cluster clone = new(parent); + Cluster clone = new(parent, this.storedPrefab) { + name = this.name, + }; return clone; } @@ -65,55 +161,55 @@ public class Cluster : INucleus { // } // Deep clone a nucleus with its connections - public virtual Cluster InstantiatePrefab(ClusterPrefab prefab) { - Cluster clone = new Cluster { - nuclei = new() - }; + // public virtual Cluster InstantiatePrefab(ClusterPrefab prefab) { + // Cluster clone = new Cluster { + // nuclei = new() + // }; - IReceptor[] nucleiArray = this.nuclei.ToArray(); - // first clone the nuclei without their connections - foreach (IReceptor nucleus in this.nuclei) - nucleus.ShallowCloneTo(clone); - IReceptor[] clonedNuclei = clone.nuclei.ToArray(); + // IReceptor[] nucleiArray = this.nuclei.ToArray(); + // // first clone the nuclei without their connections + // foreach (IReceptor nucleus in this.nuclei) + // nucleus.ShallowCloneTo(clone); + // IReceptor[] clonedNuclei = clone.nuclei.ToArray(); - // Now clone the connections - for (int nucleusIx = 0; nucleusIx < nucleiArray.Length; nucleusIx++) { - IReceptor receptor = nucleiArray[nucleusIx]; - IReceptor clonedReceptor = clonedNuclei[nucleusIx]; - if (clonedReceptor == null) - continue; + // // Now clone the connections + // for (int nucleusIx = 0; nucleusIx < nucleiArray.Length; nucleusIx++) { + // IReceptor receptor = nucleiArray[nucleusIx]; + // IReceptor clonedReceptor = clonedNuclei[nucleusIx]; + // if (clonedReceptor == null) + // continue; - // Copy the synapses - if (receptor is INucleus nucleus) { - foreach (Synapse synapse in nucleus.synapses) { - if (clonedReceptor is not INucleus clonedNucleus) - continue; + // // Copy the synapses + // if (receptor is INucleus nucleus) { + // foreach (Synapse synapse in nucleus.synapses) { + // if (clonedReceptor is not INucleus clonedNucleus) + // continue; - int ix = GetNucleusIndex(nucleiArray, synapse.nucleus); - if (ix < 0) - continue; - IReceptor clonedSynapseNucleus = clonedNuclei[ix]; - if (clonedSynapseNucleus == null) - continue; + // int ix = GetNucleusIndex(nucleiArray, synapse.nucleus); + // if (ix < 0) + // continue; + // IReceptor clonedSynapseNucleus = clonedNuclei[ix]; + // if (clonedSynapseNucleus == null) + // continue; - clonedNucleus.AddSynapse(clonedSynapseNucleus, synapse.weight); - } - } - // Copy the receivers - foreach (INucleus receiver in nucleiArray[nucleusIx].receivers) { - int ix = GetNucleusIndex(nucleiArray, receiver); - if (ix < 0) - continue; + // clonedNucleus.AddSynapse(clonedSynapseNucleus, synapse.weight); + // } + // } + // // Copy the receivers + // foreach (INucleus receiver in nucleiArray[nucleusIx].receivers) { + // int ix = GetNucleusIndex(nucleiArray, receiver); + // if (ix < 0) + // continue; - if (clonedNuclei[ix] is not INucleus clonedReceiver) - continue; + // if (clonedNuclei[ix] is not INucleus clonedReceiver) + // continue; - clonedReceptor.AddReceiver(clonedReceiver); - } - } + // clonedReceptor.AddReceiver(clonedReceiver); + // } + // } - return clone; - } + // return clone; + // } private int GetNucleusIndex(IReceptor[] nucleiArray, IReceptor nucleus) { for (int i = 0; i < nucleiArray.Length; i++) { @@ -129,13 +225,6 @@ public class Cluster : INucleus { [SerializeReference] public List nuclei = new(); - [SerializeField] - protected string _name; - public virtual string name { - get => _name; - set => _name = value; - } - public List _inputs = null; public virtual List inputs { get { @@ -154,7 +243,13 @@ public class Cluster : INucleus { } //public INucleus output => prefab.output; - public virtual INucleus output => this.nuclei[0] as INucleus; + public virtual INucleus output {//=> this.nuclei[0] as INucleus; + get { + if (this.nuclei.Count > 0) + return this.nuclei[0] as INucleus; + return null; + } + } // Not sure if this belongs here... [SerializeReference] diff --git a/Neuron.cs b/Neuron.cs index 26443d0..9c153ef 100644 --- a/Neuron.cs +++ b/Neuron.cs @@ -169,9 +169,7 @@ public class Neuron : INucleus { public Neuron(Cluster parent, string name) { this.parent = parent; this.name = name; - if (this.cluster != null) { - this.cluster.nuclei.Add(this); - } + this.parent?.nuclei.Add(this); } public Neuron(ClusterPrefab parent, string name) { this.cluster = parent; diff --git a/Receptor.cs b/Receptor.cs index 8d9c81e..0baec36 100644 --- a/Receptor.cs +++ b/Receptor.cs @@ -4,7 +4,6 @@ using UnityEngine; using Unity.Mathematics; using static Unity.Mathematics.math; -[Serializable] public class Receptor : IReceptor { private ClusterPrefab cluster; @@ -141,7 +140,9 @@ public class Receptor : IReceptor { public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector, string thingName = null) { this.localPosition = newLocalPositionVector; - + if (this._receivers == null) + return; + thingIds ??= new int[this._receivers.Count]; int receiverIx = 0; diff --git a/VisualEditor/Editor/ClusterInspector.cs b/VisualEditor/Editor/ClusterInspector.cs index 6e2022a..a8c2922 100644 --- a/VisualEditor/Editor/ClusterInspector.cs +++ b/VisualEditor/Editor/ClusterInspector.cs @@ -623,6 +623,9 @@ public class ClusterInspector : Editor { private void OnClusterPicked(INucleus nucleus, ClusterPrefab prefab) { Cluster subclusterInstance = new(this.cluster, prefab); subclusterInstance.AddReceiver(nucleus); + // This does not work somehow + // this.currentNucleus = subclusterInstance; + // BuildLayers(); } private void EditCluster(Cluster subCluster) { diff --git a/VisualEditor/NanoBrainComponent.cs b/VisualEditor/NanoBrainComponent.cs index 5ed427f..d32c4ce 100644 --- a/VisualEditor/NanoBrainComponent.cs +++ b/VisualEditor/NanoBrainComponent.cs @@ -1,11 +1,11 @@ +using System; using UnityEngine; public class NanoBrainComponent : MonoBehaviour { - [SerializeField] public ClusterPrefab defaultBrain; + + [NonSerialized] private Cluster brainInstance; - - //public INucleus root => brainInstance.output; public Cluster brain { get { if (brainInstance == null && defaultBrain != null) {