ReactivePanelScope.cs
#if SANDBOX
using Sandbox.Reactivity.Internals;
#if JETBRAINS_ANNOTATIONS
#endif
// we can't wrap the BuildRenderTree method for razor components, so we need something that can set up the proper
// scope inside the markup itself
namespace Sandbox.Reactivity;
/// <summary>
/// A disposable that's used to enable reactivity for a <see cref="ReactivePanelComponent" /> or
/// <see cref="ReactivePanel" /> during rendering.
/// </summary>
#if JETBRAINS_ANNOTATIONS
#endif
public readonly ref struct ReactivePanelScope : IDisposable
{
private readonly Effect.ExecutionScope _executionScope;
internal ReactivePanelScope(IReactivePanel panel)
{
if (panel.RenderEffectRoot is { } previousRoot)
{
// don't teardown previous root since we're already building the render tree by this point
previousRoot.Dispose(false);
}
// nested panels don't render immediately when a containing panel's tree is rendering, so the parent is
// always null anyway
var effectRoot = new Effect(null, null, true, () => panel.Version++);
effectRoot.SetDebugInfo(panel.GetType().ToSimpleString(false) + " (Render)",
panel is ReactivePanel ? "view_quilt" : "monitor",
new CallLocation(2),
panel is ReactivePanel reactive ? reactive.GameObject?.GetComponent<IReactivePanel>() : panel);
panel.RenderEffectRoot = effectRoot;
_executionScope = new Effect.ExecutionScope(effectRoot);
}
public void Dispose()
{
_executionScope.Dispose();
}
}
#endif