2025-12-11 12:27:55 +01:00

88 lines
2.8 KiB
C#

using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "Passer/NanoBrain")]
public class NanoBrainObj : ScriptableObject, ISerializationCallbackReceiver {
public string title;
public int count;
public Color color = Color.white;
public Texture2D texture;
public List<Neuroid> nuclei = new();
public List<Perceptoid> perceptei = new();
// This is probably always the first element in the nuclei list...
[System.NonSerialized]
public Nucleus root;
public int rootId;
// public Perception perception;
public NanoBrainObj() {
this.root = new Neuroid(this, "Root");
// this.perception = new Perception(this);
}
public Neuroid AddNeuron(string name) {
Neuroid neuroid = new(this, name);
return neuroid;
}
public void UpdateNuclei() {
foreach (Nucleus nucleus in nuclei) {
nucleus.stale++;
if (nucleus.isSleeping)
nucleus.outputValue = Vector3.zero;
}
}
public void OnBeforeSerialize() {
this.rootId = root.id;
}
public void OnAfterDeserialize() {
try {
foreach (Nucleus nucleus in this.nuclei.ToArray()) {
if (this.rootId == nucleus.id)
this.root = nucleus;
nucleus.Rebuild(this);
}
// List<Nucleus> rebuildNuclei = new();
// foreach (Nucleus nucleus in this.nuclei.ToArray()) {
// rebuildNuclei.Add(Nucleus.RebuildType(this, nucleus));
// }
// this.nuclei = rebuildNuclei;
foreach (Perceptoid perceptoid in this.perceptei.ToArray()) {
perceptoid.Rebuild(this);
}
}
catch (System.Exception) { }
this.GarbageCollection();
}
public void GarbageCollection() {
HashSet<Nucleus> visitedNuclei = new();
MarkNuclei(visitedNuclei, this.root);
Debug.Log($"Garbage collection found {visitedNuclei.Count} Nuclei");
this.nuclei.RemoveAll(nucleus => visitedNuclei.Contains(nucleus) == false);
this.perceptei.RemoveAll(perceptoid => visitedNuclei.Contains(perceptoid) == false);
}
public void MarkNuclei(HashSet<Nucleus> visitedNuclei, Nucleus nucleus) {
if (nucleus is null)
return;
visitedNuclei.Add(nucleus);
if (nucleus.synapses != null) {
HashSet<Synapse> visitedSynapses = new();
foreach (Synapse synapse in nucleus.synapses) {
if (synapse != null && synapse.nucleus != null) {
visitedSynapses.Add(synapse);
MarkNuclei(visitedNuclei, synapse.nucleus);
}
}
nucleus.synapses.RemoveAll(synapse => visitedSynapses.Contains(synapse) == false);
}
}
}