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, ClusterReceptor, } #region Synapses public Vector3 bias = Vector3.zero; [SerializeField] private List _synapses = new(); public List 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 _receivers = new(); public List 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 #region Update public abstract void UpdateStateIsolated(); public virtual void UpdateNuclei() { } public virtual void SetBias(Vector3 inputValue) { this.stale = 0; this.bias = inputValue; this.parent.UpdateFromNucleus(this); } #endregion Update }