/GammaJul.LgLcd/LcdPage.cs
C# | 212 lines | 89 code | 37 blank | 86 comment | 13 complexity | 037e68c684c23e0b85c936c08b4ac3ee MD5 | raw file
Possible License(s): LGPL-2.1
1using System; 2 3namespace GammaJul.LgLcd { 4 5 /// <summary> 6 /// Base class for every device page. 7 /// </summary> 8 public abstract class LcdPage : IDisposable { 9 10 11 #region Properties 12 13 private readonly LcdDevice _device; 14 private int _desiredFramerate; 15 private bool _invalidated; 16 17 /// <summary> 18 /// Gets the device where this page will be shown. 19 /// </summary> 20 public LcdDevice Device { 21 get { return _device; } 22 } 23 24 /// <summary> 25 /// Gets the last time this page was updated, relative to the device's creation time. 26 /// </summary> 27 internal TimeSpan LastFrameUpdate { get; set; } 28 29 /// <summary> 30 /// Gets or sets the priority of this page when drawing. 31 /// The default value is <see cref="LcdPriority.Normal"/>. 32 /// </summary> 33 public LcdPriority Priority { get; set; } 34 35 /// <summary> 36 /// Gets or sets the mode (synchronous or asynchronous) used to update this page. 37 /// The default value is <see cref="LcdUpdateMode.Async"/>. 38 /// </summary> 39 public LcdUpdateMode UpdateMode { get; set; } 40 41 /// <summary> 42 /// Gets or sets the desired frame rate, in frame per seconds, for this page. 43 /// The default value is 30. 44 /// </summary> 45 public int DesiredFramerate { 46 get { return _desiredFramerate; } 47 set { 48 if (value < 1 || value > 60) 49 throw new ArgumentOutOfRangeException("value", "DesiredFrameRate must be between 1 and 60"); 50 _desiredFramerate = value; 51 } 52 } 53 54 #endregion 55 56 57 #region Events 58 59 /// <summary> 60 /// Occurs when the page starts updating its content. 61 /// </summary> 62 public event EventHandler<UpdateEventArgs> Updating; 63 64 /// <summary> 65 /// Occurs when the page has updated its content. 66 /// </summary> 67 public event EventHandler<UpdateEventArgs> Updated; 68 69 /// <summary> 70 /// Occurs when the page starts drawing its content. 71 /// </summary> 72 public event EventHandler Drawing; 73 74 /// <summary> 75 /// Occurs when the page has drawn its content, but the pixels have not yet been send to the device. 76 /// This is your last chance to do some kind of post-processing on the pixels. 77 /// </summary> 78 public event EventHandler<DrawnEventArgs> Drawn; 79 80 /// <summary> 81 /// Raises the <see cref="Updating"/> event. 82 /// </summary> 83 /// <param name="e">Update parameters.</param> 84 protected virtual void OnUpdating(UpdateEventArgs e) { 85 EventHandler<UpdateEventArgs> handler = Updating; 86 if (handler != null) 87 handler(this, e); 88 } 89 90 /// <summary> 91 /// Raises the <see cref="Updated"/> event. 92 /// </summary> 93 /// <param name="e">Update parameters.</param> 94 protected virtual void OnUpdated(UpdateEventArgs e) { 95 EventHandler<UpdateEventArgs> handler = Updated; 96 if (handler != null) 97 handler(this, e); 98 } 99 100 /// <summary> 101 /// Raises the <see cref="Drawing"/> event. 102 /// </summary> 103 protected virtual void OnDrawing() { 104 EventHandler handler = Drawing; 105 if (handler != null) 106 handler(this, EventArgs.Empty); 107 } 108 109 /// <summary> 110 /// Raises the <see cref="Drawn"/> event. 111 /// </summary> 112 protected virtual void OnDrawn(byte[] pixels) { 113 EventHandler<DrawnEventArgs> handler = Drawn; 114 if (handler != null) 115 handler(this, new DrawnEventArgs(pixels)); 116 } 117 118 #endregion 119 120 121 /// <summary> 122 /// Sets this page as <see cref="Device"/>'s <see cref="LcdDevice.CurrentPage"/>. 123 /// </summary> 124 public void SetAsCurrentDevicePage() { 125 _device.CurrentPage = this; 126 } 127 128 /// <summary> 129 /// Call this method to force an update and draw cycle even if the page has not changed. 130 /// </summary> 131 public void Invalidate() { 132 _invalidated = true; 133 } 134 135 /// <summary> 136 /// Updates the page content. 137 /// </summary> 138 /// <param name="elapsedTotalTime">Time elapsed since the device creation.</param> 139 /// <param name="elapsedTimeSinceLastFrame">Time elapsed since last frame update.</param> 140 /// <returns><c>true</c> if the update has done something and a redraw is required.</returns> 141 internal bool Update(TimeSpan elapsedTotalTime, TimeSpan elapsedTimeSinceLastFrame) { 142 UpdateEventArgs updateEventArgs = new UpdateEventArgs(elapsedTotalTime, elapsedTimeSinceLastFrame); 143 OnUpdating(updateEventArgs); 144 bool redrawNeeded = UpdateCore(elapsedTotalTime, elapsedTimeSinceLastFrame) || _invalidated; 145 OnUpdated(updateEventArgs); 146 _invalidated = false; 147 return redrawNeeded; 148 } 149 150 /// <summary> 151 /// Derived classes override this method in order to update the page content. 152 /// </summary> 153 /// <param name="elapsedTotalTime">Time elapsed since the device creation.</param> 154 /// <param name="elapsedTimeSinceLastFrame">Time elapsed since last frame update.</param> 155 /// <returns><c>true</c> if the update has done something and a redraw is required.</returns> 156 protected abstract bool UpdateCore(TimeSpan elapsedTotalTime, TimeSpan elapsedTimeSinceLastFrame); 157 158 /// <summary> 159 /// Draws the page content. 160 /// </summary> 161 /// <returns>A pixel array conforming to <see cref="Device"/>'s <see cref="LcdDevice.DeviceType"/>.</returns> 162 internal byte[] Draw() { 163 OnDrawing(); 164 byte[] pixels = DrawCore(); 165 OnDrawn(pixels); 166 return pixels; 167 } 168 169 /// <summary> 170 /// Derived classes override this method in order to draw the page content visually. 171 /// </summary> 172 /// <returns>Implementors must return a pixel array conforming to 173 /// <see cref="Device"/>'s <see cref="LcdDevice.DeviceType"/>.</returns> 174 protected abstract byte[] DrawCore(); 175 176 177 #region IDisposable 178 179 /// <summary> 180 /// Releases the resources associated with this <see cref="LcdPage"/>. 181 /// </summary> 182 public void Dispose() { 183 Dispose(true); 184 GC.SuppressFinalize(this); 185 } 186 187 /// <summary> 188 /// Releases the resources associated with this <see cref="LcdPage"/>. 189 /// </summary> 190 /// <param name="disposing">Whether to also release managed resources along with unmanaged ones.</param> 191 protected virtual void Dispose(bool disposing) { 192 } 193 194 #endregion 195 196 197 /// <summary> 198 /// Creates a new <see cref="LcdPage"/> on the given device. 199 /// </summary> 200 /// <param name="device">Device where this page will be shown.</param> 201 protected LcdPage(LcdDevice device) { 202 if (device == null) 203 throw new ArgumentNullException("device"); 204 _device = device; 205 DesiredFramerate = 30; 206 LastFrameUpdate = TimeSpan.Zero; 207 Priority = LcdPriority.Normal; 208 UpdateMode = LcdUpdateMode.Async; 209 } 210 } 211 212}