public bool CaptureInstrumentStateSnapshotAndCheckIfStale(IInstrumentRenderer renderer, InstrumentForm instrumentForm) { if (renderer == null) { return(false); } var storedState = _instrumentStates.ContainsKey(renderer) ? _instrumentStates[renderer] : InstrumentStateSnapshot.Default; var latestState = CaptureStateSnapshot(renderer); var newStateIsDifferent = (storedState.HashCode != latestState.HashCode); if (newStateIsDifferent) { _instrumentStates.AddOrUpdate(renderer, latestState, (x, y) => latestState); } else { latestState = storedState; } var timeSinceLastRendered = instrumentForm != null? DateTime.UtcNow.Subtract(instrumentForm.LastRenderedOn).TotalMilliseconds : 0; var isStale = instrumentForm != null && (newStateIsDifferent || instrumentForm.LastRenderedOn <latestState.DateTime || timeSinceLastRendered> StaleDataTimeoutMilliseconds); return(isStale); }
private static InstrumentStateSnapshot CaptureStateSnapshot(IInstrumentRenderer renderer) { var newState = renderer.GetState(); return(new InstrumentStateSnapshot { HashCode = newState?.GetHashCode() ?? 0, DateTime = DateTime.UtcNow }); }
public InstrumentForm Create ( InstrumentType instrumentType, IInstrumentRenderer renderer, Image initialImage = null ) { var currentSettings = _instrumentFormSettingsReader.Read(instrumentType.ToString()); if (!currentSettings.Enabled) { return(null); } Point location; Size size; var screen = Util.FindScreen(currentSettings.OutputDisplay); var instrumentForm = new InstrumentForm { Text = instrumentType.ToString(), ShowInTaskbar = false, ShowIcon = false, Settings = currentSettings }; if (currentSettings.StretchToFit) { location = new Point(0, 0); size = screen.Bounds.Size; instrumentForm.StretchToFill = true; } else { location = new Point(currentSettings.ULX, currentSettings.ULY); size = new Size(currentSettings.LRX - currentSettings.ULX, currentSettings.LRY - currentSettings.ULY); instrumentForm.StretchToFill = false; } instrumentForm.AlwaysOnTop = currentSettings.AlwaysOnTop; instrumentForm.Monochrome = currentSettings.Monochrome; instrumentForm.Rotation = currentSettings.RotateFlipType; instrumentForm.WindowState = FormWindowState.Normal; Util.OpenFormOnSpecificMonitor(instrumentForm, screen, location, size, true, true); instrumentForm.DataChanged += new InstrumentFormDataChangedHandler(instrumentType, instrumentForm).HandleDataChangedEvent; if (initialImage == null) { return(instrumentForm); } using (var graphics = (Graphics)instrumentForm.CreateGraphics()) { graphics.DrawImageFast(initialImage, instrumentForm.ClientRectangle); } return(instrumentForm); }
private void Dispose(bool disposing) { if (!_disposed && disposing) { Hide(); Common.Util.DisposeObject(OutputForm); Common.Util.DisposeObject(Renderer); Renderer = null; Common.Util.DisposeObject(_renderedFramesCounter); Common.Util.DisposeObject(_skippedFramesCounter); Common.Util.DisposeObject(_totalFramesCounter); } _disposed = true; }
internal Instrument( InstrumentType instrumentType, IInstrumentRenderer renderer, IInstrumentStateSnapshotCache instrumentStateSnapshotCache = null, IPerformanceCounterInstanceFactory performanceCounterInstanceFactory = null, IInstrumentRenderHelper instrumentRenderHelper = null, IInstrumentFormFactory instrumentFormFactory = null ) { Type = instrumentType; Renderer = renderer; _instrumentStateSnapshotCache = instrumentStateSnapshotCache ?? new InstrumentStateSnapshotCache(); _instrumentRenderHelper = instrumentRenderHelper ?? new InstrumentRenderHelper(); _instrumentFormFactory = instrumentFormFactory ?? new InstrumentFormFactory(); var performanceCounterInstanceFactory1 = performanceCounterInstanceFactory ?? new PerformanceCounterInstanceInstanceFactory(); _renderedFramesCounter = performanceCounterInstanceFactory1.CreatePerformanceCounterInstance(Application.ProductName, $"Rendered Frames per second - {instrumentType}"); _skippedFramesCounter = performanceCounterInstanceFactory1.CreatePerformanceCounterInstance(Application.ProductName, $"Skipped Frames per second - {instrumentType}"); _totalFramesCounter = performanceCounterInstanceFactory1.CreatePerformanceCounterInstance(Application.ProductName, $"Total Frames per second - {instrumentType}"); }
public void Render( IInstrumentRenderer renderer, InstrumentForm targetForm, RotateFlipType rotation, bool monochrome, bool highlightBorder, bool nightVisionMode) { try { if (!targetForm.Visible || targetForm.IsDisposed) { return; } var renderSurface = ObtainRenderSurface(targetForm); using (var destinationGraphics = Graphics.FromImage(renderSurface)) { try { renderer.Render(destinationGraphics, new Rectangle(0, 0, renderSurface.Width, renderSurface.Height)); targetForm.LastRenderedOn = DateTime.UtcNow; if (highlightBorder) { HighlightBorder(destinationGraphics, renderSurface); } } catch (ThreadAbortException) { } catch (ThreadInterruptedException) { } catch (Exception ex) { var rendererName = renderer != null?renderer.GetType().FullName : "unknown"; _log.Error($"An error occurred while rendering {rendererName}", ex); } } if (rotation != RotateFlipType.RotateNoneFlipNone) { renderSurface.RotateFlip(rotation); } using (var graphics = targetForm.CreateGraphics()) { if (nightVisionMode) { RenderWithNightVisionEffect(targetForm, graphics, renderSurface); } else if (monochrome) { RenderWithMonochromeEffect(targetForm, graphics, renderSurface); } else { RenderWithStandardEffect(graphics, renderSurface); } } } catch (ExternalException) { //GDI+ error message we don't care about } catch (ObjectDisposedException) { //GDI+ error message thrown on operations on disposed images -- can happen when one thread disposes while shutting-down thread tries to render } catch (ArgumentException) { //GDI+ error message we don't care about } catch (OutOfMemoryException) { //bullshit OOM messages from GDI+ } catch (InvalidOperationException) { //GDI+ error message we don't care about } }