@@ -5,24 +5,15 @@ namespace Bunit.Rendering;
55/// </summary>
66public sealed class RenderEvent
77{
8- private readonly RenderBatch renderBatch ;
8+ private readonly Dictionary < int , Status > statuses = new ( ) ;
9+
10+ internal IReadOnlyDictionary < int , Status > Statuses => statuses ;
911
1012 /// <summary>
1113 /// Gets a collection of <see cref="ArrayRange{RenderTreeFrame}"/>, accessible via the ID
1214 /// of the component they are created by.
1315 /// </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 ( ) ;
2617
2718 /// <summary>
2819 /// Gets the render status for a <paramref name="renderedComponent"/>.
@@ -34,86 +25,57 @@ internal RenderEvent(RenderBatch renderBatch, RenderTreeFrameDictionary frames)
3425 if ( renderedComponent is null )
3526 throw new ArgumentNullException ( nameof ( renderedComponent ) ) ;
3627
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+ }
3832
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 ) )
4436 {
45- ( result . Rendered , result . Changed ) = GetRenderAndChangeStatus ( renderedComponent ) ;
37+ status = new ( ) ;
38+ statuses [ componentId ] = status ;
4639 }
40+ return status ;
41+ }
4742
48- return result ;
43+ internal void SetDisposed ( int componentId )
44+ {
45+ GetOrCreateStatus ( componentId ) . Disposed = true ;
4946 }
5047
51- private bool DidComponentDispose ( IRenderedFragmentBase renderedComponent )
48+ internal void SetUpdated ( int componentId , bool hasChanges )
5249 {
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+ }
6054
61- return false ;
55+ internal void SetUpdatedApplied ( int componentId )
56+ {
57+ GetOrCreateStatus ( componentId ) . UpdatesApplied = true ;
6258 }
6359
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 )
7561 {
76- var result = ( Rendered : false , HasChanges : false ) ;
62+ Frames . Add ( componentId , frames ) ;
63+ GetOrCreateStatus ( componentId ) . FramesLoaded = true ;
64+ }
7765
78- GetStatus ( renderedComponent . ComponentId ) ;
66+ internal record class Status
67+ {
68+ public bool Rendered { get ; set ; }
7969
80- return result ;
70+ public bool Changed { get ; set ; }
8171
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 ; }
10073
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 ;
11879 }
11980}
81+
0 commit comments