Improve custer/clusterinstance

This commit is contained in:
Pascal Serrarens 2026-01-28 14:34:52 +01:00
parent 296b80453f
commit 96ed53312d
6 changed files with 69 additions and 110 deletions

View File

@ -1,7 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Unity.Mathematics;
using static Unity.Mathematics.math;
[CreateAssetMenu(menuName = "Passer/Cluster")] [CreateAssetMenu(menuName = "Passer/Cluster")]
public class Cluster : ScriptableObject { public class Cluster : ScriptableObject {
@ -35,30 +33,6 @@ public class Cluster : ScriptableObject {
} }
} }
// The synapses of all inputs
private readonly List<Synapse> _synapses = new();
public List<Synapse> synapses => _synapses;
public NucleusArray array { get; set; }
public List<INucleus> receivers {
get { return this.output.receivers; }
set { this.output.receivers = value; }
}
// public List<Cluster> clusterReceivers {
// get { return this.output.clusterReceivers; }
// set { this.output.clusterReceivers = clusterReceivers; }
// }
// public IEnumerable<INucleus> allReceivers {
// get => output.allReceivers;
// }
// public INucleus Clone() {
// Cluster clone = CreateInstance<Cluster>();
// // Lots to add here...
// return clone;
// }
// Call this function to ensure that there is at least one nucleus // Call this function to ensure that there is at least one nucleus
// This is an invariant and should be ensured before the nucleus is used // This is an invariant and should be ensured before the nucleus is used
// because output requires it. // because output requires it.
@ -67,38 +41,12 @@ public class Cluster : ScriptableObject {
if (nuclei.Count == 0) if (nuclei.Count == 0)
new Neuron(this, "Output"); // Every cluster should have at least 1 neuron new Neuron(this, "Output"); // Every cluster should have at least 1 neuron
} }
/*
public void AddReceiver(INucleus receivingNucleus) {
//output.AddReceiver(receiver);
this.output.receivers.Add(receivingNucleus);
receivingNucleus.AddClusterSynapse(this);
}
public void AddClusterReceiver(Cluster clusterReceiver) {
this.output.clusterReceivers.Add(clusterReceiver);
clusterReceiver.AddClusterSynapse(this);
}
public void RemoveReceiver(INucleus receiver) {
output.RemoveReceiver(receiver);
}
public Synapse AddSynapse(IReceptor sender) {
Synapse synapse = new(sender);
synapses.Add(synapse);
return synapse;
}
public Synapse AddClusterSynapse(Cluster sender) {
Synapse synapse = new(sender);
synapses.Add(synapse);
return synapse;
}
*/
public void GarbageCollection() { public void GarbageCollection() {
HashSet<INucleus> visitedNuclei = new(); HashSet<INucleus> visitedNuclei = new();
MarkNuclei(visitedNuclei, this.output); MarkNuclei(visitedNuclei, this.output);
//Debug.Log($"Garbage collection found {visitedNuclei.Count} Nuclei"); //Debug.Log($"Garbage collection found {visitedNuclei.Count} Nuclei");
this.nuclei.RemoveAll(nucleus => nucleus is INucleus n && visitedNuclei.Contains(n) == false); this.nuclei.RemoveAll(nucleus => nucleus is INucleus n && visitedNuclei.Contains(n) == false);
//this.perceptei.RemoveAll(perceptoid => visitedNuclei.Contains(perceptoid) == false);
} }
public void MarkNuclei(HashSet<INucleus> visitedNuclei, INucleus nucleus) { public void MarkNuclei(HashSet<INucleus> visitedNuclei, INucleus nucleus) {
@ -129,22 +77,8 @@ public class Cluster : ScriptableObject {
} }
} }
#region Dynamics
public float3 outputValue => this.output.outputValue;
public bool isSleeping => lengthsq(this.outputValue) == 0;
public void UpdateState() {
// Don't know if this is right
this.output.UpdateState();
// it is not, I should take inputs from the synapses and route them to the right internal nuclei
}
public void UpdateNuclei() { public void UpdateNuclei() {
foreach (IReceptor nucleus in this.nuclei) foreach (IReceptor nucleus in this.nuclei)
nucleus.UpdateNuclei(); nucleus.UpdateNuclei();
} }
#endregion Dynamics
} }

