1use std::ops::Deref;
4
5use crate::{
6 common::{MaaId, MaaStatus},
7 sys, MaaResult,
8};
9
10pub type StatusFn<'a> = Box<dyn Fn(MaaId) -> MaaStatus + Send + Sync + 'a>;
11pub type WaitFn<'a> = Box<dyn Fn(MaaId) -> MaaStatus + Send + Sync + 'a>;
12
13pub struct Job<'a> {
17 pub id: MaaId,
18 status_fn: StatusFn<'a>,
19 wait_fn: WaitFn<'a>,
20}
21
22impl<'a> Job<'a> {
23 pub fn new(id: MaaId, status_fn: StatusFn<'a>, wait_fn: WaitFn<'a>) -> Self {
25 Self {
26 id,
27 status_fn,
28 wait_fn,
29 }
30 }
31
32 pub fn for_tasker(tasker: &crate::tasker::Tasker, id: MaaId) -> Job<'static> {
34 let tasker1 = tasker.clone();
35 let tasker2 = tasker.clone();
36 Job {
37 id,
38 status_fn: Box::new(move |job_id| {
39 MaaStatus(unsafe { sys::MaaTaskerStatus(tasker1.raw(), job_id) })
40 }),
41 wait_fn: Box::new(move |job_id| {
42 MaaStatus(unsafe { sys::MaaTaskerWait(tasker2.raw(), job_id) })
43 }),
44 }
45 }
46
47 pub fn for_controller(controller: &crate::controller::Controller, id: MaaId) -> Job<'static> {
49 let controller1 = controller.clone();
50 let controller2 = controller.clone();
51 Job {
52 id,
53 status_fn: Box::new(move |job_id| {
54 MaaStatus(unsafe { sys::MaaControllerStatus(controller1.raw(), job_id) })
55 }),
56 wait_fn: Box::new(move |job_id| {
57 MaaStatus(unsafe { sys::MaaControllerWait(controller2.raw(), job_id) })
58 }),
59 }
60 }
61
62 pub fn for_resource(resource: &crate::resource::Resource, id: MaaId) -> Job<'static> {
64 let resource1 = resource.clone();
65 let resource2 = resource.clone();
66 Job {
67 id,
68 status_fn: Box::new(move |job_id| {
69 MaaStatus(unsafe { sys::MaaResourceStatus(resource1.raw(), job_id) })
70 }),
71 wait_fn: Box::new(move |job_id| {
72 MaaStatus(unsafe { sys::MaaResourceWait(resource2.raw(), job_id) })
73 }),
74 }
75 }
76
77 pub fn wait(&self) -> MaaStatus {
79 (self.wait_fn)(self.id)
80 }
81
82 pub fn status(&self) -> MaaStatus {
84 (self.status_fn)(self.id)
85 }
86
87 pub fn succeeded(&self) -> bool {
89 self.status() == MaaStatus::SUCCEEDED
90 }
91
92 pub fn failed(&self) -> bool {
94 self.status() == MaaStatus::FAILED
95 }
96
97 pub fn running(&self) -> bool {
99 self.status() == MaaStatus::RUNNING
100 }
101
102 pub fn pending(&self) -> bool {
104 self.status() == MaaStatus::PENDING
105 }
106
107 pub fn done(&self) -> bool {
109 let s = self.status();
110 s == MaaStatus::SUCCEEDED || s == MaaStatus::FAILED
111 }
112}
113
114pub struct JobWithResult<'a, T> {
118 job: Job<'a>,
119 get_fn: Box<dyn Fn(MaaId) -> MaaResult<Option<T>> + Send + Sync + 'a>,
120}
121
122impl<'a, T> Deref for JobWithResult<'a, T> {
123 type Target = Job<'a>;
124
125 fn deref(&self) -> &Self::Target {
126 &self.job
127 }
128}
129
130impl<'a, T> JobWithResult<'a, T> {
131 pub fn new(
133 id: MaaId,
134 status_fn: StatusFn<'a>,
135 wait_fn: WaitFn<'a>,
136 get_fn: impl Fn(MaaId) -> MaaResult<Option<T>> + Send + Sync + 'a,
137 ) -> Self {
138 Self {
139 job: Job::new(id, status_fn, wait_fn),
140 get_fn: Box::new(get_fn),
141 }
142 }
143
144 pub fn get(&self, wait: bool) -> MaaResult<Option<T>> {
149 if wait {
150 self.wait();
151 }
152 (self.get_fn)(self.job.id)
153 }
154}
155
156pub type OverridePipelineFn<'a> = Box<dyn Fn(MaaId, &str) -> MaaResult<bool> + Send + Sync + 'a>;
157
158pub struct TaskJob<'a, T> {
162 job: JobWithResult<'a, T>,
163 override_fn: OverridePipelineFn<'a>,
164}
165
166impl<'a, T> Deref for TaskJob<'a, T> {
167 type Target = JobWithResult<'a, T>;
168
169 fn deref(&self) -> &Self::Target {
170 &self.job
171 }
172}
173
174impl<'a, T> TaskJob<'a, T> {
175 pub fn new(job: JobWithResult<'a, T>, override_fn: OverridePipelineFn<'a>) -> Self {
177 Self { job, override_fn }
178 }
179
180 pub fn override_pipeline(&self, pipeline_override: &str) -> MaaResult<bool> {
190 (self.override_fn)(self.job.id, pipeline_override)
191 }
192}
193
194pub type CtrlJob = Job<'static>;
200
201pub type ResJob = Job<'static>;
205
206pub type TaskJobWithResult = TaskJob<'static, crate::common::TaskDetail>;
210
211pub type RecoJobWithResult = TaskJob<'static, crate::common::RecognitionDetail>;
215
216pub type ActionJobWithResult = TaskJob<'static, crate::common::ActionDetail>;