WIP cluster references/instance
This commit is contained in:
parent
04bab9264f
commit
d583e67e39
@ -7,7 +7,7 @@ using UnityEngine.UIElements;
|
||||
namespace NanoBrain {
|
||||
|
||||
[CustomEditor(typeof(Brain))]
|
||||
public class NanoBrainComponent_Editor : Editor {
|
||||
public class Brain_Editor : Editor {
|
||||
protected static VisualElement mainContainer;
|
||||
protected static VisualElement inspectorContainer;
|
||||
|
||||
@ -24,7 +24,7 @@ namespace NanoBrain {
|
||||
}
|
||||
|
||||
public override VisualElement CreateInspectorGUI() {
|
||||
Cluster brain = component.brain;
|
||||
Cluster brain = component.InitializeBrain();
|
||||
|
||||
if (Application.isPlaying == false)
|
||||
serializedObject.Update();
|
||||
@ -47,6 +47,7 @@ namespace NanoBrain {
|
||||
root.Add(brainField);
|
||||
//}
|
||||
|
||||
|
||||
if (brain != null)
|
||||
CreateViewer(root, brain.prefab, brain.defaultOutput, component.gameObject);
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ using UnityEngine.UIElements;
|
||||
namespace NanoBrain {
|
||||
|
||||
[CustomEditor(typeof(ClusterPrefab))]
|
||||
public class ClusterInspector : ClusterViewer {
|
||||
public class ClusterEditor : ClusterViewer {
|
||||
|
||||
public override VisualElement CreateInspectorGUI() {
|
||||
ClusterPrefab prefab = target as ClusterPrefab;
|
||||
@ -18,13 +18,13 @@ namespace NanoBrain {
|
||||
serializedObject.Update();
|
||||
|
||||
VisualElement root = new();
|
||||
CreateInspector(root, prefab, prefab.output, null);
|
||||
CreateEditor(root, prefab, prefab.output, null);
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
return root;
|
||||
}
|
||||
|
||||
public GraphView CreateInspector(VisualElement root, ClusterPrefab cluster, Nucleus output, GameObject gameObject) {
|
||||
public GraphView CreateEditor(VisualElement root, ClusterPrefab cluster, Nucleus output, GameObject gameObject) {
|
||||
root.style.paddingLeft = 0;
|
||||
root.style.paddingRight = 0;
|
||||
root.style.paddingTop = 0;
|
||||
@ -42,7 +42,6 @@ namespace NanoBrain {
|
||||
graphContainer.style.width = 300;
|
||||
graphContainer.style.overflow = Overflow.Hidden;
|
||||
|
||||
|
||||
VisualElement inspectorContainer = new() {
|
||||
name = "inspector",
|
||||
style = {
|
||||
@ -57,7 +56,7 @@ namespace NanoBrain {
|
||||
mainContainer.Add(inspectorContainer);
|
||||
root.Add(mainContainer);
|
||||
|
||||
graphContainer.SetGraph(gameObject, output, inspectorContainer, this);
|
||||
graphContainer.SetGraph(gameObject, output, inspectorContainer);
|
||||
|
||||
return graphContainer;
|
||||
}
|
||||
@ -83,11 +82,9 @@ namespace NanoBrain {
|
||||
this.currentNucleus = newOutput;
|
||||
}
|
||||
|
||||
public void SetGraph(GameObject gameObject, Nucleus nucleus, VisualElement inspectorContainer, ClusterInspector editor) {
|
||||
public void SetGraph(GameObject gameObject, Nucleus nucleus, VisualElement inspectorContainer) {
|
||||
this.gameObject = gameObject;
|
||||
this.currentEditor = editor;
|
||||
|
||||
//this.cluster = brain;
|
||||
if (Application.isPlaying == false)
|
||||
this.serializedBrain = new SerializedObject(this.prefab);
|
||||
this.currentNucleus = nucleus;
|
||||
@ -96,7 +93,7 @@ namespace NanoBrain {
|
||||
OnOutputChanged(outputsPopup.choices[0]);
|
||||
}
|
||||
|
||||
void Rebuild(VisualElement inspectorContainer) {
|
||||
private void Rebuild(VisualElement inspectorContainer) {
|
||||
BuildLayers();
|
||||
|
||||
if (this.currentNucleus == null) {
|
||||
@ -121,6 +118,11 @@ namespace NanoBrain {
|
||||
|
||||
// create a SerializedObject wrapper so Unity inspector controls work (and Undo)
|
||||
SerializedObject so = new(prefabAsset);
|
||||
|
||||
foreach (Nucleus nucleus in this.prefab.nuclei) {
|
||||
nucleus.Initialize();
|
||||
}
|
||||
|
||||
this.inspectorIMGUIContainer = new IMGUIContainer(() => InspectorHandler(so));
|
||||
|
||||
inspectorContainer.Add(inspectorIMGUIContainer);
|
||||
@ -257,7 +259,6 @@ namespace NanoBrain {
|
||||
}
|
||||
trace = EditorGUILayout.Toggle("Trace", trace);
|
||||
this.currentNucleus.trace = trace;
|
||||
|
||||
}
|
||||
|
||||
protected void SynapsesInspector(ref bool anythingChanged) {
|
||||
@ -319,19 +320,27 @@ namespace NanoBrain {
|
||||
else {
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
if (synapse.neuron.parent != null && synapse.neuron.parent != this.currentNucleus) {
|
||||
if (synapse.neuron.clusterPrefab != this.currentNucleus.clusterPrefab) {
|
||||
// If it is a cluster
|
||||
GUIStyle labelStyle = new(GUI.skin.label);
|
||||
float labelWidth = 200;
|
||||
if (synapse.neuron.clusterPrefab != null) {
|
||||
labelWidth = labelStyle.CalcSize(new GUIContent($"{synapse.neuron.parent.baseName}.")).x;
|
||||
GUILayout.Label($"{synapse.neuron.parent.baseName}", GUILayout.Width(labelWidth));
|
||||
labelWidth = labelStyle.CalcSize(new GUIContent($"{synapse.neuron.clusterPrefab.name}.")).x;
|
||||
GUILayout.Label($"{synapse.neuron.clusterPrefab.name}", GUILayout.Width(labelWidth));
|
||||
}
|
||||
string[] options = synapse.neuron.parent.clusterNuclei.Select(n => n.name).ToArray();
|
||||
//string[] options = synapse.neuron.parent.clusterNuclei.Select(n => n.name).ToArray();
|
||||
string[] options = synapse.neuron.clusterPrefab.nuclei.Select(n => n.name).ToArray();
|
||||
int selectedIndex = System.Array.IndexOf(options, synapse.neuron.name);
|
||||
int newIndex = EditorGUILayout.Popup(selectedIndex, options);
|
||||
if (newIndex != selectedIndex && synapse.neuron.parent.clusterNuclei[newIndex] is Neuron newNeuron)
|
||||
// if (newIndex != selectedIndex && synapse.neuron.clusterPrefab.nuclei[newIndex] is Neuron newNeuron)
|
||||
// ChangeSynapse(synapse, newNeuron);
|
||||
if (newIndex != selectedIndex) {
|
||||
// It shall be ensured that the parent.clusterNuclei and
|
||||
// clusterPrefab.nuclei contain the same neurons in the same order....
|
||||
Nucleus selectedNucleus = synapse.neuron.parent.clusterNuclei[newIndex];
|
||||
Neuron newNeuron = selectedNucleus as Neuron;
|
||||
ChangeSynapse(synapse, newNeuron);
|
||||
}
|
||||
}
|
||||
else
|
||||
GUILayout.Label(synapse.neuron.name);
|
||||
@ -9,7 +9,6 @@ namespace NanoBrain {
|
||||
|
||||
public class ClusterViewer : Editor {
|
||||
|
||||
//public static ClusterViewer previousEditor;
|
||||
public static ClusterPrefab previousPrefab;
|
||||
|
||||
public class GraphView : VisualElement {
|
||||
@ -29,9 +28,6 @@ namespace NanoBrain {
|
||||
protected IMGUIContainer graphContainer;
|
||||
protected readonly PopupField<string> outputsPopup;
|
||||
|
||||
public ClusterInspector currentEditor;
|
||||
//public ClusterViewer previousEditor;
|
||||
|
||||
public enum Mode {
|
||||
Focus,
|
||||
Full
|
||||
@ -93,8 +89,8 @@ namespace NanoBrain {
|
||||
RegisterCallback<DetachFromPanelEvent>(evt => Unsubscribe());
|
||||
}
|
||||
|
||||
protected virtual void OnModeChange(ChangeEvent<System.Enum> evt) {
|
||||
mode = (Mode)evt.newValue;
|
||||
protected virtual void OnModeChange(ChangeEvent<System.Enum> changeEvent) {
|
||||
this.mode = (Mode)changeEvent.newValue;
|
||||
}
|
||||
|
||||
protected virtual void OnOutputChanged(string outputName) {
|
||||
@ -441,8 +437,6 @@ namespace NanoBrain {
|
||||
}
|
||||
|
||||
private void DrawSynapses(Nucleus nucleus, Vector3 parentPos, float size) {
|
||||
int nodeCount = nucleus.synapses.Count;
|
||||
|
||||
// Determine the maximum value in this layer
|
||||
// This is used to 'scale' the output value colors of the nuclei
|
||||
float maxValue = 0;
|
||||
@ -452,7 +446,7 @@ namespace NanoBrain {
|
||||
if (synapse.neuron == null)
|
||||
continue;
|
||||
|
||||
// Draw multiple synapses to the same neuron only once
|
||||
// Count multiple synapses to the same neuron only once
|
||||
if (drawnNeurons.Contains(synapse.neuron))
|
||||
continue;
|
||||
drawnNeurons.Add(synapse.neuron);
|
||||
@ -474,6 +468,7 @@ namespace NanoBrain {
|
||||
if (synapse.neuron is null)
|
||||
continue;
|
||||
|
||||
// Draw multiple synapses to the same neuron only once
|
||||
if (drawnNeurons.Contains(synapse.neuron))
|
||||
continue;
|
||||
drawnNeurons.Add(synapse.neuron);
|
||||
@ -485,8 +480,7 @@ namespace NanoBrain {
|
||||
if (Application.isPlaying) {
|
||||
if (maxValue == 0 || !float.IsFinite(maxValue))
|
||||
maxValue = 1;
|
||||
float brightness = 0;
|
||||
brightness = synapse.neuron.outputMagnitude * synapse.weight / maxValue;
|
||||
float brightness = synapse.neuron.outputMagnitude * synapse.weight / maxValue;
|
||||
color = new Color(brightness, brightness, brightness, 1f);
|
||||
}
|
||||
DrawNucleus(synapse.neuron, pos, size, color);
|
||||
@ -731,7 +725,7 @@ namespace NanoBrain {
|
||||
Selection.activeObject = subCluster.prefab;
|
||||
EditorGUIUtility.PingObject(subCluster.prefab);
|
||||
ClusterViewer.previousPrefab = this.prefab;
|
||||
ClusterInspector newEditor = CreateEditor(subCluster.prefab) as ClusterInspector;
|
||||
ClusterEditor newEditor = CreateEditor(subCluster.prefab) as ClusterEditor;
|
||||
}
|
||||
|
||||
#endregion Graph
|
||||
|
||||
@ -20,17 +20,24 @@ namespace NanoBrain {
|
||||
/// </summary>
|
||||
public Cluster brain {
|
||||
get {
|
||||
if (brainInstance == null && brainPrefab != null) {
|
||||
brainInstance = new Cluster(brainPrefab) {
|
||||
name = brainPrefab.name
|
||||
};
|
||||
} else if (brainInstance != null && brainPrefab == null) {
|
||||
brainInstance = null;
|
||||
}
|
||||
// if (brainInstance == null && brainPrefab != null) {
|
||||
// brainInstance = new Cluster(brainPrefab) {
|
||||
// name = brainPrefab.name
|
||||
// };
|
||||
// } else if (brainInstance != null && brainPrefab == null) {
|
||||
// brainInstance = null;
|
||||
// }
|
||||
return brainInstance;
|
||||
}
|
||||
}
|
||||
|
||||
public Cluster InitializeBrain() {
|
||||
brainInstance = new Cluster(brainPrefab) {
|
||||
name = brainPrefab.name
|
||||
};
|
||||
return brainInstance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the weight for all Synapses coming from the Neuron with the given name
|
||||
/// </summary>
|
||||
|
||||
@ -17,6 +17,8 @@ namespace NanoBrain {
|
||||
public class Cluster : Nucleus {
|
||||
// It may be that clusters will not be nuclei anymore in the future....
|
||||
|
||||
public ClusterPrefab prefab;
|
||||
|
||||
/// <summary>
|
||||
/// The base name of the cluster. I don't think this is actively used at this moment
|
||||
/// </summary>
|
||||
@ -36,6 +38,12 @@ namespace NanoBrain {
|
||||
public int instanceCount = 1;
|
||||
public Dictionary<int, Cluster> thingClusters = new();
|
||||
|
||||
[SerializeReference]
|
||||
public List<Nucleus> clusterNuclei = new();
|
||||
// the nuclei sorted using topological sorting
|
||||
// to ensure that the cluster is computer in the right order
|
||||
public List<Nucleus> sortedNuclei;
|
||||
|
||||
#region Init
|
||||
|
||||
/// <summary>
|
||||
@ -79,8 +87,9 @@ namespace NanoBrain {
|
||||
/// Where which the clone be found???
|
||||
private void ClonePrefab() {
|
||||
Nucleus[] prefabNuclei = this.prefab.nuclei.ToArray();
|
||||
|
||||
// first clone the nuclei without their connections
|
||||
foreach (Nucleus nucleus in this.prefab.nuclei) {
|
||||
foreach (Nucleus nucleus in prefabNuclei) {
|
||||
nucleus.ShallowCloneTo(this);
|
||||
}
|
||||
Nucleus[] clonedNuclei = this.clusterNuclei.ToArray();
|
||||
@ -95,110 +104,152 @@ namespace NanoBrain {
|
||||
if (clonedNucleus == null || clonedNucleus is not Neuron clonedNeuron)
|
||||
continue;
|
||||
|
||||
// Copy the receivers, which will also create the synapses
|
||||
// Clusters do not have receivers...
|
||||
foreach (Nucleus receiver in prefabNeuron.receivers.ToArray()) {
|
||||
int ix = GetNucleusIndex(prefabNuclei, receiver);
|
||||
if (ix < 0)
|
||||
continue;
|
||||
|
||||
if (clonedNuclei[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.neuron == prefabNucleus) {
|
||||
weight = synapse.weight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
clonedNeuron.AddReceiver(clonedReceiver, weight);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the siblings for clusters
|
||||
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
||||
Nucleus prefabNucleus = prefabNuclei[nucleusIx];
|
||||
if (prefabNucleus is not Cluster prefabCluster)
|
||||
continue;
|
||||
|
||||
if (prefabCluster.siblingClusters == null || prefabCluster.siblingClusters.Length == 0)
|
||||
continue;
|
||||
|
||||
Cluster clonedNucleus = clonedNuclei[nucleusIx] as Cluster;
|
||||
if (prefabCluster == prefabCluster.siblingClusters[0]) {
|
||||
// We clone the array only for the first entry
|
||||
//NucleusArray clonedArray = new(prefabReceptor.nucleiArray.Length);
|
||||
Cluster[] clonedArray = new Cluster[prefabCluster.siblingClusters.Length];
|
||||
int arrayIx = 0;
|
||||
foreach (Cluster prefabArrayNucleus in prefabCluster.siblingClusters) {
|
||||
int arrayNucleusIx = GetNucleusIndex(prefabNuclei, prefabArrayNucleus);
|
||||
if (arrayNucleusIx >= 0) {
|
||||
Cluster clonedArrayNucleus = clonedNuclei[arrayNucleusIx] as Cluster;
|
||||
clonedArray[arrayIx] = clonedArrayNucleus;
|
||||
}
|
||||
else {
|
||||
Debug.LogError($" Could not find prefab nucleus {prefabNucleus.name} in the clones");
|
||||
}
|
||||
arrayIx++;
|
||||
}
|
||||
clonedNucleus.siblingClusters = clonedArray;
|
||||
}
|
||||
else {
|
||||
// The others will refer to the array created for the first nucleus in the array
|
||||
int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabCluster.siblingClusters[0]);
|
||||
Cluster clonedFirstNucleus = clonedNuclei[firstNucleusIx] as Cluster;
|
||||
clonedNucleus.siblingClusters = clonedFirstNucleus.siblingClusters;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect the subclusters
|
||||
List<Cluster> subClusters = new();
|
||||
foreach (Nucleus nucleus in prefabNuclei) {
|
||||
foreach (Synapse synapse in nucleus.synapses) {
|
||||
Nucleus synapseNucleus = synapse.neuron;
|
||||
if (synapseNucleus is not Cluster subCluster)
|
||||
continue;
|
||||
if (subClusters.Contains(subCluster))
|
||||
continue;
|
||||
subClusters.Add(subCluster);
|
||||
}
|
||||
}
|
||||
// Create the subcluster instances
|
||||
foreach (Cluster subCluster in subClusters) {
|
||||
for (int ix = 0; ix < subCluster.instanceCount; ix++) {
|
||||
// create the new instance
|
||||
Cluster clusterInstance = new(subCluster.prefab);
|
||||
// connect it
|
||||
foreach ((Neuron sender, Nucleus receiver) in subCluster.CollectConnections()) {
|
||||
int receiverIx = GetNucleusIndex(prefabNuclei, receiver);
|
||||
if (receiverIx < 0)
|
||||
foreach (Synapse prefabSynapse in prefabNeuron.synapses) {
|
||||
Neuron synapseNeuron = prefabSynapse.neuron;
|
||||
if (synapseNeuron.parent is not null && synapseNeuron.clusterPrefab != this.clusterPrefab) {
|
||||
// Neuron is in another cluster, find the cloned cluster first
|
||||
Cluster prefabCluster = synapseNeuron.parent;
|
||||
int clusterIx = GetNucleusIndex(prefabNuclei, prefabCluster);
|
||||
if (clusterIx < 0)
|
||||
// Could not find the cluster in the prefab
|
||||
continue;
|
||||
if (clonedNuclei[clusterIx] is not Cluster clonedCluster)
|
||||
// Could not find the cloned cluster
|
||||
continue;
|
||||
|
||||
if (clonedNuclei[receiverIx] is not Nucleus clonedReceiver)
|
||||
// Now find the neuron in that cloned cluster
|
||||
int neuronIx = GetNucleusIndex(prefabCluster.prefab.nuclei, prefabSynapse.neuron);
|
||||
if (neuronIx < 0)
|
||||
// Could not find the neuron in the prefab cluster
|
||||
continue;
|
||||
if (clonedCluster.clusterNuclei[neuronIx] is not Neuron clonedSender)
|
||||
// Could not find the neuron in the cloned cluster
|
||||
continue;
|
||||
|
||||
// Find the synapse for the weight
|
||||
float weight = 1;
|
||||
foreach (Synapse synapse in receiver.synapses) {
|
||||
// Find the weight for this synapse
|
||||
if (synapse.neuron == sender) {
|
||||
weight = synapse.weight;
|
||||
break;
|
||||
clonedSender.AddReceiver(clonedNeuron, prefabSynapse.weight);
|
||||
}
|
||||
else {
|
||||
int ix = GetNucleusIndex(prefabNuclei, prefabSynapse.neuron);
|
||||
if (ix < 0)
|
||||
continue;
|
||||
if (clonedNuclei[ix] is not Neuron clonedSender)
|
||||
continue;
|
||||
|
||||
// Copy the receivers which will also create the synapse
|
||||
clonedSender.AddReceiver(clonedNeuron, prefabSynapse.weight);
|
||||
}
|
||||
}
|
||||
|
||||
// // Copy the receivers, which will also create the synapses
|
||||
// foreach (Nucleus receiver in prefabNeuron.receivers.ToArray()) {
|
||||
// int ix = GetNucleusIndex(prefabNuclei, receiver);
|
||||
// if (ix < 0)
|
||||
// continue;
|
||||
|
||||
// if (clonedNuclei[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.neuron == prefabNucleus) {
|
||||
// weight = synapse.weight;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// clonedNeuron.AddReceiver(clonedReceiver, weight);
|
||||
// }
|
||||
}
|
||||
/*
|
||||
// Copy the siblings for clusters
|
||||
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
||||
Nucleus prefabNucleus = prefabNuclei[nucleusIx];
|
||||
if (prefabNucleus is not Cluster prefabCluster)
|
||||
continue;
|
||||
|
||||
if (prefabCluster.siblingClusters == null || prefabCluster.siblingClusters.Length == 0)
|
||||
continue;
|
||||
|
||||
Cluster clonedNucleus = clonedNuclei[nucleusIx] as Cluster;
|
||||
if (prefabCluster == prefabCluster.siblingClusters[0]) {
|
||||
// We clone the array only for the first entry
|
||||
//NucleusArray clonedArray = new(prefabReceptor.nucleiArray.Length);
|
||||
Cluster[] clonedArray = new Cluster[prefabCluster.siblingClusters.Length];
|
||||
int arrayIx = 0;
|
||||
foreach (Cluster prefabArrayNucleus in prefabCluster.siblingClusters) {
|
||||
int arrayNucleusIx = GetNucleusIndex(prefabNuclei, prefabArrayNucleus);
|
||||
if (arrayNucleusIx >= 0) {
|
||||
Cluster clonedArrayNucleus = clonedNuclei[arrayNucleusIx] as Cluster;
|
||||
clonedArray[arrayIx] = clonedArrayNucleus;
|
||||
}
|
||||
else {
|
||||
Debug.LogError($" Could not find prefab nucleus {prefabNucleus.name} in the clones");
|
||||
}
|
||||
arrayIx++;
|
||||
}
|
||||
clonedNucleus.siblingClusters = clonedArray;
|
||||
}
|
||||
else {
|
||||
// The others will refer to the array created for the first nucleus in the array
|
||||
int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabCluster.siblingClusters[0]);
|
||||
Cluster clonedFirstNucleus = clonedNuclei[firstNucleusIx] as Cluster;
|
||||
clonedNucleus.siblingClusters = clonedFirstNucleus.siblingClusters;
|
||||
}
|
||||
}
|
||||
|
||||
if (clusterInstance.GetNucleus(sender.name) is not Neuron clonedSender)
|
||||
continue;
|
||||
/*
|
||||
// Collect the subclusters
|
||||
List<Cluster> subClusters = new();
|
||||
foreach (Nucleus nucleus in prefabNuclei) {
|
||||
foreach (Synapse synapse in nucleus.synapses) {
|
||||
Nucleus synapseNucleus = synapse.neuron;
|
||||
Cluster subCluster = synapseNucleus.parent;
|
||||
if (subCluster is null ||
|
||||
synapseNucleus.clusterPrefab == this.clusterPrefab) {
|
||||
|
||||
clonedSender.AddReceiver(clonedReceiver, weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// if (synapseNucleus is not Cluster subCluster)
|
||||
// continue;
|
||||
if (subClusters.Contains(subCluster))
|
||||
continue;
|
||||
subClusters.Add(subCluster);
|
||||
}
|
||||
}
|
||||
// Create the subcluster instances
|
||||
foreach (Cluster subCluster in subClusters) {
|
||||
for (int ix = 0; ix < subCluster.instanceCount; ix++) {
|
||||
// create the new instance
|
||||
Cluster clusterInstance = new(subCluster.prefab);
|
||||
// connect it
|
||||
foreach ((Neuron sender, Nucleus receiver) in subCluster.CollectConnections()) {
|
||||
int receiverIx = GetNucleusIndex(prefabNuclei, receiver);
|
||||
if (receiverIx < 0)
|
||||
continue;
|
||||
|
||||
if (clonedNuclei[receiverIx] 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.neuron == sender) {
|
||||
weight = synapse.weight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (clusterInstance.GetNucleus(sender.name) is not Neuron clonedSender)
|
||||
continue;
|
||||
|
||||
clonedSender.AddReceiver(clonedReceiver, weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
foreach (Nucleus nucleus in this.clusterNuclei) {
|
||||
if (nucleus is Cluster clonedSubCluster)
|
||||
@ -477,14 +528,8 @@ namespace NanoBrain {
|
||||
|
||||
#endregion ClusterArray
|
||||
|
||||
public ClusterPrefab prefab;
|
||||
|
||||
|
||||
[SerializeReference]
|
||||
public List<Nucleus> clusterNuclei = new();
|
||||
// the nuclei sorted using topological sorting
|
||||
// to ensure that the cluster is computer in the right order
|
||||
public List<Nucleus> sortedNuclei;
|
||||
//public Dictionary<string, Nucleus> nucleiDict = new();
|
||||
|
||||
public List<Nucleus> _inputs = null;
|
||||
|
||||
@ -59,6 +59,8 @@ public abstract class Nucleus {
|
||||
//ClusterArray,
|
||||
}
|
||||
|
||||
public virtual void Initialize() {}
|
||||
|
||||
#region Synapses
|
||||
|
||||
/// <summary>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user