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