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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//! Pictures: registering the bytes once and drawing them by id.
//!
//! An asset is not part of the tree. It is bytes that have to reach the Renderer before
//! anything can draw them and have to outlive the frame that does, which is the opposite
//! of a node: a node is re-sent whenever it changes and points at nothing after the call
//! that carried it.
//!
//! So an asset is registered and forgotten, the way a message is posted and forgotten. It
//! rides out on the batch the current call produces, and everything after that is the id.
use crateAssetKind;
use RefCell;
/// One registration, waiting for the batch that carries it.
pub
thread_local!
/// Registers one picture and returns the id an [`crate::Image`] draws it by.
///
/// ```ignore
/// static HERO: &[u8] = include_bytes!("../assets/hero.svg");
///
/// rsx! { Image { asset_id: asset(AssetKind::Svg, HERO), height: 240.0 } }
/// ```
///
/// Call it wherever the picture is drawn, including in a component body that runs every
/// render. The second call with the same bytes returns the first call's id and queues
/// nothing, so a screen that draws the same picture every frame registers it once.
///
/// The bytes are `'static` because a registration is carried by whichever batch the
/// current call produces, which is not always the call this was made in, and because
/// `include_bytes!` is what an application almost always has.
/// Registers bytes this process built rather than bytes it was compiled with.
///
/// A gradient is worked out at run time, so there is no `include_bytes!` to point at. The
/// bytes are handed to the registry to keep for the life of the process, which is what
/// `'static` means here and what a registration is anyway: an asset has to outlive every
/// frame that draws it, and nothing ever un-registers by dropping.
///
/// The content comparison runs first, so building the same gradient on every render keeps
/// one copy. Only a brush nobody has registered before is kept.
/// The id these bytes were registered under, by address first and by content after.
///
/// Address first because that is the answer almost every time and it costs a comparison.
/// Content after because the same picture really can arrive at two addresses: a `const`
/// holding a reference is inlined at each use, and each use can get an allocation of its
/// own, so a catalogue written as a `const` array hands out two pointers to one file and
/// the shop registers the same cover twice under two ids. The full comparison only runs
/// when the address misses, which is once per new picture and never in the steady state.
/// Hands every queued registration to `emit` and empties the queue.
///
/// The buffer is moved out and put back, so the steady state, where nothing new has been
/// registered, touches an empty `Vec` and allocates nothing.
pub
/// Forgets every registration and every id. Used between tests.
/// Queues every registration again, for a Renderer that has not been told any of them.
///
/// What a new `Host` does instead of forgetting them. A new Host means a Renderer whose
/// cache is empty, so an id handed out before it names nothing over there, and the cure
/// for that is to say all of them again rather than to drop them.
///
/// Dropping them was wrong in a way that only shows on the screen. A theme names its fonts
/// by id and a window names its icon by id, and both are built by the caller before the
/// Host is made out of them: the ids travelled and the bytes they named had been thrown
/// away, so the window wore no icon and the screen was set in the machine's own face while
/// every batch looked correct.
///
/// Ids do not move. The same bytes keep the id they were given, which is what lets a theme
/// built before this still name the right thing after it.
pub