npc_engine_core/
active_task.rs1use crate::{AgentId, Domain, IdleTask, StateDiffRef, Task};
7use std::cmp::Ordering;
8use std::collections::BTreeSet;
9use std::hash::{Hash, Hasher};
10use std::{fmt, mem};
11
12pub struct ActiveTask<D: Domain> {
14 pub end: u64,
16 pub agent: AgentId,
18 pub task: Box<dyn Task<D>>,
20}
21pub type ActiveTasks<D> = BTreeSet<ActiveTask<D>>;
25
26impl<D: Domain> ActiveTask<D> {
27 pub fn new(
29 agent: AgentId,
30 task: Box<dyn Task<D>>,
31 tick: u64,
32 state_diff: StateDiffRef<D>,
33 ) -> Self {
34 let end = tick + task.duration(tick, state_diff, agent);
35 ActiveTask { end, agent, task }
36 }
37 pub fn new_with_end(end: u64, agent: AgentId, task: Box<dyn Task<D>>) -> Self {
39 ActiveTask { end, agent, task }
40 }
41 pub fn new_idle(tick: u64, agent: AgentId, active_agent: AgentId) -> Self {
44 ActiveTask {
45 end: if agent < active_agent { tick + 1 } else { tick },
48 agent,
49 task: Box::new(IdleTask),
50 }
51 }
52 pub fn size(&self, task_size: fn(&dyn Task<D>) -> usize) -> usize {
54 let mut size = 0;
55 size += mem::size_of::<Self>();
56 size += task_size(&*self.task);
57 size
58 }
59}
60
61pub(crate) fn get_task_for_agent<D: Domain>(
63 set: &ActiveTasks<D>,
64 agent: AgentId,
65) -> Option<&ActiveTask<D>> {
66 for task in set {
67 if task.agent == agent {
68 return Some(task);
69 }
70 }
71 None
72}
73
74impl<D: Domain> fmt::Debug for ActiveTask<D> {
75 fn fmt(&self, f: &'_ mut fmt::Formatter) -> fmt::Result {
76 f.debug_struct("ActiveTask")
77 .field("end", &self.end)
78 .field("agent", &self.agent)
79 .field("task", &self.task)
80 .finish()
81 }
82}
83
84impl<D: Domain> std::fmt::Display for ActiveTask<D> {
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 write!(f, "{} {:?} ends T{}", self.agent, self.task, self.end)
87 }
88}
89
90impl<D: Domain> Hash for ActiveTask<D> {
91 fn hash<H: Hasher>(&self, state: &mut H) {
92 self.end.hash(state);
93 self.agent.hash(state);
94 self.task.hash(state);
95 }
96}
97
98impl<D: Domain> Clone for ActiveTask<D> {
99 fn clone(&self) -> Self {
100 ActiveTask {
101 end: self.end,
102 agent: self.agent,
103 task: self.task.box_clone(),
104 }
105 }
106}
107
108impl<D: Domain> Ord for ActiveTask<D> {
109 fn cmp(&self, other: &Self) -> Ordering {
111 self.end.cmp(&other.end).then(self.agent.cmp(&other.agent))
112 }
113}
114
115impl<D: Domain> PartialOrd for ActiveTask<D> {
116 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
117 Some(self.cmp(other))
118 }
119}
120
121impl<D: Domain> Eq for ActiveTask<D> {}
122
123impl<D: Domain> PartialEq for ActiveTask<D> {
124 fn eq(&self, other: &Self) -> bool {
125 self.end == other.end && self.agent == other.agent && self.task.box_eq(&other.task)
126 }
127}