Skip to main content

Context

Struct Context 

Source
pub struct Context { /* private fields */ }
Expand description

Represents the execution context of a task.

This struct provides an interface for interacting with the current task’s runtime state. Capabilities include:

  • Executing sub-tasks.
  • Overriding pipeline configurations dynamically.
  • Performing direct recognition and actions.
  • Managing node hit counts and control flow anchors.

§Safety

Context is a wrapper around a non-owning pointer (MaaContext). The underlying resources are managed by the Tasker. Users must ensure the Context does not outlive the validity of the underlying task or callback scope.

Implementations§

Source§

impl Context

Source

pub fn run_task(&self, entry: &str, pipeline_override: &str) -> MaaResult<i64>

Submits a new task for execution.

§Arguments
  • entry - The name of the task entry point.
  • pipeline_override - A JSON string specifying pipeline parameter overrides.
§Returns

Returns the job ID (MaaId) associated with the submitted task.

Source

pub fn override_pipeline(&self, override_json: &str) -> MaaResult<()>

Overrides pipeline parameters for the current context.

§Arguments
  • override_json - A JSON string containing the parameters to override.
Examples found in repository?
examples/main.rs (line 73)
37    fn analyze(
38        &self,
39        context: &Context,
40        _task_id: sys::MaaTaskId,
41        node_name: &str,
42        custom_recognition_name: &str,
43        custom_recognition_param: &str,
44        _image: &maa_framework::buffer::MaaImageBuffer,
45        _roi: &maa_framework::common::Rect,
46    ) -> Option<(maa_framework::common::Rect, String)> {
47        println!(
48            "[MyRecognition] analyze called: node={}, name={}, param={}",
49            node_name, custom_recognition_name, custom_recognition_param
50        );
51
52        // --- Context API Demo ---
53
54        // 1. Run sub-pipeline recognition with override
55        let pp_override = r#"{"MyCustomOCR": {"recognition": "OCR", "roi": [100, 100, 200, 300]}}"#;
56        if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
57            let reco_id = context.run_recognition("MyCustomOCR", pp_override, &img_buf);
58            println!("  run_recognition result: {:?}", reco_id);
59        }
60
61        // 2. Take a new screenshot via tasker's controller
62        let tasker_ptr = context.tasker_handle();
63        if !tasker_ptr.is_null() {
64            // Note: In real usage, you would use the Tasker's controller reference
65            println!("  tasker handle available for controller access");
66        }
67
68        // 3. Async click - post now, will wait later
69        // (In real code, you'd get controller from context.tasker)
70        println!("  [Demo] Would post async click at (10, 20)");
71
72        // 4. Override pipeline for all subsequent operations in this context
73        let _ = context.override_pipeline(r#"{"MyCustomOCR": {"roi": [1, 1, 114, 514]}}"#);
74
75        // 5. Check if tasker is stopping - IMPORTANT for responsive cancellation
76        // Note: Context provides tasker_handle() which returns a raw pointer.
77        // In production code, you should wrap this or use the Tasker instance directly.
78        // Here we demonstrate the raw API call for completeness.
79        let tasker_ptr = context.tasker_handle();
80        if !tasker_ptr.is_null() {
81            // Using sys:: directly requires unsafe - this matches C API usage
82            let is_stopping = unsafe { sys::MaaTaskerStopping(tasker_ptr) != 0 };
83            if is_stopping {
84                println!("  Task is stopping, returning early!");
85                return Some((
86                    common::Rect {
87                        x: 0,
88                        y: 0,
89                        width: 0,
90                        height: 0,
91                    },
92                    r#"{"status": "Task Stopped"}"#.to_string(),
93                ));
94            }
95        }
96
97        // 6. Wait for the async click to complete
98        println!("  [Demo] Async click would complete here");
99
100        // 7. Clone context for independent operations (modifications won't affect original)
101        if let Ok(new_ctx) = context.clone_context() {
102            let _ = new_ctx.override_pipeline(r#"{"MyCustomOCR": {"roi": [100, 200, 300, 400]}}"#);
103
104            // Run recognition and use the result
105            if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
106                let reco_id = new_ctx.run_recognition("MyCustomOCR", "{}", &img_buf);
107
108                // If recognition succeeded, get the tasker to retrieve details
109                if reco_id.is_ok() {
110                    // In a real scenario, you would:
111                    // 1. Get recognition detail from tasker
112                    // 2. Check if it hit
113                    // 3. Use the box coordinates to click
114                    println!("  [Demo] Would get reco detail and click on result box");
115
116                    // Example of clicking on recognition result box:
117                    // if let Ok(Some(detail)) = tasker.get_recognition_detail(reco_id) {
118                    //     if detail.hit {
119                    //         let box_rect = detail.box_rect;
120                    //         controller.post_click(box_rect.x, box_rect.y).wait();
121                    //     }
122                    // }
123                }
124            }
125            // new_ctx changes don't affect original context
126        }
127
128        // 8. Get current task ID
129        let task_id = context.task_id();
130        println!("  current task_id: {}", task_id);
131
132        // 9. Get task job for result retrieval
133        let task_job = context.get_task_job();
134        if let Ok(Some(detail)) = task_job.get(false) {
135            println!("  task entry: {}", detail.entry);
136        }
137
138        // Return recognition result: bounding box + detail JSON
139        Some((
140            common::Rect {
141                x: 0,
142                y: 0,
143                width: 100,
144                height: 100,
145            },
146            r#"{"message": "Hello World!"}"#.to_string(),
147        ))
148    }
Source

