@@ -5,24 +5,15 @@ namespace Bunit.Rendering;
5
5
/// </summary>
6
6
public sealed class RenderEvent
7
7
{
8
- private readonly RenderBatch renderBatch ;
8
+ private readonly Dictionary < int , Status > statuses = new ( ) ;
9
+
10
+ internal IReadOnlyDictionary < int , Status > Statuses => statuses ;
9
11
10
12
/// <summary>
11
13
/// Gets a collection of <see cref="ArrayRange{RenderTreeFrame}"/>, accessible via the ID
12
14
/// of the component they are created by.
13
15
/// </summary>
14
- public RenderTreeFrameDictionary Frames { get ; }
15
-
16
- /// <summary>
17
- /// Initializes a new instance of the <see cref="RenderEvent"/> class.
18
- /// </summary>
19
- /// <param name="renderBatch">The <see cref="RenderBatch"/> update from the render event.</param>
20
- /// <param name="frames">The <see cref="RenderTreeFrameDictionary"/> from the current render.</param>
21
- internal RenderEvent ( RenderBatch renderBatch , RenderTreeFrameDictionary frames )
22
- {
23
- this . renderBatch = renderBatch ;
24
- Frames = frames ;
25
- }
16
+ public RenderTreeFrameDictionary Frames { get ; } = new ( ) ;
26
17
27
18
/// <summary>
28
19
/// Gets the render status for a <paramref name="renderedComponent"/>.
@@ -34,86 +25,57 @@ internal RenderEvent(RenderBatch renderBatch, RenderTreeFrameDictionary frames)
34
25
if ( renderedComponent is null )
35
26
throw new ArgumentNullException ( nameof ( renderedComponent ) ) ;
36
27
37
- var result = ( Rendered : false , Changed : false , Disposed : false ) ;
28
+ return statuses . TryGetValue ( renderedComponent . ComponentId , out var status )
29
+ ? ( status . Rendered , status . Changed , status . Disposed )
30
+ : ( Rendered : false , Changed : false , Disposed : false ) ;
31
+ }
38
32
39
- if ( DidComponentDispose ( renderedComponent ) )
40
- {
41
- result . Disposed = true ;
42
- }
43
- else
33
+ internal Status GetOrCreateStatus ( int componentId )
34
+ {
35
+ if ( ! statuses . TryGetValue ( componentId , out var status ) )
44
36
{
45
- ( result . Rendered , result . Changed ) = GetRenderAndChangeStatus ( renderedComponent ) ;
37
+ status = new ( ) ;
38
+ statuses [ componentId ] = status ;
46
39
}
40
+ return status ;
41
+ }
47
42
48
- return result ;
43
+ internal void SetDisposed ( int componentId )
44
+ {
45
+ GetOrCreateStatus ( componentId ) . Disposed = true ;
49
46
}
50
47
51
- private bool DidComponentDispose ( IRenderedFragmentBase renderedComponent )
48
+ internal void SetUpdated ( int componentId , bool hasChanges )
52
49
{
53
- for ( var i = 0 ; i < renderBatch . DisposedComponentIDs . Count ; i ++ )
54
- {
55
- if ( renderBatch . DisposedComponentIDs . Array [ i ] . Equals ( renderedComponent . ComponentId ) )
56
- {
57
- return true ;
58
- }
59
- }
50
+ var status = GetOrCreateStatus ( componentId ) ;
51
+ status . Rendered = true ;
52
+ status . Changed = status . Changed || hasChanges ;
53
+ }
60
54
61
- return false ;
55
+ internal void SetUpdatedApplied ( int componentId )
56
+ {
57
+ GetOrCreateStatus ( componentId ) . UpdatesApplied = true ;
62
58
}
63
59
64
- /// <summary>
65
- /// This method determines if the <paramref name="renderedComponent"/> or any of the
66
- /// components underneath it in the render tree rendered and whether they they changed
67
- /// their render tree during render.
68
- ///
69
- /// It does this by getting the status from the <paramref name="renderedComponent"/>,
70
- /// then from all its children, using a recursive pattern, where the internal methods
71
- /// GetStatus and GetStatusFromChildren call each other until there are no more children,
72
- /// or both a render and a change is found.
73
- /// </summary>
74
- private ( bool Rendered , bool HasChanges ) GetRenderAndChangeStatus ( IRenderedFragmentBase renderedComponent )
60
+ internal void AddFrames ( int componentId , ArrayRange < RenderTreeFrame > frames )
75
61
{
76
- var result = ( Rendered : false , HasChanges : false ) ;
62
+ Frames . Add ( componentId , frames ) ;
63
+ GetOrCreateStatus ( componentId ) . FramesLoaded = true ;
64
+ }
77
65
78
- GetStatus ( renderedComponent . ComponentId ) ;
66
+ internal record class Status
67
+ {
68
+ public bool Rendered { get ; set ; }
79
69
80
- return result ;
70
+ public bool Changed { get ; set ; }
81
71
82
- void GetStatus ( int componentId )
83
- {
84
- for ( var i = 0 ; i < renderBatch . UpdatedComponents . Count ; i ++ )
85
- {
86
- ref var update = ref renderBatch . UpdatedComponents . Array [ i ] ;
87
- if ( update . ComponentId == componentId )
88
- {
89
- result . Rendered = true ;
90
- result . HasChanges = update . Edits . Count > 0 ;
91
- break ;
92
- }
93
- }
94
-
95
- if ( ! result . HasChanges )
96
- {
97
- GetStatusFromChildren ( componentId ) ;
98
- }
99
- }
72
+ public bool Disposed { get ; set ; }
100
73
101
- void GetStatusFromChildren ( int componentId )
102
- {
103
- var frames = Frames [ componentId ] ;
104
- for ( var i = 0 ; i < frames . Count ; i ++ )
105
- {
106
- ref var frame = ref frames . Array [ i ] ;
107
- if ( frame . FrameType == RenderTreeFrameType . Component )
108
- {
109
- GetStatus ( frame . ComponentId ) ;
110
-
111
- if ( result . HasChanges )
112
- {
113
- break ;
114
- }
115
- }
116
- }
117
- }
74
+ public bool UpdatesApplied { get ; set ; }
75
+
76
+ public bool FramesLoaded { get ; set ; }
77
+
78
+ public bool UpdateNeeded => Rendered || Changed ;
118
79
}
119
80
}
81
+
0 commit comments