Process clusterreceptor per thingId
This commit is contained in:
parent
3cdca017d6
commit
abbce40992
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
using System.Linq;
|
||||
|
||||
[Serializable]
|
||||
public class ClusterReceptor : Cluster, IReceptor {
|
||||
@ -71,7 +72,7 @@ public class ClusterReceptor : Cluster, IReceptor {
|
||||
foreach (Nucleus outputNucleus in clusterElement.clusterNuclei) {
|
||||
if (outputNucleus is not Neuron output)
|
||||
continue;
|
||||
|
||||
|
||||
// this should be clusterElement.outputs,
|
||||
// but outputs is not updated when correctly and may contain old data...
|
||||
foreach (Nucleus receiver in output.receivers) {
|
||||
@ -138,4 +139,73 @@ public class ClusterReceptor : Cluster, IReceptor {
|
||||
this._array ??= new NucleusArray(this.parent);
|
||||
this._array.ProcessStimulus(thingId, inputValue, thingName);
|
||||
}
|
||||
|
||||
private Dictionary<int, ClusterReceptor> thingReceivers = new();
|
||||
|
||||
public virtual void ProcessStimulus(Neuron input, Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||
inputValue = input.Activator(inputValue);
|
||||
|
||||
if (!thingReceivers.TryGetValue(thingId, out ClusterReceptor selectedReceiver))
|
||||
selectedReceiver = FindReceiver(thingId, inputValue);
|
||||
if (selectedReceiver == null)
|
||||
return;
|
||||
|
||||
if (thingName != null) {
|
||||
string baseName = selectedReceiver.name;
|
||||
int colonPos = selectedReceiver.name.IndexOf(":");
|
||||
if (colonPos > 0)
|
||||
baseName = selectedReceiver.name[..colonPos];
|
||||
selectedReceiver.name = baseName + ": " + thingName;
|
||||
}
|
||||
|
||||
int inputIx = this.GetNucleusIndex(this.clusterNuclei, input);
|
||||
if (inputIx < 0)
|
||||
return;
|
||||
|
||||
if (selectedReceiver.clusterNuclei[inputIx] is Neuron selectedNeuron)
|
||||
selectedNeuron.ProcessStimulusDirect(inputValue);
|
||||
}
|
||||
|
||||
private ClusterReceptor FindReceiver(int thingId, float3 inputValue) {
|
||||
// No existing nucleus for this thing
|
||||
float inputMagnitude = length(inputValue);
|
||||
ClusterReceptor selectedReceiver = null;
|
||||
float selectedMagnitude = 0;
|
||||
foreach (ClusterReceptor receiver in nucleiArray.Cast<ClusterReceptor>()) {
|
||||
if (thingReceivers.ContainsValue(receiver) == false) {
|
||||
// We found an unusued receiver
|
||||
thingReceivers.Add(thingId, receiver);
|
||||
return receiver;
|
||||
}
|
||||
else if (receiver.isSleeping) {
|
||||
// A sleeping receiver is not active and can therefore always be used
|
||||
thingReceivers.Add(thingId, receiver);
|
||||
return receiver;
|
||||
}
|
||||
else if (selectedReceiver == null) {
|
||||
// If we haven't found a receiver yet, just start by taking the first
|
||||
selectedReceiver = receiver;
|
||||
selectedMagnitude = length(selectedReceiver.outputValue);
|
||||
}
|
||||
// Look for the receiver with the lowest magnitude
|
||||
else {
|
||||
float magnitude = length(receiver.outputValue);
|
||||
|
||||
if (magnitude < inputMagnitude && length(receiver.outputValue) < selectedMagnitude) {
|
||||
selectedReceiver = receiver;
|
||||
selectedMagnitude = length(selectedReceiver.outputValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selectedReceiver != null) {
|
||||
// Replace the receiver
|
||||
// Find the thingId current associated with the receiver
|
||||
int keyToRemove = thingReceivers.FirstOrDefault(r => r.Value.Equals(selectedReceiver)).Key;
|
||||
if (keyToRemove != 0 || thingReceivers.ContainsKey(keyToRemove))
|
||||
thingReceivers.Remove(keyToRemove);
|
||||
// And add the new association
|
||||
thingReceivers.Add(thingId, selectedReceiver);
|
||||
}
|
||||
return selectedReceiver;
|
||||
}
|
||||
}
|
||||
@ -806,16 +806,8 @@ public class ClusterInspector : Editor {
|
||||
|
||||
void OnSceneGUI(SceneView sceneView) {
|
||||
if (this.gameObject != null) {
|
||||
// if (this.currentNucleus is ReceptorArray receptor && expandArray) {
|
||||
// foreach (Nucleus nucleus in receptor.instances) {
|
||||
// Vector3 worldVector = this.gameObject.transform.TransformVector(nucleus.outputValue);
|
||||
// Handles.color = Color.yellow;
|
||||
// Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
if (this.currentNucleus is Receptor receptor1) {
|
||||
foreach (Nucleus nucleus in receptor1.nucleiArray) {
|
||||
if (this.currentNucleus is IReceptor receptor) {
|
||||
foreach (Nucleus nucleus in receptor.nucleiArray) {
|
||||
Vector3 worldVector = this.gameObject.transform.TransformVector(nucleus.outputValue);
|
||||
Handles.color = Color.yellow;
|
||||
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
||||
@ -825,9 +817,7 @@ public class ClusterInspector : Editor {
|
||||
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue);
|
||||
Handles.color = Color.yellow;
|
||||
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
||||
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1016,7 +1006,7 @@ public class ClusterInspector : Editor {
|
||||
// so we have to change all synapses to this nucleus array elements
|
||||
int oldNucleusIx = subCluster.GetNucleusIndex(subCluster.clusterNuclei, synapse.nucleus);
|
||||
int newNucleusIx = subCluster.GetNucleusIndex(subCluster.clusterNuclei, newNucleus);
|
||||
foreach(Nucleus element in receptor.nucleiArray) {
|
||||
foreach (Nucleus element in receptor.nucleiArray) {
|
||||
if (element is not ClusterReceptor clusterReceptor)
|
||||
continue;
|
||||
// Get the same neuron as the synapse.nucleus in a different element
|
||||
@ -1029,14 +1019,15 @@ public class ClusterInspector : Editor {
|
||||
Nucleus newElementNucleus = clusterReceptor.clusterNuclei[newNucleusIx];
|
||||
if (newElementNucleus is not Neuron newElementNeuron)
|
||||
continue;
|
||||
|
||||
|
||||
oldElementNeuron.RemoveReceiver(this.currentNucleus);
|
||||
newElementNeuron.AddReceiver(this.currentNucleus);
|
||||
// Now find the synapse which pointed to the old Neuron
|
||||
// Synapse synapseForUpdate = this.currentNucleus.GetSynapse(oldElementNeuron);
|
||||
// synapseForUpdate.nucleus = newElementNeuron;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// it is a neuron in a subcluster
|
||||
synapseNeuron.RemoveReceiver(this.currentNucleus);
|
||||
newNucleus.AddReceiver(this.currentNucleus);
|
||||
|
||||
@ -312,7 +312,10 @@ public class Neuron : Nucleus {
|
||||
#endregion Receivers
|
||||
|
||||
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||
ProcessStimulusDirect(inputValue, thingId, thingName);
|
||||
if (this.parent is ClusterReceptor clusterReceptor) {
|
||||
clusterReceptor.ProcessStimulus(this, inputValue, thingId, thingName);
|
||||
} else
|
||||
ProcessStimulusDirect(inputValue, thingId, thingName);
|
||||
// this.stale = 0;
|
||||
// this.bias = inputValue;
|
||||
// this.parent.UpdateFromNucleus(this);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user