pub fn raw(&self) -> *mut MaaContext

Returns the underlying raw MaaContext pointer.

Useful for advanced FFI interop scenarios.

Source

pub fn run_recognition( &self, entry: &str, pipeline_override: &str, image: &MaaImageBuffer, ) -> MaaResult<i64>

Runs a specific recognition task with an input image.

§Arguments
  • entry - The task entry name.
  • pipeline_override - A JSON string for parameter overrides.
  • image - The input image buffer.
§Returns

Returns the job ID associated with the recognition task.

Examples found in repository?
examples/main.rs (line 57)
37    fn analyze(
38        &self,
39        context: &Context,
40        _task_id: sys::MaaTaskId,
41        node_name: &str,
42        custom_recognition_name: &str,
43        custom_recognition_param: &str,
44        _image: &maa_framework::buffer::MaaImageBuffer,
45        _roi: &maa_framework::common::Rect,
46    ) -> Option<(maa_framework::common::Rect, String)> {
47        println!(
48            "[MyRecognition] analyze called: node={}, name={}, param={}",
49            node_name, custom_recognition_name, custom_recognition_param
50        );
51
52        // --- Context API Demo ---
53
54        // 1. Run sub-pipeline recognition with override
55        let pp_override = r#"{"MyCustomOCR": {"recognition": "OCR", "roi": [100, 100, 200, 300]}}"#;
56        if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
57            let reco_id = context.run_recognition("MyCustomOCR", pp_override, &img_buf);
58            println!("  run_recognition result: {:?}", reco_id);
59        }
60
61        // 2. Take a new screenshot via tasker's controller
62        let tasker_ptr = context.tasker_handle();
63        if !tasker_ptr.is_null() {
64            // Note: In real usage, you would use the Tasker's controller reference
65            println!("  tasker handle available for controller access");
66        }
67
68        // 3. Async click - post now, will wait later
69        // (In real code, you'd get controller from context.tasker)
70        println!("  [Demo] Would post async click at (10, 20)");
71
72        // 4. Override pipeline for all subsequent operations in this context
73        let _ = context.override_pipeline(r#"{"MyCustomOCR": {"roi": [1, 1, 114, 514]}}"#);
74
75        // 5. Check if tasker is stopping - IMPORTANT for responsive cancellation
76        // Note: Context provides tasker_handle() which returns a raw pointer.
77        // In production code, you should wrap this or use the Tasker instance directly.
78        // Here we demonstrate the raw API call for completeness.
79        let tasker_ptr = context.tasker_handle();
80        if !tasker_ptr.is_null() {
81            // Using sys:: directly requires unsafe - this matches C API usage
82            let is_stopping = unsafe { sys::MaaTaskerStopping(tasker_ptr) != 0 };
83            if is_stopping {
84                println!("  Task is stopping, returning early!");
85                return Some((
86                    common::Rect {
87                        x: 0,
88                        y: 0,
89                        width: 0,
90                        height: 0,
91                    },
92                    r#"{"status": "Task Stopped"}"#.to_string(),
93                ));
94            }
95        }
96
97        // 6. Wait for the async click to complete
98        println!("  [Demo] Async click would complete here");
99
100        // 7. Clone context for independent operations (modifications won't affect original)
101        if let Ok(new_ctx) = context.clone_context() {
102            let _ = new_ctx.override_pipeline(r#"{"MyCustomOCR": {"roi": [100, 200, 300, 400]}}"#);
103
104            // Run recognition and use the result
105            if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
106                let reco_id = new_ctx.run_recognition("MyCustomOCR", "{}", &img_buf);
107
108                // If recognition succeeded, get the tasker to retrieve details
109                if reco_id.is_ok() {
110                    // In a real scenario, you would:
111                    // 1. Get recognition detail from tasker
112                    // 2. Check if it hit
113                    // 3. Use the box coordinates to click
114                    println!("  [Demo] Would get reco detail and click on result box");
115
116                    // Example of clicking on recognition result box:
117                    // if let Ok(Some(detail)) = tasker.get_recognition_detail(reco_id) {
118                    //     if detail.hit {
119                    //         let box_rect = detail.box_rect;
120                    //         controller.post_click(box_rect.x, box_rect.y).wait();
121                    //     }
122                    // }
123                }
124            }
125            // new_ctx changes don't affect original context
126        }
127
128        // 8. Get current task ID
129        let task_id = context.task_id();
130        println!("  current task_id: {}", task_id);
131
132        // 9. Get task job for result retrieval
133        let task_job = context.get_task_job();
134        if let Ok(Some(detail)) = task_job.get(false) {
135            println!("  task entry: {}", detail.entry);
136        }
137
138        // Return recognition result: bounding box + detail JSON
139        Some((
140            common::Rect {
141                x: 0,
142                y: 0,
143                width: 100,
144                height: 100,
145            },
146            r#"{"message": "Hello World!"}"#.to_string(),
147        ))
148    }
Source

