1use crate::brain::BrainID;
2use crate::id::ID;
3use crate::Scalar;
4use serde::{Deserialize, Serialize};
5
6pub type NeuronID = ID<Neuron>;
7
8#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
9#[repr(C)]
10pub struct Impulse {
11 pub potential: Scalar,
12 pub timeout: Scalar,
13}
14
15#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
16pub(crate) struct Synapse {
17 pub source: NeuronID,
18 pub target: NeuronID,
19 pub distance: Scalar,
20 pub receptors: Scalar,
21 pub impulses: Vec<Impulse>,
22 pub inactivity: Scalar,
23}
24
25#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
26#[repr(C)]
27pub struct Position {
28 pub x: Scalar,
29 pub y: Scalar,
30 pub z: Scalar,
31}
32
33impl Position {
34 #[inline]
35 pub fn magnitude_sqr(&self) -> Scalar {
36 self.x * self.x + self.y * self.y + self.z * self.z
37 }
38
39 #[inline]
40 pub fn magnitude(&self) -> Scalar {
41 self.magnitude_sqr().sqrt()
42 }
43
44 pub fn distance_sqr(&self, other: Self) -> Scalar {
45 let dx = self.x - other.x;
46 let dy = self.y - other.y;
47 let dz = self.z - other.z;
48 dx * dx + dy * dy + dz * dz
49 }
50
51 #[inline]
52 pub fn distance(&self, other: Self) -> Scalar {
53 self.distance_sqr(other).sqrt()
54 }
55}
56
57#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
58#[repr(C)]
59pub struct Neuron {
60 id: NeuronID,
61 owner_id: BrainID,
62 position: Position,
63 potential: Scalar,
64}
65
66impl Neuron {
67 pub(crate) fn new(owner_id: BrainID, position: Position) -> Self {
68 Self {
69 id: Default::default(),
70 owner_id,
71 position,
72 potential: 0.0,
73 }
74 }
75
76 pub(crate) fn with_id(id: NeuronID, owner_id: BrainID, position: Position) -> Self {
77 Self {
78 id,
79 owner_id,
80 position,
81 potential: 0.0,
82 }
83 }
84
85 #[inline]
86 pub fn id(&self) -> NeuronID {
87 self.id
88 }
89
90 #[inline]
91 pub fn owner_id(&self) -> BrainID {
92 self.owner_id
93 }
94
95 #[inline]
96 pub fn position(&self) -> Position {
97 self.position
98 }
99
100 #[inline]
101 pub fn potential(&self) -> Scalar {
102 self.potential
103 }
104
105 #[inline]
106 pub(crate) fn push_potential(&mut self, value: Scalar) {
107 self.potential += value;
108 }
109
110 #[inline]
111 pub(crate) fn process_potential(&mut self, delta_time_times_decay: Scalar) {
112 if self.potential < -delta_time_times_decay {
113 self.potential = (self.potential + delta_time_times_decay).min(0.0);
114 } else if self.potential > delta_time_times_decay {
115 self.potential = (self.potential - delta_time_times_decay).max(0.0);
116 } else {
117 self.potential = 0.0;
118 }
119 }
120
121 #[inline]
122 pub(crate) fn fire(&mut self) {
123 self.potential = 0.0;
124 }
125}