/// <summary>
        /// Wrapper for the concrete modifier action, used for error handling and preconditions checking.
        /// </summary>
        /// <param name="concreteBehavior"> External method to execute </param>
        /// <param name="policy"> The update policy to employ </param>
        /// <param name="preconditions"> Predicates to check before executing the action </param>
        protected void ApplyModifier(Action concreteBehavior, IRenderingPolicy policy, params Func<bool>[] preconditions)
        {
            try
            {
                if (HasLessThanTwoLayers()) return;
                if (BreaksPreconditions(preconditions)) return;

                concreteBehavior();

                HandlerGraphics.UpdateFrame(HandlerLayers.WorkspaceLayers, policy);
            }
            catch (Exception ex)
            {
                Logger.Warn(ex.ToString());
            }
        }
 public void RefreshFrame(IRenderingPolicy renderPolicy)
 {
     formGraphics.DrawImageUnscaledAndClipped(frame, renderPolicy.DirtyRegion);
 }
        public void UpdateFrame(SortedContainer<Layer> objectCollection,
                                IRenderingPolicy renderPolicy)
        {
            // Clip the invalidated region to the size of the frame
            renderPolicy.ClipToFrame(frame.Size);

            // Refreh the invalidated frame/region
            profiler.ProfileClearFrame(() =>
            {
                Color clearColor = Color.FromArgb(255, surfaceInfo.GraphicsBackground);
                using (SolidBrush clearBrush = new SolidBrush(clearColor))
                {
                    /*var localPolicy = renderPolicy as MinimalUpdate;
                    if (localPolicy != null && localPolicy.OldRegion != default(Rectangle))
                    {
                        _frameGraphics.FillRectangle(clearBrush, localPolicy.OldRegion);
                    }*/
                    frameGraphics.FillRectangle(clearBrush, renderPolicy.DirtyRegion);
                }
            });

            profiler.ProfileRasterizeObjects(() =>
            {
                using (var frameInfo = new BitmapHelper(frame)) // lock framebuffer data
                using (var rasterizer = new RasterizerStage(objectCollection, surfaceInfo)) // rasterize all scene objects
                using (var compositor = new CompositionStage(objectCollection, rasterizer))
                {
                    // perform scene composition on needed regions
                    compositor.Composite(renderPolicy, frameInfo);
                }
            });

            // Draw the new completed frame/region on the visible area
            profiler.ProfileDrawFrame(() =>
            {
                RefreshFrame(renderPolicy);
            });

            // Notify interested clients with statistics after frame update
            if (graphicsUpdateCallback != null) graphicsUpdateCallback.BeginInvoke(profiler, null, null);
        }