public static void BindAttributes(ofElement element) { if (element == null) { return; } var type = element.GetType(); if (_binder.TryGetValue(type, out var binder)) { binder(element); return; } var x = Expression.Parameter(typeof(ofElement)); var y = Expression.Variable(type, nameof(element)); binder = Expression.Lambda <Action <ofElement> >( Expression.Block(new[] { y }, Expression.Assign(y, Expression.Convert(x, type)), BuildBinder(type, y)), x) .CompileSafe(); (_binder[type] = binder)(element); }
bool CanRender(ofElement element) { if (element == null) { return(false); } if (Element == null || ReferenceEquals(element, Element)) { return(true); } return(element.GetType() == Element.GetType() && KeysEqual(element, Element)); }
internal bool Set(ofNode node, EffectDelegate effect, object[] dependencies) { var pending = _node == null || dependencies?.Length == 0 || !Utils.ObjectsEqual(_dependencies, dependencies); _node = node; _element = node.Element; _dependencies = dependencies; _effect = effect; node.LocalEffects.Add(this); if (pending) { node.Root.PendingEffects.Enqueue(this); } return(pending); }
static bool KeysEqual(ofElement a, ofElement b) => a.Key == b.Key || a.Key != null && a.Key.Equals(b.Key);
/// <summary> /// Renders the given element. /// </summary> public virtual RenderResult RenderElement(ofElement element) { bool shouldRender; // remove first to avoid infinite rerender loop lock (Root.RerenderNodes) shouldRender = Root.RerenderNodes.Remove(this); if (_disposed) { return(RenderResult.Mismatch); } if (!CanRender(element)) { return(RenderResult.Mismatch); } shouldRender = shouldRender || AlwaysInvalid || Element == null || Element.ShouldComponentUpdate(element); if (!shouldRender) { Root.Diagnostics?.OnNodeRenderSkipped(this); return(RenderResult.Skipped); } // enable hooks _hooks = 0; try { using (element.Bind(this)) { Root.Diagnostics?.OnNodeRendering(this); var result = element.RenderSubtree(); if (result && ofElement.IsHookValidated) { if (_lastHook == null) { _lastHook = _hooks; } else if (_lastHook != _hooks) { throw new InvalidOperationException($"The number of hooks ({_hooks}) does not match with the previous render ({_lastHook}). " + "See https://reactjs.org/docs/hooks-rules.html for rules about hooks."); } } return(result ? RenderResult.Rendered : RenderResult.Skipped); } } catch (Exception e) { Root.Diagnostics?.OnException(e); throw; } finally { _hooks = null; } }