/* using System; using System.Collections.Generic; using UnityEngine; using Unity.Mathematics; using static Unity.Mathematics.math; public class Receptor : IReceptor { [SerializeField] protected string _name; public virtual string name { get => _name; set => _name = value; } public Receptor(Cluster parent) { this.parent = parent; parent?.nuclei.Add(this); } public Receptor(Cluster parent, string name, string nucleusName) { this.parent = parent ?? throw new ArgumentNullException(nameof(parent), "Parent cannot be null."); this.name = name; this.parent.nuclei.Add(this); foreach (INucleus nucleus in parent.inputs) { if (nucleus != null && nucleus.name == nucleusName) { this.AddReceiver(nucleus); } } } private readonly Cluster parent; public virtual IReceptor ShallowCloneTo(Cluster parent) { Receptor clone = new(parent); return clone; } public virtual IReceptor Clone() { Receptor clone = new(this.parent); foreach (INucleus receiver in this.receivers) { clone.AddReceiver(receiver); } return clone; } class Receiver { public INucleus nucleus; public int thingId; public string thingName; public Receiver(INucleus nucleus, int thingId, string thingName) { this.nucleus = nucleus; this.thingId = thingId; this.thingName = thingName; } } [SerializeReference] private List _receivers = new(); public List receivers { get { return _receivers; } set { _receivers = value; } } protected int[] thingIds; // every receiver can handle a thing with this id 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); } private int stale = 1000; private bool _isSleeping = false; public bool isSleeping => _isSleeping; private float3 _outputValue; public float3 outputValue { get { return this._outputValue; } set { this.stale = 0; this._isSleeping = false; this._outputValue = value; } } public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector, string thingName = null) { this.outputValue = newLocalPositionVector; if (this._receivers == null) return; thingIds ??= new int[this._receivers.Count]; int receiverIx = 0; INucleus selectedReceiver = null; int selectedReceiverIx = 0; foreach (INucleus receiver in this.receivers) { if (thingIds[receiverIx] == thingId) { // We found an existing receiver for this thing selectedReceiver = receiver; selectedReceiverIx = receiverIx; // Do not look any further break; } else if (receiver.isSleeping) { // A sleeping receiver is not active and can therefore always be used selectedReceiver = receiver; selectedReceiverIx = receiverIx; // Look further because we may find an existing receiver for this thing } else if (selectedReceiver == null) { // If we haven't found a receiver yet, just start by taking the first selectedReceiver = receiver; selectedReceiverIx = receiverIx; } else if (selectedReceiver.isSleeping == false) { // If no existing or sleeping receiver is found, we look for // the receiver with the furthest/least interesting stimulus if (length(receiver.outputValue) < length(selectedReceiver.outputValue)) { // Debug.Log($"{selectedReceiver.name}[{selectedReceiverIx}] {length(selectedReceiver.outputValue)}" + // $" {receiver.name}[{receiverIx}] {length(receiver.outputValue)} "); selectedReceiver = receiver; selectedReceiverIx = receiverIx; } } receiverIx++; } if (selectedReceiverIx >= thingIds.Length) return; thingIds[selectedReceiverIx] = thingId; if (thingName != null) { string baseName = selectedReceiver.name; int colonPos = selectedReceiver.name.IndexOf(":"); if (colonPos > 0) baseName = selectedReceiver.name.Substring(0, colonPos); selectedReceiver.name = baseName + ": " + thingName; } Debug.Log($"Receiver {selectedReceiver.name}[{selectedReceiverIx}] for thing {thingId}"); selectedReceiver.parent.UpdateStateIsolated(); } public void UpdateNuclei() { this.stale++; this._isSleeping = this.stale > 2; if (isSleeping) this._outputValue = Vector3.zero; } } */