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
6use accesskit::{ActionHandler, ActionRequest};
7use accesskit_consumer::Tree;
8use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
9
10use crate::WindowBounds;
11
12pub(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
19impl 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
55pub 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
63impl 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