pub fn run_recognition_direct( &self, reco_type: &str, reco_param: &str, image: &MaaImageBuffer, ) -> MaaResult<Option<RecognitionDetail>>

Performs a direct recognition operation.

This executes a specific recognition algorithm immediately, bypassing the pipeline structure.

§Arguments
  • reco_type - The specific recognition algorithm type (e.g., “TemplateMatch”, “OCR”).
  • reco_param - A JSON string containing the recognition parameters.
  • image - The image buffer to perform recognition on.
§Returns

Returns Some(RecognitionDetail) if successful, or None if the operation failed to initiate or yielded no result.

Source

pub fn run_action( &self, entry: &str, pipeline_override: &str, box_rect: &Rect, reco_detail: &str, ) -> MaaResult<i64>

Runs a specific action with context parameters.

§Arguments
  • entry - The task entry name.
  • pipeline_override - A JSON string for parameter overrides.
  • box_rect - The target region for the action.
  • reco_detail - A string containing details from a previous recognition step.
§Returns

Returns the job ID associated with the action.

Examples found in repository?
examples/main.rs (lines 181-191)
161    fn run(
162        &self,
163        context: &Context,
164        _task_id: sys::MaaTaskId,
165        node_name: &str,
166        custom_action_name: &str,
167        custom_action_param: &str,
168        reco_id: sys::MaaRecoId,
169        box_rect: &maa_framework::common::Rect,
170    ) -> bool {
171        println!(
172            "[MyAction] run called: node={}, name={}, param={}",
173            node_name, custom_action_name, custom_action_param
174        );
175        println!(
176            "  reco_id={}, box=({}, {}, {}, {})",
177            reco_id, box_rect.x, box_rect.y, box_rect.width, box_rect.height
178        );
179
180        // You can use Context API here too
181        let _ = context.run_action(
182            "Click",
183            "{}",
184            &common::Rect {
185                x: 114,
186                y: 514,
187                width: 100,
188                height: 100,
189            },
190            "{}",
191        );
192
193        true // Return true for success, false for failure
194    }
Source

pub fn run_action_direct( &self, action_type: &str, action_param: &str, box_rect: &Rect, reco_detail: &str, ) -> MaaResult<Option<ActionDetail>>

Performs a direct action operation.

