using System;
using System.Collections.Generic;
using UnityEngine;
///
/// The Nanobrain namespace
///
namespace NanoBrain {
///
/// A Nucleus is a basic element in a brain cluster
///
[Serializable]
public abstract class Nucleus {
///
/// The name of the Nucleus
///
public string name;
///
/// The cluster prefab in which the nucleus is located
///
[SerializeReference]
public ClusterPrefab clusterPrefab;
///
/// The cluster instance in which the nucleus is located
///
[SerializeReference]
public Cluster parent;
///
/// Toggle for printing debugging trace data
///
public bool trace = false;
///
/// Function to make a partial clone of this nucleus
///
/// The cluster in which the cloned nucleus should be placed
///
public abstract Nucleus ShallowCloneTo(Cluster parent);
///
/// Function to clone a nucleus to a Cluster prefab
///
///
///
public abstract Nucleus Clone(ClusterPrefab prefab);
///
/// The types of Nucleus
///
public enum Type {
None,
Neuron,
MemoryCell,
Cluster,
//Receptor,
//ClusterReceptor,
//ClusterArray,
}
public virtual void Initialize() {}
#region Synapses
///
/// The bias of the nucleus
///
/// The bias which a value which is always added to the combined value of the nucleus
/// It does not have a synapse and therefore no weight of source nucleus
public Vector3 bias = Vector3.zero;
[SerializeField]
private List _synapses = new();
///
/// The synapses of the nucleus
///
public List synapses => _synapses;
///
/// Add a new synapse to this nuclues
///
/// The nucleus from which the signals may originate
/// The weight applied to the input. Default value = 1
/// The created Synapse
/// This will add a new input to this nucleus with the given weight.
public Synapse AddSynapse(Neuron sendingNucleus, float weight = 1) {
Synapse synapse = new(sendingNucleus, weight);
this.synapses.Add(synapse);
return synapse;
}
// public Synapse AddSynapse(ClusterPrefab clusterPrefab, string neuronName, float weight = 1) {
// }
///
/// Find a synapse
///
/// The sender of the input to the Synapse
/// The found Synapse or null when the sender has no synapse to this nucleus.
public Synapse GetSynapse(Nucleus sender) {
foreach (Synapse synapse in this.synapses)
if (synapse.neuron == sender)
return synapse;
return null;
}
///
/// Remove a synapse from a Nucleus
///
/// Remote the synapse connecting to this Nucleus
public void RemoveSynapse(Nucleus sendingNucleus) {
this.synapses.RemoveAll(synapse => synapse.neuron == sendingNucleus);
}
#endregion Synapses
#region Update
///
/// Update the state without updating other Nuclei
///
public abstract void UpdateStateIsolated();
///
/// Update the state and recursively all Nuclei receiving data from this Nucleus
///
public virtual void UpdateNuclei() {
}
///
/// Set the bias, recalculate the output and update all Nuclei receiving from this Nucleus
///
///
public virtual void SetBias(Vector3 inputValue) {
this.bias = inputValue;
this.parent.UpdateFromNucleus(this);
}
///
/// Process an external stimulus
///
/// The value of the stimulus
/// The id of the thing causing the stimulus
/// The name of the thing causing the stimulus
public virtual void ProcessStimulus(Vector3 inputValue) { //, int thingId = 0, string thingName = "") {
}
#endregion Update
}
}