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
//! What a declared property holds: a constant, a signal, or nothing.
//!
//! Every styling property used to be an `Option<Signal<T>>`, and a constant
//! went into it through the cheapest signal there is — [`create_stored`], no
//! `RefCell`, no tracking, documented as such. It was still a signal, and a
//! signal costs an arena slot however little it does with one: an `Rc`, a
//! `Slot` in storage, an entry in the owner's disposal list, and an index in
//! `signal_subscribers` that the next tracked signal pads out even though a
//! stored one never registers there.
//!
//! Measured at ~112 bytes per property set, which on a list of twenty thousand
//! rows is 22% of what a row costs (#450). The constant is 16 of those bytes,
//! and the rest is the machinery for reacting to a value that does not change.
//!
//! So a property keeps the constant where the constant is. [`IntoSignal`] has
//! always known which it was given — `ValueMarker` against `ClosureMarker`,
//! decided at the type level before any of this existed — so `into_prop` reads
//! the answer off the marker rather than asking anything at runtime, and the
//! public spelling does not move: `.background(RED)` and `.background(|| red())`
//! differ by exactly what they differed by before.
//!
//! [`create_stored`]: crate::reactive::create_stored
//! [`IntoSignal`]: crate::reactive::IntoSignal
use Signal;
/// A property as it was declared.
///
/// The three cases a setter can be handed, kept apart so the constant one
/// costs a constant. Read it with [`get_or`](Prop::get_or) and its siblings,
/// which answer the same questions `Option<Signal<T>>` answered and in the same
/// words.
/// Written out rather than derived, because the derive would bound `T:
/// Default` and nothing here needs one: an undeclared property is `Unset`
/// whatever it would have held. `TransformProps` derives `Default` over four
/// of these, and `Translate` having a default is beside the point.