33open System
44open System.Threading
55
6+ #nowarn " 7331"
7+
68[<AutoOpen>]
79module internal LockingExtensions =
810 type IAdaptiveObject with
@@ -29,6 +31,50 @@ exception LevelChangedException of
2931 /// The new level for the top-level object.
3032 newLevel : int
3133
34+ /// internal type used for properly handling of decorator objects (as introduced in AVal.mapNonAdaptive)
35+ /// Note that it should never be necessary to use this in user-code.
36+ [<CompilerMessage( " internal" , 7331 ) >]
37+ type internal DecoratedObject private ( real : IAdaptiveObject , decorator : IAdaptiveObject ) =
38+ let mutable weak : WeakReference < IAdaptiveObject > = null
39+
40+ interface IAdaptiveObject with
41+ member x.Tag
42+ with get() = null
43+ and set _ = ()
44+
45+ member x.IsConstant = false
46+ member x.Weak =
47+ // Note that we accept the race conditon here since locking the object
48+ // would potentially cause deadlocks and the worst case is, that we
49+ // create two different WeakReferences for the same object
50+ let w = weak
51+ if isNull w then
52+ let w = WeakReference<_>( x :> IAdaptiveObject)
53+ weak <- w
54+ w
55+ else
56+ w
57+ member x.Outputs = Unchecked.defaultof<_>
58+ member x.Mark () = false
59+ member x.AllInputsProcessed ( _ ) = ()
60+ member x.InputChanged ( _ , _ ) = ()
61+
62+ member x.OutOfDate
63+ with get() = false
64+ and set o = ()
65+
66+ member x.Level
67+ with get() = real.Level
68+ and set l = real.Level <- l
69+
70+ member x.Real = real
71+ member x.Decorator = decorator
72+
73+ static member Create ( real : IAdaptiveObject , decorator : IAdaptiveObject ) =
74+ match real with
75+ | :? DecoratedObject as r -> r
76+ | _ -> DecoratedObject( real, decorator)
77+
3278
3379/// Holds a set of adaptive objects which have been changed and shall
3480/// therefore be marked as outOfDate. Committing the transaction propagates
@@ -180,8 +226,13 @@ type Transaction() =
180226 for i in 0 .. outputCount - 1 do
181227 let o = outputs.[ i]
182228 outputs.[ i] <- Unchecked.defaultof<_>
183- o.InputChanged( x, e)
184- x.Enqueue o
229+ match o with
230+ | :? DecoratedObject as o ->
231+ o.Real.InputChanged( x, o.Decorator)
232+ x.Enqueue o.Real
233+ | _ ->
234+ o.InputChanged( x, e)
235+ x.Enqueue o
185236
186237 current <- Unchecked.defaultof<_>
187238
0 commit comments