Cleanup
This commit is contained in:
parent
8a9700981b
commit
ccb7a41577
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
@ -48,7 +47,6 @@ public class Cluster : Nucleus {
|
||||
Nucleus[] prefabNuclei = this.prefab.nuclei.ToArray();
|
||||
// first clone the nuclei without their connections
|
||||
foreach (Nucleus nucleus in this.prefab.nuclei) {
|
||||
// Debug.Log($"prefab clone {nucleus.name}");
|
||||
nucleus.ShallowCloneTo(this);
|
||||
}
|
||||
Nucleus[] clonedNuclei = this.clusterNuclei.ToArray();
|
||||
@ -477,9 +475,6 @@ public class Cluster : Nucleus {
|
||||
Debug.Log($" {nucleus.name}[{nucleus.GetHashCode()}] = {neuron.outputValue}");
|
||||
}
|
||||
|
||||
// this.outputValue = this.defaultOutput.outputValue;
|
||||
// this.stale = 0;
|
||||
|
||||
// continue in parent
|
||||
this.parent?.UpdateFromNucleus(this);
|
||||
|
||||
@ -494,7 +489,6 @@ public class Cluster : Nucleus {
|
||||
if (synapse.nucleus is Neuron neuron) {
|
||||
if (lengthsq(neuron.outputValue) > 0) {
|
||||
sum += synapse.weight * neuron.outputValue;
|
||||
//this.stale = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -502,9 +496,6 @@ public class Cluster : Nucleus {
|
||||
foreach (Nucleus nucleus in this.sortedNuclei)
|
||||
nucleus.UpdateStateIsolated();
|
||||
|
||||
// this.outputValue = this.defaultOutput.outputValue;
|
||||
// this.stale = 0;
|
||||
|
||||
UpdateNuclei();
|
||||
}
|
||||
|
||||
|
||||
@ -64,7 +64,6 @@ public class ClusterPrefab : ScriptableObject {
|
||||
HashSet<Nucleus> visitedNuclei = new();
|
||||
foreach (Nucleus output in this.outputs)
|
||||
MarkNuclei(visitedNuclei, output);
|
||||
//MarkNuclei(visitedNuclei, this.output);
|
||||
//Debug.Log($"Garbage collection found {visitedNuclei.Count} Nuclei");
|
||||
this.nuclei.RemoveAll(nucleus => visitedNuclei.Contains(nucleus) == false);
|
||||
}
|
||||
|
||||
@ -26,12 +26,7 @@ public class ClusterReceptor : Cluster, IReceptor {
|
||||
public override Nucleus ShallowCloneTo(Cluster parent) {
|
||||
ClusterReceptor clone = new(this.prefab, parent, this.name) {
|
||||
clusterPrefab = this.clusterPrefab,
|
||||
//array = this.array
|
||||
};
|
||||
//CloneFields(clone);
|
||||
// This cloned the prefab with the clusternuclei,
|
||||
// but did not clone the receivers outside the cluster
|
||||
//RestoreExternalReceivers(clone, this.clusterPrefab, parent);
|
||||
|
||||
return clone;
|
||||
}
|
||||
@ -41,16 +36,11 @@ public class ClusterReceptor : Cluster, IReceptor {
|
||||
array = this._array
|
||||
};
|
||||
|
||||
//CloneFields(clone);
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
|
||||
clonedSynapse.weight = synapse.weight;
|
||||
}
|
||||
|
||||
// foreach (Nucleus receiver in this.receivers) {
|
||||
// clone.AddReceiver(receiver);
|
||||
// }
|
||||
|
||||
this._outputs = null; // Make sure the output are regenerated
|
||||
foreach (Neuron output in this.outputs) {
|
||||
int ix = GetNucleusIndex(this.clusterNuclei, output);
|
||||
@ -89,19 +79,14 @@ public class ClusterReceptor : Cluster, IReceptor {
|
||||
[SerializeReference]
|
||||
private NucleusArray _array;
|
||||
public NucleusArray array {
|
||||
//get { return _array; }
|
||||
set { _array = value; }
|
||||
}
|
||||
|
||||
//[SerializeReference]
|
||||
//private Nucleus[] _nucleusArray;
|
||||
public Nucleus[] nucleiArray {
|
||||
get { return _array.nuclei; }
|
||||
set { _array.nuclei = value; }
|
||||
}
|
||||
|
||||
//public ClusterReceptor[] nucleiArray;
|
||||
|
||||
public void AddReceptorElement(ClusterPrefab prefab) {
|
||||
IReceptorHelpers.AddReceptorElement(this, prefab);
|
||||
}
|
||||
@ -118,32 +103,14 @@ public class ClusterReceptor : Cluster, IReceptor {
|
||||
// Clusters don't do anything,
|
||||
// The nuclei in them do the work
|
||||
// and should be called directly, not from the cluster
|
||||
|
||||
// float3 sum = this.bias;
|
||||
|
||||
// foreach (Nucleus nucleus in this.sortedNuclei)
|
||||
// nucleus.UpdateStateIsolated();
|
||||
|
||||
// this.outputValue = this.defaultOutput.outputValue;
|
||||
// this.stale = 0;
|
||||
|
||||
// UpdateNuclei();
|
||||
}
|
||||
|
||||
public override void UpdateNuclei() {
|
||||
// this.stale++;
|
||||
// if (this.stale > staleValueForSleep && lengthsq(this.bias) > 0) {
|
||||
// this.bias = new float3(0, 0, 0);
|
||||
// this.parent.UpdateFromNucleus(this);
|
||||
// }
|
||||
|
||||
foreach (Nucleus nucleus in this.clusterNuclei)
|
||||
nucleus.UpdateNuclei();
|
||||
}
|
||||
|
||||
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||
//this._array ??= new NucleusArray(this.parent);
|
||||
//this._array.ProcessStimulus(thingId, inputValue, thingName);
|
||||
Debug.LogError("Process Stimulus was called on clusterreceptor without a neuron specified");
|
||||
}
|
||||
|
||||
@ -152,9 +119,6 @@ public class ClusterReceptor : Cluster, IReceptor {
|
||||
public virtual void ProcessStimulus(Neuron input, Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||
CleanupReceivers();
|
||||
|
||||
// Debug.Log($"{input.name} is {inputValue}, 1/{inputValue} = {1 / inputValue.x}, {1/inputValue.y}, {1/inputValue.z}");
|
||||
//inputValue = input.Activator(inputValue);
|
||||
|
||||
if (!thingReceivers.TryGetValue(thingId, out ClusterReceptor selectedReceiver))
|
||||
selectedReceiver = FindReceiver2(thingId, inputValue, input);
|
||||
if (selectedReceiver == null)
|
||||
@ -174,52 +138,8 @@ public class ClusterReceptor : Cluster, IReceptor {
|
||||
|
||||
if (selectedReceiver.clusterNuclei[inputIx] is Neuron selectedNeuron)
|
||||
selectedNeuron.ProcessStimulusDirect(inputValue);
|
||||
// Debug.Log($"cluster output = {selectedReceiver.defaultOutput.outputValue}");
|
||||
}
|
||||
|
||||
// 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;
|
||||
// }
|
||||
|
||||
private ClusterReceptor FindReceiver2(int thingId, float3 inputValue, Neuron input) {
|
||||
// No existing nucleus for this thing
|
||||
ClusterReceptor selectedReceiver = null;
|
||||
|
||||
@ -3,9 +3,6 @@ using UnityEngine;
|
||||
public interface IReceptor {
|
||||
public string GetName();
|
||||
|
||||
// public NucleusArray array {
|
||||
// get; set;
|
||||
// }
|
||||
public Nucleus[] nucleiArray { get; set; }
|
||||
|
||||
public void AddReceptorElement(ClusterPrefab prefab);
|
||||
@ -54,7 +51,7 @@ public static class IReceptorHelpers {
|
||||
newArray[i] = receptor.nucleiArray[i];
|
||||
// Delete the last perception
|
||||
if (receptor.nucleiArray[newLength] is Nucleus nucleus)
|
||||
Neuron.Delete(nucleus); //this._nuclei[newLength]);
|
||||
Neuron.Delete(nucleus);
|
||||
|
||||
foreach (Nucleus element in receptor.nucleiArray) {
|
||||
if (element is IReceptor receptorElement) {
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
|
||||
[Serializable]
|
||||
public class MemoryCell : Neuron {
|
||||
|
||||
14
Neuron.cs
14
Neuron.cs
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using Unity.Mathematics;
|
||||
@ -303,18 +302,8 @@ public class Neuron : Nucleus {
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -341,9 +330,6 @@ public class Neuron : Nucleus {
|
||||
}
|
||||
else
|
||||
ProcessStimulusDirect(inputValue, thingId, thingName);
|
||||
// this.stale = 0;
|
||||
// this.bias = inputValue;
|
||||
// this.parent.UpdateFromNucleus(this);
|
||||
}
|
||||
|
||||
public void ProcessStimulusDirect(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||
|
||||
22
Nucleus.cs
22
Nucleus.cs
@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
|
||||
[Serializable]
|
||||
public abstract class Nucleus {
|
||||
@ -13,22 +11,6 @@ public abstract class Nucleus {
|
||||
[SerializeReference]
|
||||
public Cluster parent;
|
||||
|
||||
// protected float3 _outputValue;
|
||||
// public virtual float3 outputValue {
|
||||
// get { return _outputValue; }
|
||||
// set {
|
||||
// _outputValue = value;
|
||||
// if (this.isFiring)
|
||||
// WhenFiring?.Invoke();
|
||||
// }
|
||||
// }
|
||||
// public bool isFiring => length(_outputValue) > 0.5f;
|
||||
// public Action WhenFiring;
|
||||
|
||||
// public virtual bool isSleeping => lengthsq(this.outputValue) == 0;
|
||||
// [NonSerialized]
|
||||
// public int stale = 1000;
|
||||
// public readonly int staleValueForSleep = 20;
|
||||
public bool trace = false;
|
||||
|
||||
public abstract Nucleus ShallowCloneTo(Cluster parent);
|
||||
@ -38,11 +20,8 @@ public abstract class Nucleus {
|
||||
None,
|
||||
Neuron,
|
||||
MemoryCell,
|
||||
Selector,
|
||||
Cluster,
|
||||
Pulsar,
|
||||
Receptor,
|
||||
// ReceptorArray,
|
||||
ClusterReceptor,
|
||||
}
|
||||
|
||||
@ -81,7 +60,6 @@ public abstract class Nucleus {
|
||||
}
|
||||
|
||||
public virtual void SetBias(Vector3 inputValue) {
|
||||
//this.stale = 0;
|
||||
this.bias = inputValue;
|
||||
this.parent.UpdateFromNucleus(this);
|
||||
}
|
||||
|
||||
105
Perceptoid.cs
105
Perceptoid.cs
@ -1,105 +0,0 @@
|
||||
/*
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class Perceptoid : Neuroid {
|
||||
// A neuroid which has no neurons as input
|
||||
// But receives value from a receptor
|
||||
|
||||
public NanoBrain brain;
|
||||
public Receptor receptor;
|
||||
public string baseName;
|
||||
|
||||
public int thingId;
|
||||
|
||||
//[SerializeField]
|
||||
// Needs serialization!!!!
|
||||
[SerializeReference]
|
||||
public PercepteiArray array;
|
||||
|
||||
#region Serialization
|
||||
|
||||
[SerializeField]
|
||||
public int thingType;
|
||||
|
||||
public override void Rebuild(NanoBrain brain) {
|
||||
base.Rebuild(brain);
|
||||
this.receptor = Receptor.GetReceptor(brain, thingType);
|
||||
this.receptor.perceptei.Add(this);
|
||||
if (string.IsNullOrEmpty(this.baseName))
|
||||
this.baseName = this.name;
|
||||
}
|
||||
|
||||
public override void Deserialize(Nucleus nucleus) {
|
||||
base.Deserialize(nucleus);
|
||||
|
||||
if (nucleus is Perceptoid perceptoid)
|
||||
this.receptor.thingType = perceptoid.thingType;
|
||||
|
||||
// Point all receivers to this perceptoid instead of the default nucleus
|
||||
foreach (INucleus receiver in nucleus.receivers) {
|
||||
foreach (Synapse synapse in receiver.synapses) {
|
||||
if (synapse.nucleus == nucleus)
|
||||
synapse.nucleus = this;
|
||||
}
|
||||
}
|
||||
// Point all synapses to this perceptoid instead of the default nucleus
|
||||
// foreach (Synapse synapse in nucleus.synapses) {
|
||||
// foreach (INucleus r in synapse.nucleus.receivers) {
|
||||
// if (r == nucleus)
|
||||
// this.receiver = this;
|
||||
// }
|
||||
// }
|
||||
// Copying disabled for now
|
||||
// // Copy all the synapses
|
||||
// this.synapses = nucleus.synapses;
|
||||
// // Copy all receivers
|
||||
// this.receivers = nucleus.receivers;
|
||||
}
|
||||
|
||||
#endregion Serialization
|
||||
|
||||
public Perceptoid(NanoBrain brain, int thingType, string name = "sensor") : base(name) {
|
||||
this.brain = brain;
|
||||
this.cluster = brain.cluster;
|
||||
if (this.cluster != null) {
|
||||
brain.perceptei.Add(this);
|
||||
}
|
||||
else
|
||||
Debug.LogError("No neuroid network");
|
||||
|
||||
this.nucleusType = nameof(Perceptoid);
|
||||
this.name = name;
|
||||
this.baseName = name;
|
||||
this.thingType = thingType;
|
||||
this.receptor = Receptor.GetReceptor(brain, thingType);
|
||||
this.receptor.perceptei.Add(this);
|
||||
this.array = new PercepteiArray(this);
|
||||
}
|
||||
|
||||
public Perceptoid(PercepteiArray array) : base(array.name) {
|
||||
this.array = array;
|
||||
Perceptoid source = array.perceptei[0];
|
||||
this.brain = source.brain;
|
||||
this.cluster = source.cluster;
|
||||
if (this.brain != null) {
|
||||
this.brain.perceptei.Add(this);
|
||||
}
|
||||
else
|
||||
Debug.LogError("No neuroid network");
|
||||
|
||||
this.nucleusType = nameof(Perceptoid);
|
||||
this.name = source.baseName;
|
||||
this.baseName = source.baseName;
|
||||
this.thingType = source.thingType;
|
||||
this.receptor = Receptor.GetReceptor(this.brain, this.thingType);
|
||||
this.receptor.perceptei.Add(this);
|
||||
}
|
||||
|
||||
public override void UpdateState() {
|
||||
Vector3 result = this.receptor.localPosition;
|
||||
UpdateResult(result);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 702f634001a21a9d7ae1057c8ce356e9
|
||||
17
Receptor.cs
17
Receptor.cs
@ -48,36 +48,19 @@ public class Receptor : Neuron, IReceptor {
|
||||
}
|
||||
|
||||
public void AddReceptorElement(ClusterPrefab prefab) {
|
||||
//this.nucleiArray = IReceptorHelpers.AddReceptorElement(this.nucleiArray, prefab);
|
||||
IReceptorHelpers.AddReceptorElement(this, prefab);
|
||||
}
|
||||
|
||||
public void RemoveReceptorElement() {
|
||||
// this.nucleiArray = IReceptorHelpers.RemoveReceptorElement(this.nucleiArray);
|
||||
IReceptorHelpers.RemoveReceptorElement(this);
|
||||
}
|
||||
|
||||
// public override void AddReceiver(Nucleus receiverToAdd, float weight = 1) {
|
||||
// foreach (Nucleus element in receptorToAdd.nucleiArray) {
|
||||
// if (element is Neuron neuron) {
|
||||
// neuron._receivers.Add(receiverToAdd);
|
||||
// receiverToAdd.AddSynapse(element, weight);
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
public virtual void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1) {
|
||||
IReceptorHelpers.AddArrayReceiver(this, receiverToAdd, weight);
|
||||
// foreach (Nucleus element in this._array.nuclei) {
|
||||
// if (element is Neuron neuron) {
|
||||
// neuron.AddReceiver(receiverToAdd, weight);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public override void UpdateStateIsolated() {
|
||||
this.outputValue = this.bias;
|
||||
//Debug.Log($"Receptor {this.name} outputvalue = {this.outputValue}");
|
||||
}
|
||||
|
||||
public override void UpdateNuclei() {
|
||||
|
||||
263
ReceptorArray.cs
263
ReceptorArray.cs
@ -1,263 +0,0 @@
|
||||
/*
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
|
||||
[Serializable]
|
||||
public class ReceptorInstance : Nucleus {
|
||||
public ReceptorInstance(Cluster parent, string name) {
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
// We explicitly do not add this to the parent, as it is serialized in the ReceptorArray
|
||||
}
|
||||
public ReceptorInstance(ClusterPrefab prefab, string name) {
|
||||
this.clusterPrefab = prefab;
|
||||
this.name = name;
|
||||
// We explicitly do not add this to the prefab, as it is serialized in the ReceptorArray
|
||||
}
|
||||
public override Nucleus ShallowCloneTo(Cluster parent) {
|
||||
ReceptorInstance clone = new(parent, name + " +1") {
|
||||
receptor = this.receptor
|
||||
};
|
||||
return clone;
|
||||
}
|
||||
public override Nucleus Clone(ClusterPrefab prefab) {
|
||||
ReceptorInstance clone = new(prefab, name) {
|
||||
receptor = this.receptor
|
||||
};
|
||||
return clone;
|
||||
}
|
||||
|
||||
[SerializeReference]
|
||||
public ReceptorArray receptor;
|
||||
|
||||
public override void UpdateStateIsolated() {
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ReceptorArray : Nucleus {
|
||||
public ReceptorArray(Cluster parent, string name) {
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
this._instances = new ReceptorInstance[1];
|
||||
this._instances[0] = new ReceptorInstance(parent, this.name + "[0]") {
|
||||
receptor = this
|
||||
};
|
||||
this.parent?.clusterNuclei.Add(this);
|
||||
}
|
||||
public ReceptorArray(ClusterPrefab prefab, string name) {
|
||||
this.clusterPrefab = prefab;
|
||||
this.name = name;
|
||||
this._instances = new ReceptorInstance[1];
|
||||
this._instances[0] = new ReceptorInstance(prefab, this.name + "[0]") {
|
||||
receptor = this
|
||||
};
|
||||
if (this.clusterPrefab != null)
|
||||
this.clusterPrefab.nuclei.Add(this);
|
||||
else
|
||||
Debug.LogError("No prefab when adding receptor to prefab");
|
||||
|
||||
}
|
||||
|
||||
public override Nucleus ShallowCloneTo(Cluster parent) {
|
||||
ReceptorArray clone = new(parent, name) {
|
||||
_instances = new ReceptorInstance[this.instances.Length]
|
||||
};
|
||||
for (int ix = 0; ix < this.instances.Length; ix++) {
|
||||
clone._instances[ix] = new ReceptorInstance(parent, $"{this.name} [{ix}]") {
|
||||
receptor = clone
|
||||
};
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
public override Nucleus Clone(ClusterPrefab prefab) {
|
||||
ReceptorArray clone = new(prefab, this.name) {
|
||||
_instances = new ReceptorInstance[this.instances.Length]
|
||||
};
|
||||
for (int ix = 0; ix < this.instances.Length; ix++) {
|
||||
clone._instances[ix] = new ReceptorInstance(prefab, this.name) {
|
||||
receptor = this
|
||||
};
|
||||
}
|
||||
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
|
||||
clonedSynapse.weight = synapse.weight;
|
||||
}
|
||||
// foreach (Nucleus receiver in this.receivers) {
|
||||
// clone.AddReceiver(receiver);
|
||||
// }
|
||||
return clone;
|
||||
}
|
||||
|
||||
[SerializeReference]
|
||||
private ReceptorInstance[] _instances = new ReceptorInstance[0];
|
||||
public ReceptorInstance[] instances {
|
||||
get {
|
||||
return _instances;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddReceptor(ClusterPrefab prefab) {
|
||||
if (this._instances.Length == 0) {
|
||||
Debug.LogError("Empty receptor array, cannot add");
|
||||
return;
|
||||
}
|
||||
int newLength = this._instances.Length + 1;
|
||||
ReceptorInstance[] newArray = new ReceptorInstance[newLength];
|
||||
|
||||
for (int i = 0; i < this._instances.Length; i++)
|
||||
newArray[i] = this._instances[i];
|
||||
ReceptorInstance newReceptor = (ReceptorInstance)this._instances[0].Clone(prefab);
|
||||
newReceptor.name = $"{this.name} [{this._instances.Length}]";
|
||||
newArray[newLength - 1] = newReceptor;
|
||||
|
||||
this._instances = newArray;
|
||||
}
|
||||
|
||||
public void RemoveReceptor() {
|
||||
int newLength = this._instances.Length - 1;
|
||||
if (newLength == 0) {
|
||||
Debug.LogWarning("Receptor array cannot be empty");
|
||||
return;
|
||||
}
|
||||
ReceptorInstance[] newPerceptei = new ReceptorInstance[newLength];
|
||||
for (int i = 0; i < newLength; i++)
|
||||
newPerceptei[i] = this._instances[i];
|
||||
// Delete the last perception
|
||||
if (this._instances[newLength] is Nucleus nucleus)
|
||||
Neuron.Delete(nucleus); //this._nuclei[newLength]);
|
||||
|
||||
this._instances = newPerceptei;
|
||||
}
|
||||
|
||||
private Dictionary<int, Nucleus> thingReceivers = new();
|
||||
|
||||
// public override void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
|
||||
// ProcessStimulus(inputValue, thingId, thingName);
|
||||
// }
|
||||
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||
CleanupReceivers();
|
||||
if (!thingReceivers.TryGetValue(thingId, out Nucleus selectedReceiver)) {
|
||||
//Debug.Log($" no receiver found for {thingId}");
|
||||
// No existing nucleus for this thing
|
||||
selectedReceiver = SelectReceptor(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;
|
||||
}
|
||||
|
||||
//if (selectedReceiver is Neuron selectedNucleus) {
|
||||
selectedReceiver.stale = 0;
|
||||
selectedReceiver.outputValue = inputValue;
|
||||
this.parent.UpdateFromNucleus(this);
|
||||
//selectedNucleus.ProcessStimulus(inputValue);
|
||||
//}
|
||||
}
|
||||
|
||||
private void CleanupReceivers() {
|
||||
// Remove a thing-receiver connection when the nucleus is inactive
|
||||
List<int> receiversToRemove = new();
|
||||
thingReceivers ??= new();
|
||||
|
||||
foreach (KeyValuePair<int, Nucleus> item in thingReceivers) {
|
||||
if (item.Value.isSleeping)
|
||||
receiversToRemove.Add(item.Key);
|
||||
}
|
||||
foreach (int thingId in receiversToRemove) {
|
||||
Nucleus selectedReceiver = thingReceivers[thingId];
|
||||
|
||||
// Debug.Log($" removed receiver for {thingId}");
|
||||
thingReceivers.Remove(thingId);
|
||||
|
||||
int colonPos = selectedReceiver.name.IndexOf(":");
|
||||
if (colonPos > 0)
|
||||
selectedReceiver.name = selectedReceiver.name[..colonPos];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Nucleus SelectReceptor(int thingId, float3 inputValue) {
|
||||
// No existing nucleus for this thing
|
||||
float inputMagnitude = length(inputValue);
|
||||
Nucleus selectedReceiver = null;
|
||||
float selectedMagnitude = 0;
|
||||
this._instances ??= new ReceptorInstance[0];
|
||||
foreach (Nucleus receiver in this._instances) {
|
||||
if (thingReceivers.ContainsValue(receiver) == false) {
|
||||
// We found an unusued receiver
|
||||
// Debug.Log($"{thingId} -> [{receiver.name}]");
|
||||
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);
|
||||
Debug.Log($"{thingId} -> [{selectedReceiver.name}]");
|
||||
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;
|
||||
}
|
||||
|
||||
public override void UpdateStateIsolated() {
|
||||
float3 sum = this.bias;
|
||||
|
||||
// Receptors do not have inputs, so we ignore the synapses
|
||||
foreach (Nucleus nucleus in this._instances)
|
||||
sum += nucleus.outputValue;
|
||||
|
||||
this.outputValue = sum / _instances.Length;
|
||||
this.stale = 0;
|
||||
|
||||
UpdateNuclei();
|
||||
}
|
||||
|
||||
public override void UpdateNuclei() {
|
||||
foreach (Nucleus nucleus in this.instances) {
|
||||
nucleus.stale++;
|
||||
if (nucleus.stale > staleValueForSleep && lengthsq(nucleus.outputValue) > 0) {
|
||||
nucleus.outputValue = Vector3.zero;
|
||||
//this.UpdateStateIsolated();
|
||||
this.parent.UpdateFromNucleus(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e915c8563642f23891b20522b3589cf
|
||||
Loading…
x
Reference in New Issue
Block a user