This executes a specific action immediately, bypassing the pipeline structure.

§Arguments
  • action_type - The type of action to perform (e.g., “Click”, “Swipe”).
  • action_param - A JSON string containing the action parameters.
  • box_rect - The target region for the action (e.g., derived from recognition results).
  • reco_detail - Contextual details from a previous recognition step.
§Returns

Returns Some(ActionDetail) on success, or None if the operation failed.

Source

pub fn override_next( &self, node_name: &str, next_list: &[&str], ) -> MaaResult<bool>

Overrides the execution list for a specific node.

§Arguments
  • node_name - The name of the target node.
  • next_list - A slice of strings representing the new next list. Supports special signals like [JumpBack] and [Anchor].
§Returns
  • Ok(true) if the override was successful.
  • Ok(false) if the operation failed.
Source

pub fn get_node_data(&self, node_name: &str) -> MaaResult<Option<String>>

Retrieves data associated with a specific node.

§Arguments
  • node_name - The name of the node.
§Returns

Returns the node data as a String if available, or None otherwise.

Source

pub fn get_node_object( &self, node_name: &str, ) -> MaaResult<Option<PipelineData>>

Retrieves and deserializes the object associated with a node.

This is a convenience wrapper around get_node_data that parses the result into PipelineData.

§Arguments
  • node_name - The name of the node.
§Errors

Returns MaaError::InvalidConfig if the data cannot be parsed.

Source

pub fn task_id(&self) -> MaaId

Returns the ID of the current task.

Examples found in repository?
examples/main.rs (line 129)
37    fn analyze(
38        &self,
39        context: &Context,
40        _task_id: sys::MaaTaskId,
41        node_name: &str,
42        custom_recognition_name: &str,
43        custom_recognition_param: &str,
44        _image: &maa_framework::buffer::MaaImageBuffer,
45        _roi: &maa_framework::common::Rect,
46    ) -> Option<(maa_framework::common::Rect, String)> {
47        println!(
48            "[MyRecognition] analyze called: node={}, name={}, param={}",
49            node_name, custom_recognition_name, custom_recognition_param
50        );
51
52        // --- Context API Demo ---
53
54        // 1. Run sub-pipeline recognition with override
55        let pp_override = r#"{"MyCustomOCR": {"recognition": "OCR", "roi": [100, 100, 200, 300]}}"#;
56        if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
57            let reco_id = context.run_recognition("MyCustomOCR", pp_override, &img_buf);
58            println!("  run_recognition result: {:?}", reco_id);
59        }
60
61        // 2. Take a new screenshot via tasker's controller
62        let tasker_ptr = context.tasker_handle();
63        if !tasker_ptr.is_null() {
64            // Note: In real usage, you would use the Tasker's controller reference
65            println!("  tasker handle available for controller access");
66        }
67
68        // 3. Async click - post now, will wait later
69        // (In real code, you'd get controller from context.tasker)
70        println!("  [Demo] Would post async click at (10, 20)");
71
72        // 4. Override pipeline for all subsequent operations in this context
73        let _ = context.override_pipeline(r#"{"MyCustomOCR": {"roi": [1, 1, 114, 514]}}"#);
74
75        // 5. Check if tasker is stopping - IMPORTANT for responsive cancellation
76        // Note: Context provides tasker_handle() which returns a raw pointer.
77        // In production code, you should wrap this or use the Tasker instance directly.
78        // Here we demonstrate the raw API call for completeness.
79        let tasker_ptr = context.tasker_handle();
80        if !tasker_ptr.is_null() {
81            // Using sys:: directly requires unsafe - this matches C API usage
82            let is_stopping = unsafe { sys::MaaTaskerStopping(tasker_ptr) != 0 };
83            if is_stopping {
84                println!("  Task is stopping, returning early!");
85                return Some((
86                    common::Rect {
87                        x: 0,
88                        y: 0,
89                        width: 0,
90                        height: 0,
91                    },
92                    r#"{"status": "Task Stopped"}"#.to_string(),
93                ));
94            }
95        }
96
97        // 6. Wait for the async click to complete
98        println!("  [Demo] Async click would complete here");
99
100        // 7. Clone context for independent operations (modifications won't affect original)
101        if let Ok(new_ctx) = context.clone_context() {
102            let _ = new_ctx.override_pipeline(r#"{"MyCustomOCR": {"roi": [100, 200, 300, 400]}}"#);
103
104            // Run recognition and use the result
105            if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
106                let reco_id = new_ctx.run_recognition("MyCustomOCR", "{}", &img_buf);
107
108                // If recognition succeeded, get the tasker to retrieve details
109                if reco_id.is_ok() {
110                    // In a real scenario, you would:
111                    // 1. Get recognition detail from tasker
112                    // 2. Check if it hit
113                    // 3. Use the box coordinates to click
114                    println!("  [Demo] Would get reco detail and click on result box");
115
116                    // Example of clicking on recognition result box:
117                    // if let Ok(Some(detail)) = tasker.get_recognition_detail(reco_id) {
118                    //     if detail.hit {
119                    //         let box_rect = detail.box_rect;
120                    //         controller.post_click(box_rect.x, box_rect.y).wait();
121                    //     }
122                    // }
123                }
124            }
125            // new_ctx changes don't affect original context
126        }
127
128        // 8. Get current task ID
129        let task_id = context.task_id();
130        println!("  current task_id: {}", task_id);
131
132        // 9. Get task job for result retrieval
133        let task_job = context.get_task_job();
134        if let Ok(Some(detail)) = task_job.get(false) {
135            println!("  task entry: {}", detail.entry);
136        }
137
138        // Return recognition result: bounding box + detail JSON
139        Some((
140            common::Rect {
141                x: 0,
142                y: 0,
143                width: 100,
144                height: 100,
145            },
146            r#"{"message": "Hello World!"}"#.to_string(),
147        ))
148    }
Source

