1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use polyhorn_android_sys::Runnable;
use polyhorn_core::{Command, Composition};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
use super::{Environment, OpaqueContainer, Platform};
#[derive(Clone)]
pub struct Compositor {
environment: Environment,
buffer: Arc<Mutex<Composition<Platform>>>,
counter: Arc<AtomicUsize>,
}
impl Compositor {
pub fn new(environment: Environment) -> Compositor {
Compositor {
environment,
buffer: Arc::new(Default::default()),
counter: Arc::new(AtomicUsize::default()),
}
}
fn next_id(&mut self) -> ContainerID {
let id = self.counter.fetch_add(1, Ordering::Relaxed);
ContainerID(id)
}
pub(crate) fn track(&mut self, container: OpaqueContainer) -> ContainerID {
let id = self.next_id();
self.buffer.lock().unwrap().insert(id, container);
id
}
}
impl polyhorn_core::Compositor<Platform> for Compositor {
fn buffer(&self) -> CommandBuffer {
CommandBuffer {
compositor: self.clone(),
commands: vec![],
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct ContainerID(usize);
pub struct CommandBuffer {
compositor: Compositor,
commands: Vec<Command<Platform>>,
}
impl polyhorn_core::CommandBuffer<Platform> for CommandBuffer {
fn mount<F>(&mut self, parent_id: ContainerID, initializer: F) -> ContainerID
where
F: FnOnce(&mut OpaqueContainer, &mut Environment) -> OpaqueContainer + Send + 'static,
{
let id = self.compositor.next_id();
self.commands
.push(Command::Mount(id, parent_id, Box::new(initializer)));
id
}
fn mutate<F>(&mut self, ids: &[ContainerID], mutator: F)
where
F: FnOnce(&mut [&mut OpaqueContainer], &mut Environment) + Send + 'static,
{
self.commands
.push(Command::Mutate(ids.to_owned(), Box::new(mutator)));
}
fn unmount(&mut self, id: ContainerID) {
self.commands.push(Command::Unmount(id));
}
fn layout(&mut self) {
self.mutate(&[], |_, environment| {
environment.layout_tree().write().unwrap().recompute_roots();
});
}
fn commit(mut self) {
let commands = std::mem::take(&mut self.commands);
let activity = self.compositor.environment.activity().clone();
let layout_tree = self.compositor.environment.layout_tree().clone();
let state = self.compositor.buffer.clone();
Runnable::new(&self.compositor.environment.env(), move |env| {
let mut environment = Environment::new(
activity,
unsafe { env.clone().prolong_lifetime() },
layout_tree.clone(),
);
let mut state = state.lock().unwrap();
for command in commands {
state.process(&mut environment, command);
}
let mut layout_tree = layout_tree.write().unwrap();
layout_tree.recompute_roots();
})
.queue(&self.compositor.environment.env());
}
}