/// <summary> /// Update visual object; /// </summary> /// <param name="visual">the visual need to update</param> public void Update(PresentationVisual visual, bool isSingle = false) { if (visual == null) { return; } Monitor.Enter(_loopLock); EnterRender(); if (isSingle) { if (visual.Mode == Mode.Normal) { _ClearVisual(visual); _UpdateSync(visual); } } else { var visuals = _visuals.Where(other => other.Mode == Mode.Normal && other.IsIntersectWith(visual)); foreach (var _visual in visuals) { _ClearVisual(_visual, _visual != visual); } foreach (var _visual in visuals) { _UpdateSync(_visual); } } ExitRender(); Monitor.Exit(_loopLock); }
/// <summary> /// If param "isUpdate" is false, You must call <see cref="UpdateAll"/> or <see cref="Update(PresentationVisual)"/> after calling this method, /// Make sure the panel is updated! /// </summary> /// <param name="visual">The visual to remove</param> /// <param name="isUpdate">Whether to refresh the panel immediately</param> public void RemoveVisual(PresentationVisual visual, bool isUpdate = true) { Monitor.Enter(_loopLock); if (_visuals.Contains(visual)) { visual.Panel = null; // It has been updated before deletion, so the count is reduced by one here. if (_isUpdatingAll && visual.Mode == Mode.Normal) { _cnt--; } else { visual.Mode = Mode.Normal; } _Remove(visual); if (isUpdate) { Monitor.Exit(_loopLock); ClearVisual(visual); Monitor.Enter(_loopLock); } } Monitor.Exit(_loopLock); }
public static bool IsIntersectWith(this PresentationVisual self, PresentationVisual other) { if (self == other) { return(true); } foreach (var primitive1 in self.Context.Primitives) { if (!self.Panel.Bounds.IsIntersectWith(primitive1.Property.Bounds)) { return(false); } foreach (var primitive2 in other.Context.Primitives) { if (!self.Panel.Bounds.IsIntersectWith(primitive2.Property.Bounds)) { return(false); } if (primitive1.IsIntersect(primitive2)) { return(true); } } } return(false); }
private void _Remove(PresentationVisual visual) { while (Interlocked.Exchange(ref _flagSync, 1) == 1) { Thread.Sleep(1); } _visuals.Remove(visual); Interlocked.Exchange(ref _flagSync, 0); }
internal void _UpdateSync(PresentationVisual visual) { visual.Update(); foreach (var primitive in visual.Context.Primitives) { if (!_bounds.IsIntersectWith(primitive)) { continue; } var bounds = GeometryHelper.RestrictBounds(_bounds, primitive.Property.Bounds); _DrawPrimitive(primitive, bounds); _UpdateBounds(bounds); } }
internal void _ClearVisual(PresentationVisual visual, bool optimizate = false) { foreach (var primitive in visual.Context.Primitives) { if (!_bounds.IsIntersectWith(primitive)) { continue; } var canFilled = primitive is ICanFilledPrimitive; if (optimizate && (primitive.Property.Pen.Color == null || primitive.Property.Pen.Color[3] == byte.MaxValue) && (!canFilled || (primitive as ICanFilledPrimitive).FillColor == null || (primitive as ICanFilledPrimitive).FillColor[3] == byte.MaxValue)) { continue; } var bounds = GeometryHelper.RestrictBounds(_bounds, primitive.Property.Bounds); _DrawPrimitive(primitive, bounds, true); _UpdateBounds(bounds); } }
/// <summary> /// If param "isUpdate" is false, You must call <see cref="UpdateAll"/> or <see cref="Update(PresentationVisual)"/> after calling this method, /// Make sure the panel is updated! /// </summary> /// <param name="visual">The visual to add</param> /// <param name="isUpdate">Whether to refresh the panel immediately</param> public void AddVisual(PresentationVisual visual, bool isUpdate = false) { Monitor.Enter(_loopLock); if (!_visuals.Contains(visual)) { visual.Panel = this; if (_isUpdatingAll) { _cnt++; } _Add(visual); if (isUpdate) { Monitor.Exit(_loopLock); Update(visual, true); Monitor.Enter(_loopLock); } } Monitor.Exit(_loopLock); }
internal void _UpdateAsync(PresentationVisual visual) { if (visual.Mode != Mode.WatingForUpdate) { return; } visual.Mode = Mode.Updating; visual.Update(); foreach (var primitive in visual.Context.Primitives) { if (_currentSource.IsCancellationRequested) { break; } if (!_bounds.IsIntersectWith(primitive)) { continue; } var bounds = GeometryHelper.RestrictBounds(_bounds, primitive.Property.Bounds); _DrawPrimitive(primitive, bounds); } visual.Mode = Mode.Completed; }
internal void ClearVisual(PresentationVisual visual) { if (visual == null) { return; } Monitor.Enter(_loopLock); EnterRender(); _ClearVisual(visual); var visuals = _visuals.Where(other => other.Mode == Mode.Normal && other != visual && other.IsIntersectWith(visual)); foreach (var _visual in visuals) { _ClearVisual(_visual, true); } foreach (var _visual in visuals) { _UpdateSync(_visual); } ExitRender(); Monitor.Exit(_loopLock); }