using System; using System.Collections.Generic; using UnityEngine; using Unity.Mathematics; using static Unity.Mathematics.math; public abstract class Nucleus : INucleus { [SerializeField] protected string _name; public virtual string name { get => _name; set => _name = value; } //[Obsolete] public ClusterPrefab cluster { get; set; } public Cluster parent { get; set; } protected float3 _outputValue; public virtual float3 outputValue { get { return _outputValue; } set { //Debug.Log($"{this.name}: stale is reset, was: {this.stale}"); //this.stale = 0; // this._isSleeping = false; _outputValue = value; } } public bool isSleeping => lengthsq(this.outputValue) == 0; [NonSerialized] public int stale = 1000; // Cannot clone an abstract nucleus... public virtual IReceptor ShallowCloneTo(Cluster parent) { return null; } // Cannot clone an abstract nucleus... public virtual IReceptor Clone() { return null; } #region Synapses [SerializeField] private List _synapses = new(); public List synapses => _synapses; public Synapse AddSynapse(INucleus sendingNucleus, float weight = 1.0f) { Synapse synapse = new(sendingNucleus, weight); this.synapses.Add(synapse); return synapse; } public Synapse GetSynapse(INucleus 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(INucleus receivingNucleus, float weight = 1) { this._receivers.Add(receivingNucleus); receivingNucleus.AddSynapse(this, weight); } public void RemoveReceiver(INucleus 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 virtual void UpdateStateIsolated() { UpdateStateIsolated(new float3(0, 0, 0)); } public virtual void UpdateStateIsolated(float3 bias) { } public void UpdateNuclei() { this.stale++; if (this.stale > 5) { //Debug.Log($"{this.name} goes to sleep, stale = {this.stale}"); _outputValue = Vector3.zero; } } public void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) { this.array.ProcessStimulus(thingId, inputValue, thingName); } #endregion Update }