pub fn set_anchor(&self, anchor_name: &str, node_name: &str) -> MaaResult<()>

Associates an anchor with a specific node.

§Arguments
  • anchor_name - The name of the anchor.
  • node_name - The name of the target node.
Source

pub fn get_anchor(&self, anchor_name: &str) -> MaaResult<Option<String>>

Retrieves the node name associated with an anchor.

§Arguments
  • anchor_name - The name of the anchor.
§Returns

Returns the node name as a String if the anchor exists.

Source

pub fn get_hit_count(&self, node_name: &str) -> MaaResult<u64>

Retrieves the hit count for a specific node.

Hit count tracks how many times a node has been executed.

§Arguments
  • node_name - The name of the node to query.
§Returns

The number of times the node has been executed, or 0 if not found.

Source

pub fn clear_hit_count(&self, node_name: &str) -> MaaResult<()>

Resets the hit count for a specific node to zero.

§Arguments
  • node_name - The name of the node to reset.
Source

pub fn clone_context(&self) -> MaaResult<Self>

Creates a clone of the current context.

The new context can be used for independent execution threads, preventing state interference with the original context.

Examples found in repository?
examples/main.rs (line 101)
37    fn analyze(
38        &self,
39        context: &Context,
40        _task_id: sys::MaaTaskId,
41        node_name: &str,
42        custom_recognition_name: &str,
43        custom_recognition_param: &str,
44        _image: &maa_framework::buffer::MaaImageBuffer,
45        _roi: &maa_framework::common::Rect,
46    ) -> Option<(maa_framework::common::Rect, String)> {
47        println!(
48            "[MyRecognition] analyze called: node={}, name={}, param={}",
49            node_name, custom_recognition_name, custom_recognition_param
50        );
51
52        // --- Context API Demo ---
53
54        // 1. Run sub-pipeline recognition with override
55        let pp_override = r#"{"MyCustomOCR": {"recognition": "OCR", "roi": [100, 100, 200, 300]}}"#;
56        if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
57            let reco_id = context.run_recognition("MyCustomOCR", pp_override, &img_buf);
58            println!("  run_recognition result: {:?}", reco_id);
59        }
60
61        // 2. Take a new screenshot via tasker's controller
62        let tasker_ptr = context.tasker_handle();
63        if !tasker_ptr.is_null() {
64            // Note: In real usage, you would use the Tasker's controller reference
65            println!("  tasker handle available for controller access");
66        }
67
68        // 3. Async click - post now, will wait later
69        // (In real code, you'd get controller from context.tasker)
70        println!("  [Demo] Would post async click at (10, 20)");
71
72        // 4. Override pipeline for all subsequent operations in this context
73        let _ = context.override_pipeline(r#"{"MyCustomOCR": {"roi": [1, 1, 114, 514]}}"#);
74
75        // 5. Check if tasker is stopping - IMPORTANT for responsive cancellation
76        // Note: Context provides tasker_handle() which returns a raw pointer.
77        // In production code, you should wrap this or use the Tasker instance directly.
78        // Here we demonstrate the raw API call for completeness.
79        let tasker_ptr = context.tasker_handle();
80        if !tasker_ptr.is_null() {
81            // Using sys:: directly requires unsafe - this matches C API usage
82            let is_stopping = unsafe { sys::MaaTaskerStopping(tasker_ptr) != 0 };
83            if is_stopping {
84                println!("  Task is stopping, returning early!");
85                return Some((
86                    common::Rect {
87                        x: 0,
88                        y: 0,
89                        width: 0,
90                        height: 0,
91                    },
92                    r#"{"status": "Task Stopped"}"#.to_string(),
93                ));
94            }
95        }
96
97        // 6. Wait for the async click to complete
98        println!("  [Demo] Async click would complete here");
99
100        // 7. Clone context for independent operations (modifications won't affect original)
101        if let Ok(new_ctx) = context.clone_context() {
102            let _ = new_ctx.override_pipeline(r#"{"MyCustomOCR": {"roi": [100, 200, 300, 400]}}"#);
103
104            // Run recognition and use the result
105            if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
106                let reco_id = new_ctx.run_recognition("MyCustomOCR", "{}", &img_buf);
107
108                // If recognition succeeded, get the tasker to retrieve details
109                if reco_id.is_ok() {
110                    // In a real scenario, you would:
111                    // 1. Get recognition detail from tasker
112                    // 2. Check if it hit
113                    // 3. Use the box coordinates to click
114                    println!("  [Demo] Would get reco detail and click on result box");
115
116                    // Example of clicking on recognition result box:
117                    // if let Ok(Some(detail)) = tasker.get_recognition_detail(reco_id) {
118                    //     if detail.hit {
119                    //         let box_rect = detail.box_rect;
120                    //         controller.post_click(box_rect.x, box_rect.y).wait();
121                    //     }
122                    // }
123                }
124            }
125            // new_ctx changes don't affect original context
126        }
127
128        // 8. Get current task ID
129        let task_id = context.task_id();
130        println!("  current task_id: {}", task_id);
131
132        // 9. Get task job for result retrieval
133        let task_job = context.get_task_job();
134        if let Ok(Some(detail)) = task_job.get(false) {
135            println!("  task entry: {}", detail.entry);
136        }
137
138        // Return recognition result: bounding box + detail JSON
139        Some((
140            common::Rect {
141                x: 0,
142                y: 0,
143                width: 100,
144                height: 100,
145            },
146            r#"{"message": "Hello World!"}"#.to_string(),
147        ))
148    }
Source

