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
116
117
118
119
120
121
122
123
124
use super::*;
use crate::{Context, EventGate, EventListenerType, NutsCheck};
pub fn register_frame<F: Frame + Activity>(
frame: F,
state: F::State,
pos: (u32, u32),
) -> FrameHandle<F> {
nuts::store_to_domain(&Domain::Frame, state);
register_frame_no_state(frame, pos)
}
pub fn register_frame_no_state<F: Frame + Activity>(frame: F, pos: (u32, u32)) -> FrameHandle<F> {
let div = div::new(pos.0, pos.1, F::WIDTH, F::HEIGHT, "").expect("Div failure");
let activity = nuts::new_domained_activity(frame, &Domain::Frame);
let area = Rectangle::new(pos, F::size());
let handle = FrameHandle::new(activity, div, area);
handle.init_frame_activity();
handle
}
struct Nop<STATE> {
_phantom: std::marker::PhantomData<STATE>,
}
impl<STATE> Frame for Nop<STATE> {
type State = STATE;
const WIDTH: u32 = 0;
const HEIGHT: u32 = 0;
}
impl<STATE: 'static, F: Frame<State = STATE> + Activity> FrameHandle<F> {
fn init_frame_activity(&self) {
let activity = self.activity();
let area = self.region();
let div: div::DivHandle = self.div().clone();
if (F::update as usize) != (Nop::<F::State>::update as usize) {
activity.subscribe_domained(|a, d, _msg: &UpdateWorld| {
let global_state: &mut F::State = d.try_get_mut().expect("Activity State missing");
a.update(global_state)
});
}
if (F::draw as usize) != (Nop::<F::State>::draw as usize) {
activity.subscribe_domained(move |a: &mut F, d: &mut DomainState, msg: &DrawWorld| {
let (global_state, ctx) = d.try_get_2_mut::<F::State, Context>();
let canvas = ctx
.expect("Context missing")
.display_region(area, div.clone());
a.draw(
global_state.expect("Activity State missing"),
canvas,
msg.time_ms,
)
});
}
if (F::pointer as usize) != (Nop::<F::State>::pointer as usize) {
activity.private_domained_channel(|a, d, msg: PointerEvent| {
let (global_state, ctx) = d.try_get_2_mut::<F::State, Context>();
let global_state: &mut F::State = global_state.expect("Activity State missing");
let display = ctx.expect("Context missing").display.full();
let projected_pos = msg.1 / display.browser_to_game_pixel_ratio();
a.pointer(global_state, PointerEvent(msg.0, projected_pos))
});
EventGate::listen(self, EventListenerType::Click);
if js::supports_pointer_events() {
EventGate::listen(self, EventListenerType::BrowserPointer);
} else {
EventGate::listen(self, EventListenerType::Mouse);
EventGate::listen(self, EventListenerType::Touch);
}
}
let div: div::DivHandle = self.div().clone();
if (F::enter as usize) != (Nop::<F::State>::enter as usize) {
activity.on_enter_domained(move |a, d| {
div.show().nuts_check();
let global_state: &mut F::State = d.try_get_mut().expect("Activity State missing");
a.enter(global_state)
});
}
let div: div::DivHandle = self.div().clone();
if (F::leave as usize) != (Nop::<F::State>::leave as usize) {
activity.on_leave_domained(move |a, d| {
div.hide().nuts_check();
let global_state: &mut F::State = d.try_get_mut().expect("Activity State missing");
a.leave(global_state)
});
}
if (F::key as usize) != (Nop::<F::State>::key as usize) {
activity.private_domained_channel(|a, d, msg: KeyEvent| {
let global_state = d.try_get_mut::<F::State>().expect("Activity State missing");
a.key(global_state, msg)
});
EventGate::listen(self, EventListenerType::Keyboard)
}
}
}
impl<STATE: 'static, FRAME: Frame<State = STATE>> FrameHandle<FRAME> {
pub fn listen<F, MSG>(&self, f: F)
where
F: Fn(&mut FRAME, &mut STATE, &MSG) + Copy + 'static,
MSG: 'static,
FRAME: 'static,
{
self.activity_id.subscribe_domained_masked(
SubscriptionFilter::no_filter(),
move |a, d, msg: &GlobalEvent<MSG>| {
let global_state: &mut FRAME::State =
d.try_get_mut().expect("Activity State missing");
f(a, global_state, &msg.0);
},
);
self.activity_id
.subscribe_domained(move |a, d, msg: &ActiveEvent<MSG>| {
let global_state: &mut FRAME::State =
d.try_get_mut().expect("Activity State missing");
f(a, global_state, &msg.0);
});
}
}