View File

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Unity.Mathematics; using Unity.Mathematics;
@ -11,14 +10,18 @@ public class ClusterInstance : INucleus {
public Cluster cluster => this.asset; public Cluster cluster => this.asset;
public List<IReceptor> dynamicNuclei = new();
public INucleus output => this.asset.nuclei[0] as INucleus; public INucleus output => this.asset.nuclei[0] as INucleus;
public float3 outputValue => this.output.outputValue; public float3 outputValue => this.output.outputValue;
public ClusterInstance(Cluster asset) { public ClusterInstance(Cluster asset) {
this.asset = asset; this.asset = asset;
foreach (IReceptor nucleus in this.asset.nuclei)
dynamicNuclei.Add(nucleus.Clone());
} }
public INucleus Clone() { public IReceptor Clone() {
ClusterInstance clone = new(this.asset); ClusterInstance clone = new(this.asset);
return clone; return clone;
} }
@ -116,7 +119,15 @@ public class ClusterInstance : INucleus {
#region Update #region Update
public void UpdateState() { } public void UpdateState() {
float3 sum = new(0, 0, 0);
//Applying the weight factgors
foreach (Synapse synapse in this.synapses) {
sum += synapse.weight * synapse.nucleus.outputValue;
}
this.asset.inputs[0].UpdateState();
}
public void UpdateNuclei() { public void UpdateNuclei() {
foreach (IReceptor nucleus in this.asset.nuclei) foreach (IReceptor nucleus in this.asset.nuclei)

View File

@ -22,8 +22,6 @@ public interface INucleus : IReceptor {
#endregion dynamic state #endregion dynamic state
public INucleus Clone();
} }
public interface IReceptor { public interface IReceptor {
@ -48,5 +46,7 @@ public interface IReceptor {
public bool isSleeping { get; } public bool isSleeping { get; }
#endregion dynamic #endregion dynamic
public IReceptor Clone();
} }

View File

@ -165,8 +165,9 @@ public class Neuron : INucleus {
#endregion Runtime state #endregion Runtime state
public Neuron(Cluster brain, string name) : this(name) { public Neuron(Cluster brain, string name) {
this.cluster = brain; this.cluster = brain;
this.name = name;
if (this.cluster != null) { if (this.cluster != null) {
this.cluster.nuclei.Add(this); this.cluster.nuclei.Add(this);
} }
@ -174,13 +175,12 @@ public class Neuron : INucleus {
Debug.LogError("No neuroid network"); Debug.LogError("No neuroid network");
} }
public Neuron(string name) { // public Neuron(string name) {
this._name = name; // this._name = name;
} // }
public virtual INucleus Clone() { public virtual IReceptor Clone() {
Neuron clone = new(this.name) { Neuron clone = new(this.cluster, this.name) {
cluster = this.cluster,
array = this.array, array = this.array,
curve = this.curve, curve = this.curve,
curvePreset = this.curvePreset, curvePreset = this.curvePreset,

View File

@ -42,7 +42,8 @@ public class NucleusArray {
for (int i = 0; i < this._nuclei.Length; i++) for (int i = 0; i < this._nuclei.Length; i++)
newArray[i] = this._nuclei[i]; newArray[i] = this._nuclei[i];
newArray[newLength - 1] = this._nuclei[0].Clone(); if (this._nuclei[0] is INucleus nucleus)
newArray[newLength - 1] = (INucleus) nucleus.Clone();
this._nuclei = newArray; this._nuclei = newArray;
} }

View File

@ -1,11 +1,12 @@
using System;
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Unity.Mathematics; using Unity.Mathematics;
using static Unity.Mathematics.math; using static Unity.Mathematics.math;
public class Receptor : IReceptor { public class Receptor : IReceptor {
private Cluster cluster;
[SerializeField] [SerializeField]
protected string _name; protected string _name;
public virtual string name { public virtual string name {
@ -13,6 +14,47 @@ public class Receptor : IReceptor {
set => _name = value; set => _name = value;
} }
public Receptor(Cluster cluster) {
this.cluster = cluster;
if (cluster != null)
cluster.nuclei.Add(this);
}
public Receptor(Cluster cluster, INucleus nucleus) {
this.cluster = cluster;
if (cluster != null)
cluster.nuclei.Add(this);
this.AddReceiver(nucleus);
}
public static Receptor CreateReceptor(Cluster cluster, string nucleusName) {
if (cluster == null)
return null;
Receptor receptor = new(cluster);
foreach (INucleus nucleus in cluster.inputs) {
if (nucleus != null && nucleus.name == nucleusName) {
// Receptor receptor = new(cluster, nucleus);
// return receptor;
receptor.AddReceiver(nucleus);
}
}
if (receptor._receivers.Count == 0)
return null;
else
return receptor;
}
public virtual IReceptor Clone() {
Receptor clone = new(this.cluster);
foreach (INucleus receiver in this.receivers) {
clone.AddReceiver(receiver);
}
return clone;
}
class Receiver { class Receiver {
public INucleus nucleus; public INucleus nucleus;
public int thingId; public int thingId;
@ -69,35 +111,6 @@ public class Receptor : IReceptor {
} }
} }
public Receptor(Cluster cluster) {
if (cluster != null)
cluster.nuclei.Add(this);
}
public Receptor(Cluster cluster, INucleus nucleus) {
if (cluster != null)
cluster.nuclei.Add(this);
this.AddReceiver(nucleus);
}
public static Receptor CreateReceptor(Cluster cluster, string nucleusName) {
if (cluster == null)
return null;
Receptor receptor = new(cluster);
foreach (INucleus nucleus in cluster.inputs) {
if (nucleus != null && nucleus.name == nucleusName) {
// Receptor receptor = new(cluster, nucleus);
// return receptor;
receptor.AddReceiver(nucleus);
}
}
if (receptor._receivers.Count == 0)
return null;
else
return receptor;
}
public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector, string thingName = null) { public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector, string thingName = null) {
this.localPosition = newLocalPositionVector; this.localPosition = newLocalPositionVector;