pub fn tasker_handle(&self) -> *mut MaaTasker

Returns the raw handle to the associated Tasker instance.

§Safety

The returned pointer is owned by the framework. The caller must not attempt to destroy or free it.

Examples found in repository?
examples/main.rs (line 62)
37    fn analyze(
38        &self,
39        context: &Context,
40        _task_id: sys::MaaTaskId,
41        node_name: &str,
42        custom_recognition_name: &str,
43        custom_recognition_param: &str,
44        _image: &maa_framework::buffer::MaaImageBuffer,
45        _roi: &maa_framework::common::Rect,
46    ) -> Option<(maa_framework::common::Rect, String)> {
47        println!(
48            "[MyRecognition] analyze called: node={}, name={}, param={}",
49            node_name, custom_recognition_name, custom_recognition_param
50        );
51
52        // --- Context API Demo ---
53
54        // 1. Run sub-pipeline recognition with override
55        let pp_override = r#"{"MyCustomOCR": {"recognition": "OCR", "roi": [100, 100, 200, 300]}}"#;
56        if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
57            let reco_id = context.run_recognition("MyCustomOCR", pp_override, &img_buf);
58            println!("  run_recognition result: {:?}", reco_id);
59        }
60
61        // 2. Take a new screenshot via tasker's controller
62        let tasker_ptr = context.tasker_handle();
63        if !tasker_ptr.is_null() {
64            // Note: In real usage, you would use the Tasker's controller reference
65            println!("  tasker handle available for controller access");
66        }
67
68        // 3. Async click - post now, will wait later
69        // (In real code, you'd get controller from context.tasker)
70        println!("  [Demo] Would post async click at (10, 20)");
71
72        // 4. Override pipeline for all subsequent operations in this context
73        let _ = context.override_pipeline(r#"{"MyCustomOCR": {"roi": [1, 1, 114, 514]}}"#);
74
75        // 5. Check if tasker is stopping - IMPORTANT for responsive cancellation
76        // Note: Context provides tasker_handle() which returns a raw pointer.
77        // In production code, you should wrap this or use the Tasker instance directly.
78        // Here we demonstrate the raw API call for completeness.
79        let tasker_ptr = context.tasker_handle();
80        if !tasker_ptr.is_null() {
81            // Using sys:: directly requires unsafe - this matches C API usage
82            let is_stopping = unsafe { sys::MaaTaskerStopping(tasker_ptr) != 0 };
83            if is_stopping {
84                println!("  Task is stopping, returning early!");
85                return Some((
86                    common::Rect {
87                        x: 0,
88                        y: 0,
89                        width: 0,
90                        height: 0,
91                    },
92                    r#"{"status": "Task Stopped"}"#.to_string(),
93                ));
94            }
95        }
96
97        // 6. Wait for the async click to complete
98        println!("  [Demo] Async click would complete here");
99
100        // 7. Clone context for independent operations (modifications won't affect original)
101        if let Ok(new_ctx) = context.clone_context() {
102            let _ = new_ctx.override_pipeline(r#"{"MyCustomOCR": {"roi": [100, 200, 300, 400]}}"#);
103
104            // Run recognition and use the result
105            if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
106                let reco_id = new_ctx.run_recognition("MyCustomOCR", "{}", &img_buf);
107
108                // If recognition succeeded, get the tasker to retrieve details
109                if reco_id.is_ok() {
110                    // In a real scenario, you would:
111                    // 1. Get recognition detail from tasker
112                    // 2. Check if it hit
113                    // 3. Use the box coordinates to click
114                    println!("  [Demo] Would get reco detail and click on result box");
115
116                    // Example of clicking on recognition result box:
117                    // if let Ok(Some(detail)) = tasker.get_recognition_detail(reco_id) {
118                    //     if detail.hit {
119                    //         let box_rect = detail.box_rect;
120                    //         controller.post_click(box_rect.x, box_rect.y).wait();
121                    //     }
122                    // }
123                }
124            }
125            // new_ctx changes don't affect original context
126        }
127
128        // 8. Get current task ID
129        let task_id = context.task_id();
130        println!("  current task_id: {}", task_id);
131
132        // 9. Get task job for result retrieval
133        let task_job = context.get_task_job();
134        if let Ok(Some(detail)) = task_job.get(false) {
135            println!("  task entry: {}", detail.entry);
136        }
137
138        // Return recognition result: bounding box + detail JSON
139        Some((
140            common::Rect {
141                x: 0,
142                y: 0,
143                width: 100,
144                height: 100,
145            },
146            r#"{"message": "Hello World!"}"#.to_string(),
147        ))
148    }
Source

