using System; using System.Collections.Generic; using UnityEngine; using Unity.Mathematics; using static Unity.Mathematics.math; [Serializable] public abstract class Nucleus { public string name; [SerializeReference] public ClusterPrefab clusterPrefab; [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); 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; } public void RemoveSynapse(Nucleus sendingNucleus) { this.synapses.RemoveAll(synapse => synapse.nucleus == sendingNucleus); } #endregion Synapses #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); } public virtual void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = "") { } #endregion Update }