1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! LOD builder.
use crate::;
/// Wrapper around memory that holds additional information about current level of details.
/// Allows to run different decision making depending on the level of details set in memory.
///
/// Useful to optimize AI processing to for example run narrow phase logic when agent is near the
/// player and run broad phase logic when agent runs in the background.
///
/// # Example
/// ```
/// use emergent::prelude::*;
///
/// const DELTA_TIME: Scalar = 1.0;
///
/// struct Memory {
/// time_since_last_meal: Scalar,
/// hunger: Scalar,
/// }
///
/// let mut lod = Lod::default()
/// // level 0 means agent is not in area and we optimize AI processing by not doing any work,
/// // so on task exit we just estimate how much more hungry agent can get during task time.
/// .level(ClosureTask::default().exit(|m: &mut LodMemory<Memory>| {
/// m.memory.hunger -= m.memory.time_since_last_meal;
/// println!("* Background hunger estimation: {}", m.memory.hunger);
/// }))
/// // level 1 means agent is in area and we want to accurately change its hunger level.
/// .level(ClosureTask::default().update(|m: &mut LodMemory<Memory>| {
/// m.memory.hunger -= DELTA_TIME;
/// println!("* Foreground hunger calculation: {}", m.memory.hunger);
/// }))
/// .build();
///
/// let mut memory = LodMemory {
/// lod_level: 0,
/// memory: Memory {
/// time_since_last_meal: 0.0,
/// hunger: 10.0,
/// },
/// };
///
/// // we start with agent running in the background.
/// assert_eq!(lod.active_index(), None);
/// assert_eq!(lod.process(&mut memory), true);
/// assert_eq!(lod.active_index(), Some(0));
/// // agent will now run in foreground and we assume 5 seconds have passed since last meal.
/// memory.lod_level = 1;
/// memory.memory.time_since_last_meal = 5.0;
/// assert_eq!(lod.process(&mut memory), true);
/// assert_eq!(lod.active_index(), Some(1));
/// assert_eq!(memory.memory.hunger, 5.0);
/// lod.update(&mut memory);
/// assert_eq!(memory.memory.hunger, 4.0);
/// ```
;