pub fn override_image( &self, image_name: &str, image: &MaaImageBuffer, ) -> MaaResult<()>

Overrides a global image resource with a provided buffer.

§Arguments
  • image_name - The identifier of the image to override.
  • image - The new image data buffer.
Source

pub fn get_task_job<'a>(&'a self) -> JobWithResult<'a, TaskDetail>

Retrieves a job handle representing the current task’s execution state.

The returned job is bound to the lifetime of the Context to ensure safety.

Examples found in repository?
examples/main.rs (line 133)
37    fn analyze(
38        &self,
39        context: &Context,
40        _task_id: sys::MaaTaskId,
41        node_name: &str,
42        custom_recognition_name: &str,
43        custom_recognition_param: &str,
44        _image: &maa_framework::buffer::MaaImageBuffer,
45        _roi: &maa_framework::common::Rect,
46    ) -> Option<(maa_framework::common::Rect, String)> {
47        println!(
48            "[MyRecognition] analyze called: node={}, name={}, param={}",
49            node_name, custom_recognition_name, custom_recognition_param
50        );
51
52        // --- Context API Demo ---
53
54        // 1. Run sub-pipeline recognition with override
55        let pp_override = r#"{"MyCustomOCR": {"recognition": "OCR", "roi": [100, 100, 200, 300]}}"#;
56        if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
57            let reco_id = context.run_recognition("MyCustomOCR", pp_override, &img_buf);
58            println!("  run_recognition result: {:?}", reco_id);
59        }
60
61        // 2. Take a new screenshot via tasker's controller
62        let tasker_ptr = context.tasker_handle();
63        if !tasker_ptr.is_null() {
64            // Note: In real usage, you would use the Tasker's controller reference
65            println!("  tasker handle available for controller access");
66        }
67
68        // 3. Async click - post now, will wait later
69        // (In real code, you'd get controller from context.tasker)
70        println!("  [Demo] Would post async click at (10, 20)");
71
72        // 4. Override pipeline for all subsequent operations in this context
73        let _ = context.override_pipeline(r#"{"MyCustomOCR": {"roi": [1, 1, 114, 514]}}"#);
74
75        // 5. Check if tasker is stopping - IMPORTANT for responsive cancellation
76        // Note: Context provides tasker_handle() which returns a raw pointer.
77        // In production code, you should wrap this or use the Tasker instance directly.
78        // Here we demonstrate the raw API call for completeness.
79        let tasker_ptr = context.tasker_handle();
80        if !tasker_ptr.is_null() {
81            // Using sys:: directly requires unsafe - this matches C API usage
82            let is_stopping = unsafe { sys::MaaTaskerStopping(tasker_ptr) != 0 };
83            if is_stopping {
84                println!("  Task is stopping, returning early!");
85                return Some((
86                    common::Rect {
87                        x: 0,
88                        y: 0,
89                        width: 0,
90                        height: 0,
91                    },
92                    r#"{"status": "Task Stopped"}"#.to_string(),
93                ));
94            }
95        }
96
97        // 6. Wait for the async click to complete
98        println!("  [Demo] Async click would complete here");
99
100        // 7. Clone context for independent operations (modifications won't affect original)
101        if let Ok(new_ctx) = context.clone_context() {
102            let _ = new_ctx.override_pipeline(r#"{"MyCustomOCR": {"roi": [100, 200, 300, 400]}}"#);
103
104            // Run recognition and use the result
105            if let Ok(img_buf) = buffer::MaaImageBuffer::new() {
106                let reco_id = new_ctx.run_recognition("MyCustomOCR", "{}", &img_buf);
107
108                // If recognition succeeded, get the tasker to retrieve details
109                if reco_id.is_ok() {
110                    // In a real scenario, you would:
111                    // 1. Get recognition detail from tasker
112                    // 2. Check if it hit
113                    // 3. Use the box coordinates to click
114                    println!("  [Demo] Would get reco detail and click on result box");
115
116                    // Example of clicking on recognition result box:
117                    // if let Ok(Some(detail)) = tasker.get_recognition_detail(reco_id) {
118                    //     if detail.hit {
119                    //         let box_rect = detail.box_rect;
120                    //         controller.post_click(box_rect.x, box_rect.y).wait();
121                    //     }
122                    // }
123                }
124            }
125            // new_ctx changes don't affect original context
126        }
127
128        // 8. Get current task ID
129        let task_id = context.task_id();
130        println!("  current task_id: {}", task_id);
131
132        // 9. Get task job for result retrieval
133        let task_job = context.get_task_job();
134        if let Ok(Some(detail)) = task_job.get(false) {
135            println!("  task entry: {}", detail.entry);
136        }
137
138        // Return recognition result: bounding box + detail JSON
139        Some((
140            common::Rect {
141                x: 0,
142                y: 0,
143                width: 100,
144                height: 100,
145            },
146            r#"{"message": "Hello World!"}"#.to_string(),
147        ))
148    }
Source

pub fn clear_all_hit_counts(&self) -> MaaResult<()>

Resets hit counts for all nodes in the context.

This clears the execution history for all nodes, resetting their hit counts to zero.

Trait Implementations§

Source§

impl Debug for Context

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Send for Context

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.