125 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using Unity.Mathematics;
using static Unity.Mathematics.math;
[Serializable]
public abstract class Nucleus {
public string name;
//[Obsolete]
public ClusterPrefab cluster { get; set; }
public Cluster parent { get; set; }
protected float3 _outputValue;
public virtual float3 outputValue {
get { return _outputValue; }
set {
//this.stale = 0;
_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);
public abstract Nucleus Clone(ClusterPrefab prefab);
public enum Type {
None,
Neuron,
MemoryCell,
Selector,
Cluster,
Pulsar,
Receptor,
ReceptorArray
}
#region Synapses
public Vector3 bias = Vector3.zero;
[SerializeField]
private List<Synapse> _synapses = new();
public List<Synapse> synapses => _synapses;
public Synapse AddSynapse(Nucleus sendingNucleus, float weight = 1.0f) {
Synapse synapse = new(sendingNucleus, weight);
this.synapses.Add(synapse);
return synapse;
}
public Synapse GetSynapse(Nucleus sender) {
foreach (Synapse synapse in this.synapses)
if (synapse.nucleus == sender)
return synapse;
return null;
}
#endregion Synapses
#region Receivers
[SerializeReference]
private List<Nucleus> _receivers = new();
public 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
[SerializeReference]
private NucleusArray _array;
public NucleusArray array {
get { return _array; }
set { _array = value; }
}
#region Update
public abstract void UpdateStateIsolated();
public virtual void UpdateNuclei() {
if (this.array == null || this.array.nuclei == null || this.array.nuclei.Length <= 1)
return;
this.stale++;
if (this.stale > staleValueForSleep) {
//Debug.Log($"{this.name} goes to sleep, stale = {this.stale}");
_outputValue = Vector3.zero;
}
}
public virtual void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
this.array.ProcessStimulus(thingId, inputValue, thingName);
}
public virtual void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
this.array.ProcessStimulus(thingId, inputValue, thingName);
}
#endregion Update
}