@@ -7,31 +7,39 @@ open Fabulous.StackAllocatedCollections
77open Fabulous.StackAllocatedCollections .StackList
88open Microsoft.FSharp .Core
99
10- type AttributesBundle = ( struct ( StackList< ScalarAttribute> * WidgetAttribute[] voption * WidgetCollectionAttribute[] voption))
10+ type AttributesBundle = ( struct ( StackList< ScalarAttribute> * WidgetAttribute[] voption * WidgetCollectionAttribute[] voption * EnvironmentAttribute [] voption ))
1111
1212[<Struct; NoComparison; NoEquality>]
1313type WidgetBuilder < 'msg , 'marker when 'msg: equality > =
1414 struct
1515 val Key : WidgetKey
1616 val Attributes : AttributesBundle
1717
18+ new ( key: WidgetKey) =
19+ { Key = key
20+ Attributes = AttributesBundle( StackList.empty(), ValueNone, ValueNone, ValueNone) }
21+
1822 new ( key: WidgetKey, attributes: AttributesBundle) = { Key = key; Attributes = attributes }
1923
2024 new ( key: WidgetKey, scalar: ScalarAttribute) =
2125 { Key = key
22- Attributes = AttributesBundle( StackList.one scalar, ValueNone, ValueNone) }
26+ Attributes = AttributesBundle( StackList.one scalar, ValueNone, ValueNone, ValueNone ) }
2327
2428 new ( key: WidgetKey, scalarA: ScalarAttribute, scalarB: ScalarAttribute) =
2529 { Key = key
26- Attributes = AttributesBundle( StackList.two( scalarA, scalarB), ValueNone, ValueNone) }
30+ Attributes = AttributesBundle( StackList.two( scalarA, scalarB), ValueNone, ValueNone, ValueNone ) }
2731
2832 new ( key: WidgetKey, scalar1: ScalarAttribute, scalar2: ScalarAttribute, scalar3: ScalarAttribute) =
2933 { Key = key
30- Attributes = AttributesBundle( StackList.three( scalar1, scalar2, scalar3), ValueNone, ValueNone) }
34+ Attributes = AttributesBundle( StackList.three( scalar1, scalar2, scalar3), ValueNone, ValueNone, ValueNone) }
35+
36+ new ( key: WidgetKey, widget: WidgetAttribute) =
37+ { Key = key
38+ Attributes = AttributesBundle( StackList.empty(), ValueSome [| widget |], ValueNone, ValueNone) }
3139
3240 [<EditorBrowsable( EditorBrowsableState.Never) >]
3341 member x.Compile () : Widget =
34- let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes ) =
42+ let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes , environmentAttributes ) =
3543 x.Attributes
3644
3745 { Key = x.Key
@@ -41,19 +49,23 @@ type WidgetBuilder<'msg, 'marker when 'msg: equality> =
4149 ScalarAttributes =
4250 match StackList.length & scalarAttributes with
4351 | 0 us -> ValueNone
44- | _ -> ValueSome( Array.sortInPlace ( fun a -> a .Key) ( StackList.toArray & scalarAttributes))
52+ | _ -> ValueSome( Array.sortInPlace _ . Key ( StackList.toArray & scalarAttributes))
4553
46- WidgetAttributes = ValueOption.map ( Array.sortInPlace( fun a -> a .Key)) widgetAttributes
54+ WidgetAttributes = ValueOption.map ( Array.sortInPlace(_ . Key)) widgetAttributes
4755
56+ WidgetCollectionAttributes = widgetCollectionAttributes |> ValueOption.map( Array.sortInPlace(_. Key))
4857
49- WidgetCollectionAttributes = widgetCollectionAttributes |> ValueOption.map( Array.sortInPlace( fun a -> a .Key)) }
58+ EnvironmentAttributes = environmentAttributes |> ValueOption.map( Array.sortInPlace(_ . Key)) }
5059
5160 [<EditorBrowsable( EditorBrowsableState.Never) >]
5261 member inline x.AddScalar ( attr : ScalarAttribute ) =
53- let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes ) =
62+ let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes , environmentAttributes ) =
5463 x.Attributes
5564
56- WidgetBuilder< 'msg, 'marker>( x.Key, struct ( StackList.add(& scalarAttributes, attr), widgetAttributes, widgetCollectionAttributes))
65+ WidgetBuilder< 'msg, 'marker>(
66+ x.Key,
67+ struct ( StackList.add(& scalarAttributes, attr), widgetAttributes, widgetCollectionAttributes, environmentAttributes)
68+ )
5769
5870 [<EditorBrowsable( EditorBrowsableState.Never) >]
5971 member inline x.AddOrReplaceScalar
@@ -62,26 +74,29 @@ type WidgetBuilder<'msg, 'marker when 'msg: equality> =
6274 [<InlineIfLambda>] replaceWith : ScalarAttribute -> ScalarAttribute ,
6375 [<InlineIfLambda>] defaultWith : unit -> ScalarAttribute
6476 ) =
65- let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes ) =
77+ let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes , environmentAttributes ) =
6678 x.Attributes
6779
6880 match StackList.tryFind(& scalarAttributes, ( fun attr -> attr.Key = attrKey)) with
6981 | ValueNone ->
7082 let attr = defaultWith()
7183
72- WidgetBuilder< 'msg, 'marker>( x.Key, struct ( StackList.add(& scalarAttributes, attr), widgetAttributes, widgetCollectionAttributes))
84+ WidgetBuilder< 'msg, 'marker>(
85+ x.Key,
86+ struct ( StackList.add(& scalarAttributes, attr), widgetAttributes, widgetCollectionAttributes, environmentAttributes)
87+ )
7388
7489 | ValueSome attr ->
7590 let newAttr = replaceWith attr
7691
7792 let newAttrs =
7893 StackList.replace(& scalarAttributes, ( fun attr -> attr.Key = attrKey), newAttr)
7994
80- WidgetBuilder< 'msg, 'marker>( x.Key, struct ( newAttrs, widgetAttributes, widgetCollectionAttributes))
95+ WidgetBuilder< 'msg, 'marker>( x.Key, struct ( newAttrs, widgetAttributes, widgetCollectionAttributes, environmentAttributes ))
8196
8297 [<EditorBrowsable( EditorBrowsableState.Never) >]
8398 member x.AddWidget ( attr : WidgetAttribute ) =
84- let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes ) =
99+ let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes , environmentAttributes ) =
85100 x.Attributes
86101
87102 let attribs = widgetAttributes
@@ -95,11 +110,11 @@ type WidgetBuilder<'msg, 'marker when 'msg: equality> =
95110 attribs2[ attribs.Length] <- attr
96111 attribs2
97112
98- WidgetBuilder< 'msg, 'marker>( x.Key, struct ( scalarAttributes, ValueSome res, widgetCollectionAttributes))
113+ WidgetBuilder< 'msg, 'marker>( x.Key, struct ( scalarAttributes, ValueSome res, widgetCollectionAttributes, environmentAttributes ))
99114
100115 [<EditorBrowsable( EditorBrowsableState.Never) >]
101116 member x.AddWidgetCollection ( attr : WidgetCollectionAttribute ) =
102- let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes ) =
117+ let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes , environmentAttributes ) =
103118 x.Attributes
104119
105120 let attribs = widgetCollectionAttributes
@@ -113,7 +128,32 @@ type WidgetBuilder<'msg, 'marker when 'msg: equality> =
113128 attribs2[ attribs.Length] <- attr
114129 attribs2
115130
116- WidgetBuilder< 'msg, 'marker>( x.Key, struct ( scalarAttributes, widgetAttributes, ValueSome res))
131+ WidgetBuilder< 'msg, 'marker>( x.Key, struct ( scalarAttributes, widgetAttributes, ValueSome res, environmentAttributes))
132+
133+ [<EditorBrowsable( EditorBrowsableState.Never) >]
134+ member inline x.AddEnvironment ( key : EnvironmentAttributeKey , value : obj ) =
135+ let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes , environmentAttributes ) =
136+ x.Attributes
137+
138+ let attr =
139+ { Key = key
140+ #if DEBUG
141+ DebugName = $" Environment.{key}"
142+ #endif
143+ Value = value }
144+
145+ let attribs = environmentAttributes
146+
147+ let res =
148+ match attribs with
149+ | ValueNone -> [| attr |]
150+ | ValueSome attribs ->
151+ let attribs2 = Array.zeroCreate( attribs.Length + 1 )
152+ Array.blit attribs 0 attribs2 0 attribs.Length
153+ attribs2[ attribs.Length] <- attr
154+ attribs2
155+
156+ WidgetBuilder< 'msg, 'marker>( x.Key, struct ( scalarAttributes, widgetAttributes, widgetCollectionAttributes, ValueSome res))
117157 end
118158
119159
@@ -130,12 +170,12 @@ type CollectionBuilder<'msg, 'marker, 'itemMarker when 'msg: equality> =
130170
131171 new ( widgetKey: WidgetKey, scalars: StackList< ScalarAttribute>, attr: WidgetCollectionAttributeDefinition) =
132172 { WidgetKey = widgetKey
133- Attributes = AttributesBundle( scalars, ValueNone, ValueNone)
173+ Attributes = AttributesBundle( scalars, ValueNone, ValueNone, ValueNone )
134174 Attr = attr }
135175
136176 new ( widgetKey: WidgetKey, attr: WidgetCollectionAttributeDefinition) =
137177 { WidgetKey = widgetKey
138- Attributes = AttributesBundle( StackList.empty(), ValueNone, ValueNone)
178+ Attributes = AttributesBundle( StackList.empty(), ValueNone, ValueNone, ValueNone )
139179 Attr = attr }
140180
141181 new ( widgetKey: WidgetKey, attr: WidgetCollectionAttributeDefinition, attributes: AttributesBundle) =
@@ -145,16 +185,16 @@ type CollectionBuilder<'msg, 'marker, 'itemMarker when 'msg: equality> =
145185
146186 new ( widgetKey: WidgetKey, attr: WidgetCollectionAttributeDefinition, scalar: ScalarAttribute) =
147187 { WidgetKey = widgetKey
148- Attributes = AttributesBundle( StackList.one scalar, ValueNone, ValueNone)
188+ Attributes = AttributesBundle( StackList.one scalar, ValueNone, ValueNone, ValueNone )
149189 Attr = attr }
150190
151191 new ( widgetKey: WidgetKey, attr: WidgetCollectionAttributeDefinition, scalarA: ScalarAttribute, scalarB: ScalarAttribute) =
152192 { WidgetKey = widgetKey
153- Attributes = AttributesBundle( StackList.two( scalarA, scalarB), ValueNone, ValueNone)
193+ Attributes = AttributesBundle( StackList.two( scalarA, scalarB), ValueNone, ValueNone, ValueNone )
154194 Attr = attr }
155195
156196 member inline x.Run ( c : Content < 'msg >) =
157- let struct ( scalars , widgets , widgetCollections ) = x.Attributes
197+ let struct ( scalars , widgets , widgetCollections , environments ) = x.Attributes
158198
159199 let attrValue =
160200 match MutStackArray1.toArraySlice & c.Widgets with
@@ -168,7 +208,7 @@ type CollectionBuilder<'msg, 'marker, 'itemMarker when 'msg: equality> =
168208 | ValueNone -> ValueSome([| widgetCollAttr |])
169209 | ValueSome widgetCollectionAttributes -> ValueSome( Array.appendOne widgetCollAttr widgetCollectionAttributes)
170210
171- WidgetBuilder< 'msg, 'marker>( x.WidgetKey, AttributesBundle( scalars, widgets, widgetCollections))
211+ WidgetBuilder< 'msg, 'marker>( x.WidgetKey, AttributesBundle( scalars, widgets, widgetCollections, environments ))
172212
173213 member inline _.Combine ( a : Content < 'msg >, b : Content < 'msg >) : Content < 'msg > =
174214 let res = MutStackArray1.combineMut(& a.Widgets, b.Widgets)
@@ -191,13 +231,13 @@ type CollectionBuilder<'msg, 'marker, 'itemMarker when 'msg: equality> =
191231
192232 [<EditorBrowsable( EditorBrowsableState.Never) >]
193233 member inline x.AddScalar ( attr : ScalarAttribute ) =
194- let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes ) =
234+ let struct ( scalarAttributes , widgetAttributes , widgetCollectionAttributes , environmentAttributes ) =
195235 x.Attributes
196236
197237 CollectionBuilder< 'msg, 'marker, 'itemMarker>(
198238 x.WidgetKey,
199239 x.Attr,
200- struct ( StackList.add(& scalarAttributes, attr), widgetAttributes, widgetCollectionAttributes)
240+ struct ( StackList.add(& scalarAttributes, attr), widgetAttributes, widgetCollectionAttributes, environmentAttributes )
201241 )
202242
203243 end
@@ -251,7 +291,7 @@ type SingleChildBuilder<'msg, 'marker, 'childMarker when 'msg: equality> =
251291 new ( widgetKey: WidgetKey, attr: WidgetAttributeDefinition) =
252292 { WidgetKey = widgetKey
253293 Attr = attr
254- AttributesBundle = AttributesBundle( StackList.empty(), ValueNone, ValueNone) }
294+ AttributesBundle = AttributesBundle( StackList.empty(), ValueNone, ValueNone, ValueNone ) }
255295
256296 new ( widgetKey: WidgetKey, attr: WidgetAttributeDefinition, attributesBundle: AttributesBundle) =
257297 { WidgetKey = widgetKey
@@ -273,7 +313,9 @@ type SingleChildBuilder<'msg, 'marker, 'childMarker when 'msg: equality> =
273313
274314 member inline this.Run ( [<InlineIfLambda>] result : SingleChildBuilderStep < 'msg , 'childMarker >) =
275315 let childAttr = this.Attr.WithValue( result.Invoke() .Compile())
276- let struct ( scalars , widgets , widgetCollections ) = this.AttributesBundle
316+
317+ let struct ( scalars , widgets , widgetCollections , environments ) =
318+ this.AttributesBundle
277319
278320 WidgetBuilder< 'msg, 'marker>(
279321 this.WidgetKey,
@@ -282,6 +324,7 @@ type SingleChildBuilder<'msg, 'marker, 'childMarker when 'msg: equality> =
282324 ( match widgets with
283325 | ValueNone -> ValueSome [| childAttr |]
284326 | ValueSome widgets -> ValueSome( Array.appendOne childAttr widgets)),
285- widgetCollections
327+ widgetCollections,
328+ environments
286329 )
287330 )
0 commit comments