1 | // Copyright 2023 The AccessKit Authors. All rights reserved. |
2 | // Licensed under the Apache License, Version 2.0 (found in |
3 | // the LICENSE-APACHE file) or the MIT license (found in |
4 | // the LICENSE-MIT file), at your option. |
5 | |
6 | use accesskit::{ActionHandler, ActionRequest}; |
7 | use accesskit_consumer::Tree; |
8 | use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; |
9 | |
10 | use crate::WindowBounds; |
11 | |
12 | pub(crate) struct Context { |
13 | pub(crate) app_context: Arc<RwLock<AppContext>>, |
14 | pub(crate) tree: RwLock<Tree>, |
15 | pub(crate) action_handler: Mutex<Box<dyn ActionHandler + Send>>, |
16 | pub(crate) root_window_bounds: RwLock<WindowBounds>, |
17 | } |
18 | |
19 | impl Context { |
20 | pub(crate) fn new( |
21 | app_context: &Arc<RwLock<AppContext>>, |
22 | tree: Tree, |
23 | action_handler: Box<dyn ActionHandler + Send>, |
24 | root_window_bounds: WindowBounds, |
25 | ) -> Arc<Self> { |
26 | Arc::new(Self { |
27 | app_context: Arc::clone(app_context), |
28 | tree: RwLock::new(tree), |
29 | action_handler: Mutex::new(action_handler), |
30 | root_window_bounds: RwLock::new(root_window_bounds), |
31 | }) |
32 | } |
33 | |
34 | pub(crate) fn read_tree(&self) -> RwLockReadGuard<'_, Tree> { |
35 | self.tree.read().unwrap() |
36 | } |
37 | |
38 | pub(crate) fn read_root_window_bounds(&self) -> RwLockReadGuard<'_, WindowBounds> { |
39 | self.root_window_bounds.read().unwrap() |
40 | } |
41 | |
42 | pub fn do_action(&self, request: ActionRequest) { |
43 | self.action_handler.lock().unwrap().do_action(request); |
44 | } |
45 | |
46 | pub(crate) fn read_app_context(&self) -> RwLockReadGuard<'_, AppContext> { |
47 | self.app_context.read().unwrap() |
48 | } |
49 | |
50 | pub(crate) fn write_app_context(&self) -> RwLockWriteGuard<'_, AppContext> { |
51 | self.app_context.write().unwrap() |
52 | } |
53 | } |
54 | |
55 | pub struct AppContext { |
56 | pub(crate) name: Option<String>, |
57 | pub(crate) toolkit_name: Option<String>, |
58 | pub(crate) toolkit_version: Option<String>, |
59 | pub(crate) id: Option<i32>, |
60 | pub(crate) adapters: Vec<(usize, Arc<Context>)>, |
61 | } |
62 | |
63 | impl AppContext { |
64 | pub fn new() -> Arc<RwLock<Self>> { |
65 | Arc::new(RwLock::new(Self { |
66 | name: None, |
67 | toolkit_name: None, |
68 | toolkit_version: None, |
69 | id: None, |
70 | adapters: Vec::new(), |
71 | })) |
72 | } |
73 | |
74 | pub(crate) fn adapter_index(&self, id: usize) -> Result<usize, usize> { |
75 | self.adapters.binary_search_by(|adapter| adapter.0.cmp(&id)) |
76 | } |
77 | |
78 | pub(crate) fn push_adapter(&mut self, id: usize, context: &Arc<Context>) { |
79 | self.adapters.push((id, Arc::clone(context))); |
80 | } |
81 | |
82 | pub(crate) fn remove_adapter(&mut self, id: usize) { |
83 | if let Ok(index) = self.adapter_index(id) { |
84 | self.adapters.remove(index); |
85 | } |
86 | } |
87 | } |
88 | |