cluster no longer have receivers
This commit is contained in:
parent
a394f582cf
commit
36e73081f9
156
Cluster.cs
156
Cluster.cs
@ -15,11 +15,11 @@ public class Cluster : Nucleus {
|
|||||||
this.name = prefab.name;
|
this.name = prefab.name;
|
||||||
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.parent?.nuclei.Add(this);
|
this.parent?.clusterNuclei.Add(this);
|
||||||
|
|
||||||
ClonePrefab();
|
ClonePrefab();
|
||||||
_ = this.inputs;
|
_ = this.inputs;
|
||||||
this.sortedNuclei = TopologicalSort(this.nuclei);
|
this.sortedNuclei = TopologicalSort(this.clusterNuclei);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cluster(ClusterPrefab prefab, ClusterPrefab parent = null) {
|
public Cluster(ClusterPrefab prefab, ClusterPrefab parent = null) {
|
||||||
@ -32,7 +32,7 @@ public class Cluster : Nucleus {
|
|||||||
|
|
||||||
ClonePrefab();
|
ClonePrefab();
|
||||||
_ = this.inputs;
|
_ = this.inputs;
|
||||||
this.sortedNuclei = TopologicalSort(this.nuclei);
|
this.sortedNuclei = TopologicalSort(this.clusterNuclei);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClonePrefab() {
|
private void ClonePrefab() {
|
||||||
@ -40,7 +40,7 @@ public class Cluster : Nucleus {
|
|||||||
// first clone the nuclei without their connections
|
// first clone the nuclei without their connections
|
||||||
foreach (Nucleus nucleus in this.prefab.nuclei)
|
foreach (Nucleus nucleus in this.prefab.nuclei)
|
||||||
nucleus.ShallowCloneTo(this);
|
nucleus.ShallowCloneTo(this);
|
||||||
Nucleus[] clonedNuclei = this.nuclei.ToArray();
|
Nucleus[] clonedNuclei = this.clusterNuclei.ToArray();
|
||||||
|
|
||||||
// Now clone the connections
|
// Now clone the connections
|
||||||
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
||||||
@ -50,26 +50,27 @@ public class Cluster : Nucleus {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Copy the receivers, which will also create the synapses
|
// Copy the receivers, which will also create the synapses
|
||||||
foreach (Nucleus receiver in prefabNucleus.receivers) {
|
// Clusters do not have receivers...
|
||||||
int ix = GetNucleusIndex(prefabNuclei, receiver);
|
// foreach (Nucleus receiver in prefabNucleus.receivers) {
|
||||||
if (ix < 0)
|
// int ix = GetNucleusIndex(prefabNuclei, receiver);
|
||||||
continue;
|
// if (ix < 0)
|
||||||
|
// continue;
|
||||||
|
|
||||||
if (clonedNuclei[ix] is not Nucleus clonedReceiver)
|
// if (clonedNuclei[ix] is not Nucleus clonedReceiver)
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
// Find the synapse for the weight
|
// // Find the synapse for the weight
|
||||||
float weight = 1;
|
// float weight = 1;
|
||||||
foreach (Synapse synapse in receiver.synapses) {
|
// foreach (Synapse synapse in receiver.synapses) {
|
||||||
// Find the weight for this synapse
|
// // Find the weight for this synapse
|
||||||
if (synapse.nucleus == prefabNucleus) {
|
// if (synapse.nucleus == prefabNucleus) {
|
||||||
weight = synapse.weight;
|
// weight = synapse.weight;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
clonedReceptor.AddReceiver(clonedReceiver, weight);
|
// clonedReceptor.AddReceiver(clonedReceiver, weight);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy nucleus arrays
|
// Copy nucleus arrays
|
||||||
@ -116,8 +117,10 @@ public class Cluster : Nucleus {
|
|||||||
|
|
||||||
// Calculate in-degrees
|
// Calculate in-degrees
|
||||||
foreach (Nucleus node in nodes) {
|
foreach (Nucleus node in nodes) {
|
||||||
foreach (Nucleus receiver in node.receivers)
|
if (node is Neuron neuron) {
|
||||||
inDegree[receiver]++;
|
foreach (Nucleus receiver in neuron.receivers)
|
||||||
|
inDegree[receiver]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Queue<Nucleus> queue = new();
|
Queue<Nucleus> queue = new();
|
||||||
@ -132,10 +135,12 @@ public class Cluster : Nucleus {
|
|||||||
Nucleus current = queue.Dequeue();
|
Nucleus current = queue.Dequeue();
|
||||||
sortedOrder.Add(current); // Process the node
|
sortedOrder.Add(current); // Process the node
|
||||||
|
|
||||||
foreach (Nucleus receiver in current.receivers) {
|
if (current is Neuron neuron) {
|
||||||
inDegree[receiver]--;
|
foreach (Nucleus receiver in neuron.receivers) {
|
||||||
if (inDegree[receiver] == 0) // If all dependencies resolved
|
inDegree[receiver]--;
|
||||||
queue.Enqueue(receiver);
|
if (inDegree[receiver] == 0) // If all dependencies resolved
|
||||||
|
queue.Enqueue(receiver);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,9 +158,9 @@ public class Cluster : Nucleus {
|
|||||||
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
|
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
|
||||||
clonedSynapse.weight = synapse.weight;
|
clonedSynapse.weight = synapse.weight;
|
||||||
}
|
}
|
||||||
foreach (Nucleus receiver in this.receivers) {
|
// foreach (Nucleus receiver in this.receivers) {
|
||||||
clone.AddReceiver(receiver);
|
// clone.AddReceiver(receiver);
|
||||||
}
|
// }
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +186,7 @@ public class Cluster : Nucleus {
|
|||||||
|
|
||||||
|
|
||||||
[SerializeReference]
|
[SerializeReference]
|
||||||
public List<Nucleus> nuclei = new();
|
public List<Nucleus> clusterNuclei = new();
|
||||||
// the nuclei sorted using topological sorting
|
// the nuclei sorted using topological sorting
|
||||||
// to ensure that the cluster is computer in the right order
|
// to ensure that the cluster is computer in the right order
|
||||||
public List<Nucleus> sortedNuclei;
|
public List<Nucleus> sortedNuclei;
|
||||||
@ -192,7 +197,7 @@ public class Cluster : Nucleus {
|
|||||||
get {
|
get {
|
||||||
if (this._inputs == null) {
|
if (this._inputs == null) {
|
||||||
this._inputs = new();
|
this._inputs = new();
|
||||||
foreach (Nucleus nucleus in this.nuclei) {
|
foreach (Nucleus nucleus in this.clusterNuclei) {
|
||||||
// inputs have no synapses
|
// inputs have no synapses
|
||||||
if (nucleus.synapses.Count == 0)
|
if (nucleus.synapses.Count == 0)
|
||||||
this._inputs.Add(nucleus);
|
this._inputs.Add(nucleus);
|
||||||
@ -215,7 +220,7 @@ public class Cluster : Nucleus {
|
|||||||
HashSet<Nucleus> visited = new HashSet<Nucleus>();
|
HashSet<Nucleus> visited = new HashSet<Nucleus>();
|
||||||
|
|
||||||
// Initialize in-degrees and mark all nodes as unvisited
|
// Initialize in-degrees and mark all nodes as unvisited
|
||||||
foreach (Nucleus node in this.nuclei) {
|
foreach (Nucleus node in this.clusterNuclei) {
|
||||||
inDegree[node] = 0;
|
inDegree[node] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,12 +231,14 @@ public class Cluster : Nucleus {
|
|||||||
|
|
||||||
while (queue.Count > 0) {
|
while (queue.Count > 0) {
|
||||||
Nucleus current = queue.Dequeue();
|
Nucleus current = queue.Dequeue();
|
||||||
foreach (Nucleus receiver in current.receivers) {
|
if (current is Neuron neuron) {
|
||||||
if (!visited.Contains(receiver)) {
|
foreach (Nucleus receiver in neuron.receivers) {
|
||||||
visited.Add(receiver);
|
if (!visited.Contains(receiver)) {
|
||||||
queue.Enqueue(receiver);
|
visited.Add(receiver);
|
||||||
|
queue.Enqueue(receiver);
|
||||||
|
}
|
||||||
|
inDegree[receiver]++;
|
||||||
}
|
}
|
||||||
inDegree[receiver]++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,11 +255,13 @@ public class Cluster : Nucleus {
|
|||||||
Nucleus current = queue.Dequeue();
|
Nucleus current = queue.Dequeue();
|
||||||
sortedOrder.Add(current); // Process the node
|
sortedOrder.Add(current); // Process the node
|
||||||
|
|
||||||
foreach (Nucleus receiver in current.receivers) {
|
if (current is Neuron neuron) {
|
||||||
if (visited.Contains(receiver)) {
|
foreach (Nucleus receiver in neuron.receivers) {
|
||||||
inDegree[receiver]--;
|
if (visited.Contains(receiver)) {
|
||||||
if (inDegree[receiver] == 0) // If all dependencies resolved
|
inDegree[receiver]--;
|
||||||
queue.Enqueue(receiver);
|
if (inDegree[receiver] == 0) // If all dependencies resolved
|
||||||
|
queue.Enqueue(receiver);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,13 +275,15 @@ public class Cluster : Nucleus {
|
|||||||
|
|
||||||
private List<Nucleus> TopologicalSort3(Nucleus startNode) {
|
private List<Nucleus> TopologicalSort3(Nucleus startNode) {
|
||||||
Dictionary<Nucleus, int> inDegree = new();
|
Dictionary<Nucleus, int> inDegree = new();
|
||||||
foreach (Nucleus node in this.nuclei)
|
foreach (Nucleus node in this.clusterNuclei)
|
||||||
inDegree[node] = 0; // Initialize in-degree to zero
|
inDegree[node] = 0; // Initialize in-degree to zero
|
||||||
|
|
||||||
// Calculate in-degrees
|
// Calculate in-degrees
|
||||||
foreach (Nucleus node in this.nuclei) {
|
foreach (Nucleus node in this.clusterNuclei) {
|
||||||
foreach (Nucleus receiver in node.receivers)
|
if (node is Neuron neuron) {
|
||||||
inDegree[receiver]++;
|
foreach (Nucleus receiver in neuron.receivers)
|
||||||
|
inDegree[receiver]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Queue<Nucleus> queue = new();
|
Queue<Nucleus> queue = new();
|
||||||
@ -283,10 +294,12 @@ public class Cluster : Nucleus {
|
|||||||
Nucleus current = queue.Dequeue();
|
Nucleus current = queue.Dequeue();
|
||||||
sortedOrder.Add(current); // Process the node
|
sortedOrder.Add(current); // Process the node
|
||||||
|
|
||||||
foreach (Nucleus receiver in current.receivers) {
|
if (current is Neuron neuron) {
|
||||||
inDegree[receiver]--;
|
foreach (Nucleus receiver in neuron.receivers) {
|
||||||
if (inDegree[receiver] == 0) // If all dependencies resolved
|
inDegree[receiver]--;
|
||||||
queue.Enqueue(receiver);
|
if (inDegree[receiver] == 0) // If all dependencies resolved
|
||||||
|
queue.Enqueue(receiver);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,22 +311,21 @@ public class Cluster : Nucleus {
|
|||||||
return sortedOrder;
|
return sortedOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Nucleus output {//=> this.nuclei[0] as Nucleus;
|
public virtual Neuron defaultOutput {//=> this.nuclei[0] as Nucleus;
|
||||||
get {
|
get {
|
||||||
if (this.nuclei.Count > 0)
|
if (this.clusterNuclei.Count > 0)
|
||||||
return this.nuclei[0];
|
return this.clusterNuclei[0] as Neuron;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public List<Nucleus> _outputs = null;
|
private List<Neuron> _outputs = null;
|
||||||
public List<Nucleus> outputs {
|
public List<Neuron> outputs {
|
||||||
get {
|
get {
|
||||||
if (this._outputs == null) {
|
if (this._outputs == null) {
|
||||||
this._outputs = new();
|
this._outputs = new();
|
||||||
foreach (Nucleus nucleus in this.nuclei) {
|
foreach (Nucleus nucleus in this.clusterNuclei) {
|
||||||
// outputs have not receivers
|
if (nucleus is Neuron neuron) // && neuron.receivers.Count == 0)
|
||||||
if (nucleus.receivers.Count == 0)
|
this._outputs.Add(neuron);
|
||||||
this._outputs.Add(nucleus);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this._outputs;
|
return this._outputs;
|
||||||
@ -321,7 +333,7 @@ public class Cluster : Nucleus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetNucleus(string nucleusName, out Nucleus foundNucleus) {
|
public bool TryGetNucleus(string nucleusName, out Nucleus foundNucleus) {
|
||||||
foreach (Nucleus receptor in this.nuclei) {
|
foreach (Nucleus receptor in this.clusterNuclei) {
|
||||||
if (receptor is Nucleus nucleus)
|
if (receptor is Nucleus nucleus)
|
||||||
if (nucleus.name == nucleusName) {
|
if (nucleus.name == nucleusName) {
|
||||||
foundNucleus = nucleus;
|
foundNucleus = nucleus;
|
||||||
@ -333,7 +345,7 @@ public class Cluster : Nucleus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Nucleus GetNucleus(string nucleusName) {
|
public Nucleus GetNucleus(string nucleusName) {
|
||||||
foreach (Nucleus nucleus in this.nuclei) {
|
foreach (Nucleus nucleus in this.clusterNuclei) {
|
||||||
if (nucleus.name == nucleusName)
|
if (nucleus.name == nucleusName)
|
||||||
return nucleus;
|
return nucleus;
|
||||||
}
|
}
|
||||||
@ -341,7 +353,7 @@ public class Cluster : Nucleus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Receptor GetReceptor(string receptorName) {
|
public Receptor GetReceptor(string receptorName) {
|
||||||
foreach (Nucleus nucleus in this.nuclei) {
|
foreach (Nucleus nucleus in this.clusterNuclei) {
|
||||||
if (nucleus is Receptor receptor)
|
if (nucleus is Receptor receptor)
|
||||||
if (receptor.name == receptorName)
|
if (receptor.name == receptorName)
|
||||||
return receptor;
|
return receptor;
|
||||||
@ -349,6 +361,18 @@ public class Cluster : Nucleus {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Receivers
|
||||||
|
|
||||||
|
public virtual List<Nucleus> CollectReceivers() {
|
||||||
|
List<Nucleus> receivers = new();
|
||||||
|
foreach (Neuron output in this.outputs) {
|
||||||
|
receivers.AddRange(output.receivers);
|
||||||
|
}
|
||||||
|
return receivers;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Receivers
|
||||||
|
|
||||||
#region Update
|
#region Update
|
||||||
|
|
||||||
public void UpdateFromNucleus(Nucleus startNucleus) {
|
public void UpdateFromNucleus(Nucleus startNucleus) {
|
||||||
@ -363,7 +387,7 @@ public class Cluster : Nucleus {
|
|||||||
Debug.Log($" {nucleus.name} = {nucleus.outputValue}");
|
Debug.Log($" {nucleus.name} = {nucleus.outputValue}");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.outputValue = this.output.outputValue;
|
this.outputValue = this.defaultOutput.outputValue;
|
||||||
this.stale = 0;
|
this.stale = 0;
|
||||||
|
|
||||||
UpdateNuclei();
|
UpdateNuclei();
|
||||||
@ -383,14 +407,14 @@ public class Cluster : Nucleus {
|
|||||||
foreach (Nucleus nucleus in this.sortedNuclei)
|
foreach (Nucleus nucleus in this.sortedNuclei)
|
||||||
nucleus.UpdateStateIsolated();
|
nucleus.UpdateStateIsolated();
|
||||||
|
|
||||||
this.outputValue = this.output.outputValue;
|
this.outputValue = this.defaultOutput.outputValue;
|
||||||
this.stale = 0;
|
this.stale = 0;
|
||||||
|
|
||||||
UpdateNuclei();
|
UpdateNuclei();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateNuclei() {
|
public override void UpdateNuclei() {
|
||||||
foreach (Nucleus nucleus in this.nuclei)
|
foreach (Nucleus nucleus in this.clusterNuclei)
|
||||||
nucleus.UpdateNuclei();
|
nucleus.UpdateNuclei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@ public class ClusterPrefab : ScriptableObject {
|
|||||||
public void RefreshOutputs() {
|
public void RefreshOutputs() {
|
||||||
this._outputs = new();
|
this._outputs = new();
|
||||||
foreach (Nucleus nucleus in this.nuclei) {
|
foreach (Nucleus nucleus in this.nuclei) {
|
||||||
if (nucleus.receivers.Count == 0)
|
if (nucleus is Neuron neuron && neuron.receivers.Count == 0)
|
||||||
this._outputs.Add(nucleus);
|
this._outputs.Add(nucleus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,15 +85,15 @@ public class ClusterPrefab : ScriptableObject {
|
|||||||
}
|
}
|
||||||
nucleus.synapses.RemoveAll(synapse => visitedSynapses.Contains(synapse) == false);
|
nucleus.synapses.RemoveAll(synapse => visitedSynapses.Contains(synapse) == false);
|
||||||
}
|
}
|
||||||
if (nucleus.receivers != null) {
|
if (nucleus is Neuron neuron && neuron.receivers != null) {
|
||||||
HashSet<Nucleus> visitedReceivers = new();
|
HashSet<Nucleus> visitedReceivers = new();
|
||||||
foreach (Nucleus receiver in nucleus.receivers) {
|
foreach (Nucleus receiver in neuron.receivers) {
|
||||||
if (receiver != null && receiver != null) {
|
if (receiver != null && receiver != null) {
|
||||||
visitedReceivers.Add(receiver);
|
visitedReceivers.Add(receiver);
|
||||||
visitedNuclei.Add(receiver);
|
visitedNuclei.Add(receiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nucleus.receivers.RemoveAll(receiver => visitedReceivers.Contains(receiver) == false);
|
neuron.receivers.RemoveAll(receiver => visitedReceivers.Contains(receiver) == false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ using Unity.Mathematics;
|
|||||||
using static Unity.Mathematics.math;
|
using static Unity.Mathematics.math;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ClusterReceptor : Cluster {
|
public class ClusterReceptor : Cluster, IReceptor {
|
||||||
public ClusterReceptor(ClusterPrefab prefab, Cluster parent, string name) : base(prefab, parent) {
|
public ClusterReceptor(ClusterPrefab prefab, Cluster parent, string name) : base(prefab, parent) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.array ??= new NucleusArray(this);
|
this.array ??= new NucleusArray(this);
|
||||||
@ -32,9 +32,9 @@ public class ClusterReceptor : Cluster {
|
|||||||
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
|
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
|
||||||
clonedSynapse.weight = synapse.weight;
|
clonedSynapse.weight = synapse.weight;
|
||||||
}
|
}
|
||||||
foreach (Nucleus receiver in this.receivers) {
|
// foreach (Nucleus receiver in this.receivers) {
|
||||||
clone.AddReceiver(receiver);
|
// clone.AddReceiver(receiver);
|
||||||
}
|
// }
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,21 +48,22 @@ public class ClusterReceptor : Cluster {
|
|||||||
#region Receivers
|
#region Receivers
|
||||||
|
|
||||||
private List<Nucleus> _clusterReceivers = null;
|
private List<Nucleus> _clusterReceivers = null;
|
||||||
public override List<Nucleus> receivers {
|
// public override List<Nucleus> receivers {
|
||||||
get {
|
// get {
|
||||||
if (_clusterReceivers == null || _clusterReceivers.Count == 0) {
|
// if (_clusterReceivers == null || _clusterReceivers.Count == 0) {
|
||||||
_clusterReceivers = new();
|
// _clusterReceivers = new();
|
||||||
foreach (Nucleus output in this.nuclei) {
|
// foreach (Nucleus output in this.clusterNuclei) {
|
||||||
_clusterReceivers.AddRange(output.receivers);
|
// _clusterReceivers.AddRange(output.receivers);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return _clusterReceivers;
|
// return _clusterReceivers;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
public override void AddReceiver(Nucleus receivingNucleus, float weight = 1) {
|
// public override void AddReceiver(Nucleus receivingNucleus, float weight = 1) {
|
||||||
this.output.receivers.Add(receivingNucleus);
|
// string nucleusName = this.
|
||||||
receivingNucleus.AddSynapse(this.output, weight);
|
// this.output.receivers.Add(receivingNucleus);
|
||||||
}
|
// receivingNucleus.AddSynapse(this.output, weight);
|
||||||
|
// }
|
||||||
|
|
||||||
#endregion Receivers
|
#endregion Receivers
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ public class ClusterReceptor : Cluster {
|
|||||||
foreach (Nucleus nucleus in this.sortedNuclei)
|
foreach (Nucleus nucleus in this.sortedNuclei)
|
||||||
nucleus.UpdateStateIsolated();
|
nucleus.UpdateStateIsolated();
|
||||||
|
|
||||||
this.outputValue = this.output.outputValue;
|
this.outputValue = this.defaultOutput.outputValue;
|
||||||
this.stale = 0;
|
this.stale = 0;
|
||||||
|
|
||||||
UpdateNuclei();
|
UpdateNuclei();
|
||||||
@ -85,7 +86,7 @@ public class ClusterReceptor : Cluster {
|
|||||||
this.parent.UpdateFromNucleus(this);
|
this.parent.UpdateFromNucleus(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Nucleus nucleus in this.nuclei)
|
foreach (Nucleus nucleus in this.clusterNuclei)
|
||||||
nucleus.UpdateNuclei();
|
nucleus.UpdateNuclei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -74,9 +74,11 @@ public class BrainEditorWindow : EditorWindow {
|
|||||||
int ix = 0;
|
int ix = 0;
|
||||||
foreach (Nucleus nucleus in prefab.nuclei) {
|
foreach (Nucleus nucleus in prefab.nuclei) {
|
||||||
nodes.Add(new DagNode() { id = ix, title = nucleus.name });
|
nodes.Add(new DagNode() { id = ix, title = nucleus.name });
|
||||||
foreach (Nucleus receiver in nucleus.receivers) {
|
if (nucleus is Neuron neuron) {
|
||||||
int receiverIx = prefab.GetNucleusIndex(receiver);
|
foreach (Nucleus receiver in neuron.receivers) {
|
||||||
edges.Add(new DagEdge() { fromId = ix, toId = receiverIx });
|
int receiverIx = prefab.GetNucleusIndex(receiver);
|
||||||
|
edges.Add(new DagEdge() { fromId = ix, toId = receiverIx });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ix++;
|
ix++;
|
||||||
}
|
}
|
||||||
@ -191,9 +193,9 @@ public class BrainEditorWindow : EditorWindow {
|
|||||||
Handles.DrawSolidDisc(n.position, Vector3.forward, n.radius);
|
Handles.DrawSolidDisc(n.position, Vector3.forward, n.radius);
|
||||||
|
|
||||||
if (GetIncomingEdges(n).Count == 0)
|
if (GetIncomingEdges(n).Count == 0)
|
||||||
DrawArrowHead(n.position - new Vector2(n.radius + 10, 0), n.position - new Vector2(n.radius + 5, 0), 10f/zoom, 12f/zoom, Color.white);
|
DrawArrowHead(n.position - new Vector2(n.radius + 10, 0), n.position - new Vector2(n.radius + 5, 0), 10f / zoom, 12f / zoom, Color.white);
|
||||||
if (GetOutgoingEdges(n).Count == 0)
|
if (GetOutgoingEdges(n).Count == 0)
|
||||||
DrawArrowHead(n.position + new Vector2(n.radius + 10, 0), n.position + new Vector2(n.radius + 15, 0), 10f/zoom, 12f/zoom, Color.white);
|
DrawArrowHead(n.position + new Vector2(n.radius + 10, 0), n.position + new Vector2(n.radius + 15, 0), 10f / zoom, 12f / zoom, Color.white);
|
||||||
|
|
||||||
Handles.color = Color.white;
|
Handles.color = Color.white;
|
||||||
GUIStyle style = new(EditorStyles.label) {
|
GUIStyle style = new(EditorStyles.label) {
|
||||||
|
|||||||
@ -195,8 +195,8 @@ public class ClusterInspector : Editor {
|
|||||||
return;
|
return;
|
||||||
NeuroidLayer currentLayer = new() { ix = layerIx };
|
NeuroidLayer currentLayer = new() { ix = layerIx };
|
||||||
|
|
||||||
if (selectedNucleus.receivers != null) {
|
if (selectedNucleus is Neuron selectedNeuron && selectedNeuron.receivers != null) {
|
||||||
foreach (Nucleus receiver in selectedNucleus.receivers) {
|
foreach (Nucleus receiver in selectedNeuron.receivers) {
|
||||||
Nucleus outputNeuroid = receiver;
|
Nucleus outputNeuroid = receiver;
|
||||||
if (outputNeuroid != null) {
|
if (outputNeuroid != null) {
|
||||||
AddToLayer(currentLayer, outputNeuroid);
|
AddToLayer(currentLayer, outputNeuroid);
|
||||||
@ -357,12 +357,20 @@ public class ClusterInspector : Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void DrawReceivers(Nucleus nucleus, Vector3 parentPos, float size) {
|
private void DrawReceivers(Nucleus nucleus, Vector3 parentPos, float size) {
|
||||||
int nodeCount = nucleus.receivers.Count();
|
List<Nucleus> receivers = null;
|
||||||
|
if (nucleus is Neuron neuron)
|
||||||
|
receivers = neuron.receivers;
|
||||||
|
else if (nucleus is Cluster cluster)
|
||||||
|
receivers = cluster.CollectReceivers();
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
int nodeCount = receivers.Count(); //neuron != null ? neuron.receivers.Count() : 1;
|
||||||
|
|
||||||
// Determine the maximum value in this layer
|
// Determine the maximum value in this layer
|
||||||
// This is used to 'scale' the output value colors of the nuclei
|
// This is used to 'scale' the output value colors of the nuclei
|
||||||
float maxValue = 0;
|
float maxValue = 0;
|
||||||
foreach (Nucleus receiver in nucleus.receivers) {
|
foreach (Nucleus receiver in receivers) {
|
||||||
if (receiver is Neuron neuroid) {
|
if (receiver is Neuron neuroid) {
|
||||||
float value = length(neuroid.outputValue);
|
float value = length(neuroid.outputValue);
|
||||||
if (value > maxValue)
|
if (value > maxValue)
|
||||||
@ -376,7 +384,7 @@ public class ClusterInspector : Editor {
|
|||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
List<NucleusArray> drawnArrays = new();
|
List<NucleusArray> drawnArrays = new();
|
||||||
foreach (Nucleus receiver in nucleus.receivers) {
|
foreach (Nucleus receiver in receivers) {
|
||||||
if (receiver is Receptor receptor) {
|
if (receiver is Receptor receptor) {
|
||||||
if (drawnArrays.Contains(receptor.array))
|
if (drawnArrays.Contains(receptor.array))
|
||||||
continue;
|
continue;
|
||||||
@ -409,7 +417,8 @@ public class ClusterInspector : Editor {
|
|||||||
if (drawnArrays.Contains(receptor.array))
|
if (drawnArrays.Contains(receptor.array))
|
||||||
continue;
|
continue;
|
||||||
drawnArrays.Add(receptor.array);
|
drawnArrays.Add(receptor.array);
|
||||||
} else if (synapse.nucleus.parent is ClusterReceptor clusterReceptor) {
|
}
|
||||||
|
else if (synapse.nucleus.parent is ClusterReceptor clusterReceptor) {
|
||||||
if (drawnArrays.Contains(clusterReceptor.array))
|
if (drawnArrays.Contains(clusterReceptor.array))
|
||||||
continue;
|
continue;
|
||||||
drawnArrays.Add(clusterReceptor.array);
|
drawnArrays.Add(clusterReceptor.array);
|
||||||
@ -432,7 +441,8 @@ public class ClusterInspector : Editor {
|
|||||||
if (drawnArrays.Contains(neuron.array))
|
if (drawnArrays.Contains(neuron.array))
|
||||||
continue;
|
continue;
|
||||||
drawnArrays.Add(neuron.array);
|
drawnArrays.Add(neuron.array);
|
||||||
} else if (synapse.nucleus.parent is ClusterReceptor clusterReceptor) {
|
}
|
||||||
|
else if (synapse.nucleus.parent is ClusterReceptor clusterReceptor) {
|
||||||
if (drawnArrays.Contains(clusterReceptor.array))
|
if (drawnArrays.Contains(clusterReceptor.array))
|
||||||
continue;
|
continue;
|
||||||
drawnArrays.Add(clusterReceptor.array);
|
drawnArrays.Add(clusterReceptor.array);
|
||||||
@ -731,56 +741,61 @@ public class ClusterInspector : Editor {
|
|||||||
if (this.currentNucleus.synapses.Count > 0) {
|
if (this.currentNucleus.synapses.Count > 0) {
|
||||||
Synapse[] synapses = this.currentNucleus.synapses.ToArray();
|
Synapse[] synapses = this.currentNucleus.synapses.ToArray();
|
||||||
foreach (Synapse synapse in synapses) {
|
foreach (Synapse synapse in synapses) {
|
||||||
if (synapse.nucleus != null) {
|
if (synapse.nucleus == null)
|
||||||
if (array != null) {
|
continue;
|
||||||
if (array.nuclei.Contains(synapse.nucleus))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (synapse.nucleus is Receptor receptor2 && receptor2.array != null && receptor2.array.nuclei.Length > 1)
|
|
||||||
array = receptor2.array;
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorGUILayout.Space();
|
if (array != null) {
|
||||||
|
if (array.nuclei.Contains(synapse.nucleus))
|
||||||
if (Application.isPlaying) {
|
continue;
|
||||||
Vector3 value = synapse.nucleus.outputValue * synapse.weight;
|
if (array.nuclei.Contains(synapse.nucleus.parent))
|
||||||
GUIContent synapseValueLabel = new(synapse.nucleus.name, synapse.nucleus.outputValue.ToString());
|
continue;
|
||||||
EditorGUILayout.FloatField(synapseValueLabel, length(synapse.nucleus.outputValue));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
EditorGUILayout.BeginHorizontal();
|
|
||||||
|
|
||||||
if (synapse.nucleus.parent != null && synapse.nucleus.parent != this.currentNucleus) {
|
|
||||||
GUIStyle labelStyle = new(GUI.skin.label);
|
|
||||||
float labelWidth = labelStyle.CalcSize(new GUIContent($"{synapse.nucleus.clusterPrefab.name}.")).x;
|
|
||||||
EditorGUILayout.LabelField($"{synapse.nucleus.clusterPrefab.name}", GUILayout.Width(labelWidth));
|
|
||||||
string[] options = synapse.nucleus.parent.nuclei.Select(n => n.name).ToArray();
|
|
||||||
int selectedIndex = System.Array.IndexOf(options, synapse.nucleus.name);
|
|
||||||
int newIndex = EditorGUILayout.Popup(selectedIndex, options);
|
|
||||||
if (newIndex != selectedIndex) {
|
|
||||||
ChangeSynapse(synapse, synapse.nucleus.parent.nuclei[newIndex]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
EditorGUILayout.LabelField(synapse.nucleus.name);
|
|
||||||
if (GUILayout.Button("Disconnect")) {
|
|
||||||
synapse.nucleus.RemoveReceiver(this.currentNucleus);
|
|
||||||
this.prefab.GarbageCollection();
|
|
||||||
anythingChanged = true;
|
|
||||||
}
|
|
||||||
EditorGUILayout.EndHorizontal();
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorGUI.indentLevel++;
|
|
||||||
synapse.weight = EditorGUILayout.FloatField("Weight", synapse.weight);
|
|
||||||
EditorGUI.indentLevel--;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (synapse.nucleus.parent is ClusterReceptor clusterReceptor)
|
||||||
|
array = clusterReceptor.array;
|
||||||
|
else if (synapse.nucleus is Receptor receptor2) // && receptor2.array != null && receptor2.array.nuclei.Length > 1)
|
||||||
|
array = receptor2.array;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
if (Application.isPlaying) {
|
||||||
|
Vector3 value = synapse.nucleus.outputValue * synapse.weight;
|
||||||
|
GUIContent synapseValueLabel = new(synapse.nucleus.name, synapse.nucleus.outputValue.ToString());
|
||||||
|
EditorGUILayout.FloatField(synapseValueLabel, length(synapse.nucleus.outputValue));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
|
||||||
|
if (synapse.nucleus.parent != null && synapse.nucleus.parent != this.currentNucleus) {
|
||||||
|
GUIStyle labelStyle = new(GUI.skin.label);
|
||||||
|
float labelWidth = labelStyle.CalcSize(new GUIContent($"{synapse.nucleus.clusterPrefab.name}.")).x;
|
||||||
|
EditorGUILayout.LabelField($"{synapse.nucleus.clusterPrefab.name}", GUILayout.Width(labelWidth));
|
||||||
|
string[] options = synapse.nucleus.parent.clusterNuclei.Select(n => n.name).ToArray();
|
||||||
|
int selectedIndex = System.Array.IndexOf(options, synapse.nucleus.name);
|
||||||
|
int newIndex = EditorGUILayout.Popup(selectedIndex, options);
|
||||||
|
if (newIndex != selectedIndex && synapse.nucleus.parent.clusterNuclei[newIndex] is Neuron newNeuron)
|
||||||
|
ChangeSynapse(synapse, newNeuron);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
EditorGUILayout.LabelField(synapse.nucleus.name);
|
||||||
|
if (GUILayout.Button("Disconnect") && synapse.nucleus is Neuron synapseNeuron) {
|
||||||
|
synapseNeuron.RemoveReceiver(this.currentNucleus);
|
||||||
|
this.prefab.GarbageCollection();
|
||||||
|
anythingChanged = true;
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.indentLevel++;
|
||||||
|
synapse.weight = EditorGUILayout.FloatField("Weight", synapse.weight);
|
||||||
|
EditorGUI.indentLevel--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activation
|
// Activation
|
||||||
|
|
||||||
EditorGUILayout.Space();
|
EditorGUILayout.Space();
|
||||||
@ -811,7 +826,7 @@ public class ClusterInspector : Editor {
|
|||||||
|
|
||||||
|
|
||||||
if (GUILayout.Button("Delete this neuron"))
|
if (GUILayout.Button("Delete this neuron"))
|
||||||
DeleteNeuron(this.currentNucleus);
|
DeleteNucleus(this.currentNucleus);
|
||||||
|
|
||||||
if (this.currentNucleus is Cluster subCluster) {
|
if (this.currentNucleus is Cluster subCluster) {
|
||||||
if (GUILayout.Button("Edit Cluster"))
|
if (GUILayout.Button("Edit Cluster"))
|
||||||
@ -934,10 +949,10 @@ public class ClusterInspector : Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AddReceptorArrayInput(Nucleus nucleus) {
|
protected virtual void AddReceptorArrayInput(Nucleus nucleus) {
|
||||||
ReceptorArray newReceptor = new(this.prefab, "New Receptor");
|
// ReceptorArray newReceptor = new(this.prefab, "New Receptor");
|
||||||
newReceptor.AddReceiver(nucleus);
|
// newReceptor.AddReceiver(nucleus);
|
||||||
this.currentNucleus = newReceptor;
|
// this.currentNucleus = newReceptor;
|
||||||
BuildLayers();
|
// BuildLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AddClusterReceptorInput(Nucleus nucleus) {
|
protected virtual void AddClusterReceptorInput(Nucleus nucleus) {
|
||||||
@ -946,12 +961,12 @@ public class ClusterInspector : Editor {
|
|||||||
|
|
||||||
private void OnClusterPicked(Nucleus nucleus, ClusterPrefab prefab) {
|
private void OnClusterPicked(Nucleus nucleus, ClusterPrefab prefab) {
|
||||||
Cluster subclusterInstance = new(prefab, this.prefab);
|
Cluster subclusterInstance = new(prefab, this.prefab);
|
||||||
subclusterInstance.AddReceiver(nucleus);
|
subclusterInstance.defaultOutput.AddReceiver(nucleus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClusterReceptorPicked(Nucleus nucleus, ClusterPrefab selectedPrefab) {
|
private void OnClusterReceptorPicked(Nucleus nucleus, ClusterPrefab selectedPrefab) {
|
||||||
ClusterReceptor clusterInstance = new(selectedPrefab, this.prefab, "New " + selectedPrefab.name);
|
ClusterReceptor clusterInstance = new(selectedPrefab, this.prefab, "New " + selectedPrefab.name);
|
||||||
clusterInstance.AddReceiver(nucleus);
|
clusterInstance.defaultOutput.AddReceiver(nucleus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EditCluster(Cluster subCluster) {
|
private void EditCluster(Cluster subCluster) {
|
||||||
@ -962,7 +977,7 @@ public class ClusterInspector : Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect to another nucleus in the same cluster
|
// Connect to another nucleus in the same cluster
|
||||||
protected virtual bool ConnectNucleus(ClusterPrefab cluster, Nucleus nucleus) {
|
protected virtual bool ConnectNucleus(ClusterPrefab cluster, Nucleus nucleusToConnect) {
|
||||||
if (cluster == null)
|
if (cluster == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -980,19 +995,25 @@ public class ClusterInspector : Editor {
|
|||||||
if (selectedIndex < 0)
|
if (selectedIndex < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Nucleus receptor = nuclei.ElementAt(selectedIndex);
|
Nucleus nucleus = nuclei.ElementAt(selectedIndex);
|
||||||
receptor.AddReceiver(this.currentNucleus);
|
if (nucleus is Neuron neuron)
|
||||||
|
neuron.AddReceiver(this.currentNucleus);
|
||||||
|
else if (nucleus is Cluster subCluster)
|
||||||
|
subCluster.defaultOutput.AddReceiver(this.currentNucleus);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void DeleteNeuron(Nucleus nucleus) {
|
protected virtual void DeleteNucleus(Nucleus nucleus) {
|
||||||
if (nucleus == null)
|
if (nucleus == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (Nucleus receiver in nucleus.receivers) {
|
if (nucleus is Neuron neuron) {
|
||||||
if (receiver != null) {
|
foreach (Nucleus receiver in neuron.receivers) {
|
||||||
this.currentNucleus = receiver;
|
if (receiver != null) {
|
||||||
break;
|
this.currentNucleus = receiver;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.prefab.nuclei.Remove(nucleus);
|
this.prefab.nuclei.Remove(nucleus);
|
||||||
@ -1021,9 +1042,17 @@ public class ClusterInspector : Editor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void ChangeSynapse(Synapse synapse, Nucleus newNucleus) {
|
protected virtual void ChangeSynapse(Synapse synapse, Neuron newNucleus) {
|
||||||
synapse.nucleus.RemoveReceiver(this.currentNucleus);
|
Neuron synapseNeuron = synapse.nucleus as Neuron;
|
||||||
newNucleus.AddReceiver(this.currentNucleus);
|
if (synapse.nucleus.parent is Cluster subCluster && subCluster.prefab != this.prefab) {
|
||||||
|
// it is a neuron in a subcluster
|
||||||
|
synapseNeuron.RemoveReceiver(this.currentNucleus);
|
||||||
|
newNucleus.AddReceiver(this.currentNucleus);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
synapseNeuron.RemoveReceiver(this.currentNucleus);
|
||||||
|
newNucleus.AddReceiver(this.currentNucleus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void DisconnectNucleus(Neuron nucleus) {
|
protected virtual void DisconnectNucleus(Neuron nucleus) {
|
||||||
@ -1032,10 +1061,10 @@ public class ClusterInspector : Editor {
|
|||||||
string[] names = this.currentNucleus.synapses.Select(synapse => synapse.nucleus.name).ToArray();
|
string[] names = this.currentNucleus.synapses.Select(synapse => synapse.nucleus.name).ToArray();
|
||||||
int selectedIndex = -1;
|
int selectedIndex = -1;
|
||||||
selectedIndex = EditorGUILayout.Popup("Disconnect from", selectedIndex, names);
|
selectedIndex = EditorGUILayout.Popup("Disconnect from", selectedIndex, names);
|
||||||
//if (selectedIndex >= 0 && selectedIndex < this.currentNucleus.brain.perceptei.Count) {
|
|
||||||
if (selectedIndex >= 0 && selectedIndex < this.currentNucleus.clusterPrefab.nuclei.Count) {
|
if (selectedIndex >= 0 && selectedIndex < this.currentNucleus.clusterPrefab.nuclei.Count) {
|
||||||
Synapse synapse = this.currentNucleus.synapses[selectedIndex];
|
Synapse synapse = this.currentNucleus.synapses[selectedIndex];
|
||||||
synapse.nucleus.RemoveReceiver(this.currentNucleus);
|
Neuron synapseNeuron = synapse.nucleus as Neuron;
|
||||||
|
synapseNeuron.RemoveReceiver(this.currentNucleus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public class NanoBrainComponent_Editor : Editor {
|
|||||||
root.Add(brainField);
|
root.Add(brainField);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClusterInspector.CreateInspector(root, brain.prefab, brain.output, component.gameObject);
|
ClusterInspector.CreateInspector(root, brain.prefab, brain.defaultOutput, component.gameObject);
|
||||||
|
|
||||||
if (Application.isPlaying == false)
|
if (Application.isPlaying == false)
|
||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
|||||||
5
IReceptor.cs
Normal file
5
IReceptor.cs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
public interface IReceptor {
|
||||||
|
public NucleusArray array {
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
IReceptor.cs.meta
Normal file
2
IReceptor.cs.meta
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 73f052292ad16bb53a3c07aa1694c705
|
||||||
@ -18,7 +18,7 @@ public class NanoBrain : MonoBehaviour {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateWeight(Cluster brain, string name, float weight) {
|
public static void UpdateWeight(Cluster brain, string name, float weight) {
|
||||||
Nucleus root = brain.output;
|
Nucleus root = brain.defaultOutput;
|
||||||
foreach (Synapse synapse in root.synapses) {
|
foreach (Synapse synapse in root.synapses) {
|
||||||
if (synapse.nucleus.name == name) {
|
if (synapse.nucleus.name == name) {
|
||||||
if (synapse.weight != weight) {
|
if (synapse.weight != weight) {
|
||||||
|
|||||||
54
Neuron.cs
54
Neuron.cs
@ -12,7 +12,7 @@ public class Neuron : Nucleus {
|
|||||||
public Neuron(Cluster parent, string name) {
|
public Neuron(Cluster parent, string name) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.parent?.nuclei.Add(this);
|
this.parent?.clusterNuclei.Add(this);
|
||||||
}
|
}
|
||||||
public Neuron(ClusterPrefab prefab, string name) {
|
public Neuron(ClusterPrefab prefab, string name) {
|
||||||
this.clusterPrefab = prefab;
|
this.clusterPrefab = prefab;
|
||||||
@ -25,7 +25,6 @@ public class Neuron : Nucleus {
|
|||||||
|
|
||||||
#region Serialization
|
#region Serialization
|
||||||
|
|
||||||
//public Type type = Type.Neuron;
|
|
||||||
public enum CombinatorType {
|
public enum CombinatorType {
|
||||||
Sum,
|
Sum,
|
||||||
Product,
|
Product,
|
||||||
@ -160,11 +159,14 @@ public class Neuron : Nucleus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (Nucleus receiver in nucleus.receivers) {
|
if (nucleus is Neuron neuron) {
|
||||||
if (receiver != null && receiver.synapses != null)
|
foreach (Nucleus receiver in neuron.receivers) {
|
||||||
receiver.synapses.RemoveAll(s => s.nucleus == nucleus);
|
if (receiver != null && receiver.synapses != null)
|
||||||
|
receiver.synapses.RemoveAll(s => s.nucleus == nucleus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (nucleus.clusterPrefab != null) {
|
if (nucleus.clusterPrefab != null) {
|
||||||
nucleus.clusterPrefab.nuclei.RemoveAll(n => n == nucleus);
|
nucleus.clusterPrefab.nuclei.RemoveAll(n => n == nucleus);
|
||||||
nucleus.clusterPrefab.GarbageCollection();
|
nucleus.clusterPrefab.GarbageCollection();
|
||||||
@ -259,6 +261,48 @@ public class Neuron : Nucleus {
|
|||||||
|
|
||||||
#endregion Activator
|
#endregion Activator
|
||||||
|
|
||||||
|
#region Receivers
|
||||||
|
|
||||||
|
[SerializeReference]
|
||||||
|
private List<Nucleus> _receivers = new();
|
||||||
|
public virtual List<Nucleus> receivers {
|
||||||
|
get { return _receivers; }
|
||||||
|
set { _receivers = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void AddReceiver(Nucleus receiverToAdd, float weight = 1) {
|
||||||
|
if (this is IReceptor receptor) {
|
||||||
|
foreach (Nucleus element in receptor.array.nuclei) {
|
||||||
|
if (element is Neuron neuron) {
|
||||||
|
neuron._receivers.Add(receiverToAdd);
|
||||||
|
receiverToAdd.AddSynapse(element, weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._receivers.Add(receiverToAdd);
|
||||||
|
receiverToAdd.AddSynapse(this, weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void RemoveReceiver(Nucleus receiverToRemove) {
|
||||||
|
if (this is IReceptor receptor) {
|
||||||
|
foreach (Nucleus element in receptor.array.nuclei) {
|
||||||
|
if (element is Neuron neuron) {
|
||||||
|
neuron._receivers.RemoveAll(receiver => receiver == receiverToRemove);
|
||||||
|
receiverToRemove.synapses.RemoveAll(synapse => synapse.nucleus == neuron);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._receivers.RemoveAll(receiver => receiver == receiverToRemove);
|
||||||
|
receiverToRemove.synapses.RemoveAll(synapse => synapse.nucleus == this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion Receivers
|
||||||
|
|
||||||
public virtual void ProcessStimulus(Vector3 inputValue, string thingName = null) {
|
public virtual void ProcessStimulus(Vector3 inputValue, string thingName = null) {
|
||||||
this.stale = 0;
|
this.stale = 0;
|
||||||
this.bias = inputValue;
|
this.bias = inputValue;
|
||||||
|
|||||||
25
Nucleus.cs
25
Nucleus.cs
@ -17,7 +17,6 @@ public abstract class Nucleus {
|
|||||||
public virtual float3 outputValue {
|
public virtual float3 outputValue {
|
||||||
get { return _outputValue; }
|
get { return _outputValue; }
|
||||||
set {
|
set {
|
||||||
//this.stale = 0;
|
|
||||||
_outputValue = value;
|
_outputValue = value;
|
||||||
if (this.isFiring)
|
if (this.isFiring)
|
||||||
WhenFiring?.Invoke();
|
WhenFiring?.Invoke();
|
||||||
@ -68,29 +67,13 @@ public abstract class Nucleus {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveSynapse(Nucleus sendingNucleus) {
|
||||||
|
this.synapses.RemoveAll(synapse => synapse.nucleus == sendingNucleus);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Synapses
|
#endregion Synapses
|
||||||
|
|
||||||
#region Receivers
|
|
||||||
|
|
||||||
[SerializeReference]
|
|
||||||
private List<Nucleus> _receivers = new();
|
|
||||||
public virtual List<Nucleus> receivers {
|
|
||||||
get { return _receivers; }
|
|
||||||
set { _receivers = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void AddReceiver(Nucleus receivingNucleus, float weight = 1) {
|
|
||||||
this._receivers.Add(receivingNucleus);
|
|
||||||
receivingNucleus.AddSynapse(this, weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveReceiver(Nucleus receiverNucleus) {
|
|
||||||
this._receivers.RemoveAll(receiver => receiver == receiverNucleus);
|
|
||||||
receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endregion Receivers
|
|
||||||
|
|
||||||
#region Update
|
#region Update
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using Unity.Mathematics;
|
|||||||
using static Unity.Mathematics.math;
|
using static Unity.Mathematics.math;
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class Receptor : Neuron {
|
public class Receptor : Neuron, IReceptor {
|
||||||
public Receptor(Cluster parent, string name) : base(parent, name) { }
|
public Receptor(Cluster parent, string name) : base(parent, name) { }
|
||||||
public Receptor(ClusterPrefab prefab, string name) : base(prefab, name) { }
|
public Receptor(ClusterPrefab prefab, string name) : base(prefab, name) { }
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ public class ReceptorArray : Nucleus {
|
|||||||
this._instances[0] = new ReceptorInstance(parent, this.name + "[0]") {
|
this._instances[0] = new ReceptorInstance(parent, this.name + "[0]") {
|
||||||
receptor = this
|
receptor = this
|
||||||
};
|
};
|
||||||
this.parent?.nuclei.Add(this);
|
this.parent?.clusterNuclei.Add(this);
|
||||||
}
|
}
|
||||||
public ReceptorArray(ClusterPrefab prefab, string name) {
|
public ReceptorArray(ClusterPrefab prefab, string name) {
|
||||||
this.clusterPrefab = prefab;
|
this.clusterPrefab = prefab;
|
||||||
@ -89,9 +89,9 @@ public class ReceptorArray : Nucleus {
|
|||||||
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
|
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
|
||||||
clonedSynapse.weight = synapse.weight;
|
clonedSynapse.weight = synapse.weight;
|
||||||
}
|
}
|
||||||
foreach (Nucleus receiver in this.receivers) {
|
// foreach (Nucleus receiver in this.receivers) {
|
||||||
clone.AddReceiver(receiver);
|
// clone.AddReceiver(receiver);
|
||||||
}
|
// }
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user