/// <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);
        }
Exemple #3
0
 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);
        }