Integrated clusterarray in cluster
This commit is contained in:
parent
e40dd234f9
commit
bc0a79688d
@ -189,17 +189,21 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
} else if (this.currentNucleus is Cluster cluster && cluster.clusterArray != null) {
|
}
|
||||||
|
else if (this.currentNucleus is Cluster cluster) {
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
EditorGUILayout.IntField("Array size", cluster.clusterArray.clusters.Count());
|
if (cluster.siblingClusters != null && cluster.siblingClusters.Length > 1)
|
||||||
|
EditorGUILayout.IntField("Array size", cluster.siblingClusters.Count());
|
||||||
|
else
|
||||||
|
EditorGUILayout.IntField("Array size", 1);
|
||||||
if (GUILayout.Button("Add")) {
|
if (GUILayout.Button("Add")) {
|
||||||
Undo.RecordObject(prefabAsset, "Array add " + prefabAsset.name);
|
Undo.RecordObject(prefabAsset, "Array add " + prefabAsset.name);
|
||||||
cluster.clusterArray.Add(this.prefab);
|
cluster.AddInstance(this.prefab);
|
||||||
anythingChanged = true;
|
anythingChanged = true;
|
||||||
}
|
}
|
||||||
if (GUILayout.Button("Del")) {
|
if (GUILayout.Button("Del")) {
|
||||||
Undo.RecordObject(prefabAsset, "Array delete " + prefabAsset.name);
|
Undo.RecordObject(prefabAsset, "Array delete " + prefabAsset.name);
|
||||||
cluster.clusterArray.Remove();
|
cluster.RemoveInstance();
|
||||||
anythingChanged = true;
|
anythingChanged = true;
|
||||||
}
|
}
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
@ -408,12 +412,12 @@ namespace NanoBrain {
|
|||||||
case Nucleus.Type.Receptor:
|
case Nucleus.Type.Receptor:
|
||||||
AddReceptorInput(nucleus);
|
AddReceptorInput(nucleus);
|
||||||
break;
|
break;
|
||||||
case Nucleus.Type.ClusterReceptor:
|
// case Nucleus.Type.ClusterReceptor:
|
||||||
AddClusterReceptorInput(nucleus);
|
// AddClusterReceptorInput(nucleus);
|
||||||
break;
|
// break;
|
||||||
case Nucleus.Type.ClusterArray:
|
// case Nucleus.Type.ClusterArray:
|
||||||
AddClusterArrayInput(nucleus);
|
// AddClusterArrayInput(nucleus);
|
||||||
break;
|
// break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -465,12 +469,12 @@ namespace NanoBrain {
|
|||||||
var editor = Editor.CreateEditor(subCluster.prefab);
|
var editor = Editor.CreateEditor(subCluster.prefab);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AddClusterArrayInput(Nucleus nucleus) {
|
// protected virtual void AddClusterArrayInput(Nucleus nucleus) {
|
||||||
ClusterPickerWindow.ShowPicker(prefab => OnPickedClusterArray(nucleus, prefab), "Select Cluster");
|
// ClusterPickerWindow.ShowPicker(prefab => OnPickedClusterArray(nucleus, prefab), "Select Cluster");
|
||||||
}
|
// }
|
||||||
private void OnPickedClusterArray(Nucleus nucleus, ClusterPrefab selectedPrefab) {
|
// private void OnPickedClusterArray(Nucleus nucleus, ClusterPrefab selectedPrefab) {
|
||||||
_ = new ClusterArray(selectedPrefab, this.prefab, 1, nucleus);
|
// _ = new ClusterArray(selectedPrefab, this.prefab, 1, nucleus);
|
||||||
}
|
// }
|
||||||
|
|
||||||
int selectedConnectNucleus = -1;
|
int selectedConnectNucleus = -1;
|
||||||
// Connect to another nucleus in the same cluster
|
// Connect to another nucleus in the same cluster
|
||||||
|
|||||||
@ -331,12 +331,16 @@ namespace NanoBrain {
|
|||||||
continue;
|
continue;
|
||||||
drawnArrays.Add(clusterReceptor.nucleiArray);
|
drawnArrays.Add(clusterReceptor.nucleiArray);
|
||||||
}
|
}
|
||||||
// Oops...
|
else if (synapse.neuron.parent is Cluster cluster && cluster.siblingClusters != null) {
|
||||||
else if (synapse.neuron.parent is Cluster cluster && cluster.clusterArray != null) {
|
if (drawnArrays.Contains(cluster.siblingClusters))
|
||||||
if (drawnArrays.Contains(cluster.clusterArray.clusters))
|
|
||||||
continue;
|
continue;
|
||||||
drawnArrays.Add(cluster.clusterArray.clusters);
|
drawnArrays.Add(cluster.siblingClusters);
|
||||||
}
|
}
|
||||||
|
// else if (synapse.neuron.parent is Cluster cluster && cluster.clusterArray != null) {
|
||||||
|
// if (drawnArrays.Contains(cluster.clusterArray.clusters))
|
||||||
|
// continue;
|
||||||
|
// drawnArrays.Add(cluster.clusterArray.clusters);
|
||||||
|
// }
|
||||||
if (synapse.neuron is Neuron synapseNeuron) {
|
if (synapse.neuron is Neuron synapseNeuron) {
|
||||||
float value = synapseNeuron.outputMagnitude * synapse.weight;
|
float value = synapseNeuron.outputMagnitude * synapse.weight;
|
||||||
// Debug.Log($"{synapse.nucleus.name}: {value} {length(synapse.nucleus.outputValue)} {synapse.weight}");
|
// Debug.Log($"{synapse.nucleus.name}: {value} {length(synapse.nucleus.outputValue)} {synapse.weight}");
|
||||||
@ -445,7 +449,7 @@ namespace NanoBrain {
|
|||||||
style.normal.textColor = Color.white;
|
style.normal.textColor = Color.white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nucleus is Cluster cluster && cluster.clusterArray != null) {
|
else if (nucleus is Cluster cluster) {
|
||||||
if (expandArray) {
|
if (expandArray) {
|
||||||
// Put array indices above elements
|
// Put array indices above elements
|
||||||
style.alignment = TextAnchor.LowerCenter;
|
style.alignment = TextAnchor.LowerCenter;
|
||||||
@ -457,15 +461,17 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (cluster.siblingClusters != null && cluster.siblingClusters.Length > 1) {
|
||||||
// draw the array size label
|
// draw the array size label
|
||||||
if (color.grayscale > 0.5f)
|
if (color.grayscale > 0.5f)
|
||||||
style.normal.textColor = Color.black;
|
style.normal.textColor = Color.black;
|
||||||
else
|
else
|
||||||
style.normal.textColor = Color.white;
|
style.normal.textColor = Color.white;
|
||||||
Handles.Label(labelPosition, cluster.clusterArray.clusters.Length.ToString(), style);
|
Handles.Label(labelPosition, cluster.siblingClusters.Length.ToString(), style);
|
||||||
style.normal.textColor = Color.white;
|
style.normal.textColor = Color.white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (expandArray == false || nucleus is not IReceptor) {
|
if (expandArray == false || nucleus is not IReceptor) {
|
||||||
// put name below nucleus
|
// put name below nucleus
|
||||||
|
|||||||
@ -8,13 +8,13 @@ using static Unity.Mathematics.math;
|
|||||||
|
|
||||||
namespace NanoBrain {
|
namespace NanoBrain {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Cluster combines a collection of Nuclei to implement reusable behaviour
|
/// A Cluster combines a collection of Nuclei to implement reusable behaviour
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// A Cluster is an instantiation of a ClusterPrefab.
|
/// A Cluster is an instantiation of a ClusterPrefab.
|
||||||
/// Clusters can be nested inside other clusters.
|
/// Clusters can be nested inside other clusters.
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Cluster : Nucleus {
|
public class Cluster : Nucleus {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The base name of the cluster. I don't think this is actively used at this moment
|
/// The base name of the cluster. I don't think this is actively used at this moment
|
||||||
@ -28,8 +28,11 @@ public class Cluster : Nucleus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//[SerializeReference]
|
||||||
|
//public ClusterArray clusterArray;
|
||||||
[SerializeReference]
|
[SerializeReference]
|
||||||
public ClusterArray clusterArray;
|
public Cluster[] siblingClusters;
|
||||||
|
public Dictionary<int, Cluster> thingClusters = new();
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
|
|
||||||
@ -44,7 +47,6 @@ public class Cluster : Nucleus {
|
|||||||
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.parent?.clusterNuclei.Add(this);
|
this.parent?.clusterNuclei.Add(this);
|
||||||
|
|
||||||
ClonePrefab();
|
ClonePrefab();
|
||||||
_ = this.inputs;
|
_ = this.inputs;
|
||||||
this.sortedNuclei = TopologicalSort(this.clusterNuclei);
|
this.sortedNuclei = TopologicalSort(this.clusterNuclei);
|
||||||
@ -244,6 +246,7 @@ public class Cluster : Nucleus {
|
|||||||
name = this.name,
|
name = this.name,
|
||||||
clusterPrefab = this.clusterPrefab,
|
clusterPrefab = this.clusterPrefab,
|
||||||
};
|
};
|
||||||
|
// Somehow siblingClusters should be cloned too. Believe I do this in ClonePrefab right now.
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
@ -306,6 +309,99 @@ public class Cluster : Nucleus {
|
|||||||
|
|
||||||
#endregion Init
|
#endregion Init
|
||||||
|
|
||||||
|
#region Cluster Array
|
||||||
|
|
||||||
|
|
||||||
|
public void AddInstance(ClusterPrefab prefab) {
|
||||||
|
// if (this.siblingClusters.Length == 0) {
|
||||||
|
// Debug.LogError("Empty perceptoid array, cannot add");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
this.siblingClusters ??= new Cluster[1] { this };
|
||||||
|
|
||||||
|
int newLength = this.siblingClusters.Length + 1;
|
||||||
|
Cluster[] newSiblings = new Cluster[newLength];
|
||||||
|
|
||||||
|
string baseName = this.name;
|
||||||
|
int colonPos = baseName.IndexOf(":");
|
||||||
|
if (colonPos > 0)
|
||||||
|
baseName = baseName[..colonPos];
|
||||||
|
|
||||||
|
for (int i = 0; i < newSiblings.Length - 1; i++)
|
||||||
|
newSiblings[i] = this.siblingClusters[i];
|
||||||
|
// Cluster sourceCluster = this.siblingClusters[0];
|
||||||
|
Cluster newCluster = this.Clone(prefab) as Cluster;
|
||||||
|
newCluster.name = $"{baseName}: {newLength - 1}";
|
||||||
|
//newCluster.clusterArray = this;
|
||||||
|
newSiblings[newLength - 1] = newCluster;
|
||||||
|
|
||||||
|
this.siblingClusters = newSiblings;
|
||||||
|
newCluster.siblingClusters = newSiblings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveInstance() {
|
||||||
|
int newLength = this.siblingClusters.Length - 1;
|
||||||
|
if (newLength == 0) {
|
||||||
|
Debug.LogWarning("Perceptoid array cannot be empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Cluster[] newClusters = new Cluster[newLength];
|
||||||
|
for (int i = 0; i < newLength; i++)
|
||||||
|
newClusters[i] = this.siblingClusters[i];
|
||||||
|
// Delete the last perception
|
||||||
|
//Cluster.Delete(nucleus);
|
||||||
|
this.siblingClusters = newClusters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Cluster GetThingCluster() {
|
||||||
|
Cluster selectedCluster = SelectCluster();
|
||||||
|
return selectedCluster;
|
||||||
|
}
|
||||||
|
public virtual Cluster GetThingCluster(int thingId, string thingName = null) {
|
||||||
|
if (thingClusters.TryGetValue(thingId, out Cluster cluster))
|
||||||
|
return cluster;
|
||||||
|
|
||||||
|
Cluster selectedCluster = SelectCluster();
|
||||||
|
thingClusters[thingId] = selectedCluster;
|
||||||
|
return selectedCluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cluster SelectCluster() {
|
||||||
|
if (this.siblingClusters == null)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
// Find a sleeping cluster
|
||||||
|
foreach (Cluster cluster in this.siblingClusters) {
|
||||||
|
if (cluster.defaultOutput.isSleeping) {
|
||||||
|
RemoveThingCluster(cluster);
|
||||||
|
return cluster;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise find the stalest cluster?
|
||||||
|
Cluster stalestCluster = this.siblingClusters[0];
|
||||||
|
for (int ix = 1; ix < this.siblingClusters.Length; ix++) {
|
||||||
|
if (this.siblingClusters[ix].defaultOutput.stale > stalestCluster.defaultOutput.stale)
|
||||||
|
stalestCluster = this.siblingClusters[ix];
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveThingCluster(stalestCluster);
|
||||||
|
return stalestCluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveThingCluster(Cluster cluster) {
|
||||||
|
List<int> keysToRemove = new();
|
||||||
|
foreach (KeyValuePair<int, Cluster> kvp in thingClusters) {
|
||||||
|
if (kvp.Value == cluster)
|
||||||
|
keysToRemove.Add(kvp.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (int thingId in keysToRemove)
|
||||||
|
thingClusters.Remove(thingId);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion ClusterArray
|
||||||
|
|
||||||
public ClusterPrefab prefab;
|
public ClusterPrefab prefab;
|
||||||
|
|
||||||
|
|
||||||
@ -540,6 +636,6 @@ public class Cluster : Nucleus {
|
|||||||
|
|
||||||
#endregion Update
|
#endregion Update
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
/*
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -8,6 +9,7 @@ namespace NanoBrain {
|
|||||||
public class ClusterArray : Nucleus {
|
public class ClusterArray : Nucleus {
|
||||||
|
|
||||||
public ClusterPrefab prefab;
|
public ClusterPrefab prefab;
|
||||||
|
[SerializeReference]
|
||||||
public Cluster[] clusters;
|
public Cluster[] clusters;
|
||||||
|
|
||||||
public Dictionary<int, Cluster> thingClusters = new();
|
public Dictionary<int, Cluster> thingClusters = new();
|
||||||
@ -19,7 +21,7 @@ namespace NanoBrain {
|
|||||||
for (int ix = 0; ix < size; ix++) {
|
for (int ix = 0; ix < size; ix++) {
|
||||||
Cluster cluster = new(prefab, parent);
|
Cluster cluster = new(prefab, parent);
|
||||||
cluster.defaultOutput.AddReceiver(receiver);
|
cluster.defaultOutput.AddReceiver(receiver);
|
||||||
cluster.clusterArray = this;
|
//cluster.clusterArray = this;
|
||||||
this.clusters[ix] = cluster;
|
this.clusters[ix] = cluster;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,7 +33,7 @@ namespace NanoBrain {
|
|||||||
for (int ix = 0; ix < size; ix++) {
|
for (int ix = 0; ix < size; ix++) {
|
||||||
Cluster cluster = new(prefab, parent);
|
Cluster cluster = new(prefab, parent);
|
||||||
cluster.defaultOutput.AddReceiver(receiver);
|
cluster.defaultOutput.AddReceiver(receiver);
|
||||||
cluster.clusterArray = this;
|
//cluster.clusterArray = this;
|
||||||
this.clusters[ix] = cluster;
|
this.clusters[ix] = cluster;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +71,7 @@ namespace NanoBrain {
|
|||||||
Cluster sourceCluster = this.clusters[0];
|
Cluster sourceCluster = this.clusters[0];
|
||||||
Cluster newCluster = sourceCluster.Clone(prefab) as Cluster;
|
Cluster newCluster = sourceCluster.Clone(prefab) as Cluster;
|
||||||
newCluster.name = $"{baseName}: {newLength - 1}";
|
newCluster.name = $"{baseName}: {newLength - 1}";
|
||||||
newCluster.clusterArray = this;
|
//newCluster.clusterArray = this;
|
||||||
newClusters[newLength - 1] = newCluster;
|
newClusters[newLength - 1] = newCluster;
|
||||||
this.clusters = newClusters;
|
this.clusters = newClusters;
|
||||||
}
|
}
|
||||||
@ -140,3 +142,4 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
@ -55,8 +55,8 @@ public abstract class Nucleus {
|
|||||||
MemoryCell,
|
MemoryCell,
|
||||||
Cluster,
|
Cluster,
|
||||||
Receptor,
|
Receptor,
|
||||||
ClusterReceptor,
|
//ClusterReceptor,
|
||||||
ClusterArray,
|
//ClusterArray,
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Synapses
|
#region Synapses
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user