// sets the raw data for the given control, invokes on main thread public void UpdateImageControlContents(int index, PixelFormat pf, params float[][] buffers) { this.Invoke(new Action(() => { if (imageFlowPanel.Controls.Count > index) { ImageControl ic = imageFlowPanel.Controls[index] as ImageControl; ic.Format = pf; for (int k = 0; k < buffers.Length; k++) { ic.SetImage(k, buffers[k]); } ic.Invalidate(); } })); }
private void AsyncUpdate() { DateTime prev = DateTime.Now; double time_since_last_draw = 0; bool parent_previously_visible = false; bool drawn_atleast_once = false; while (true) { // update last time since last draw DateTime now = DateTime.Now; time_since_last_draw += now.Subtract(prev).TotalSeconds; prev = now; // get a command message if there is one Message m = _messages.Dequeue(); if (m != null) { switch (m.Type) { case "Start": switch (_current_state) { case State.Paused: _current_state = State.Running; break; case State.Running: break; case State.Stopped: // image controls need to be added and modified on the main thread, so do an Invoke this.Invoke(new Action(() => { int image_width = this.ImageControlWidth; int image_height = this.ImageControlHeight; PixelFormat pixel_format = this.ImageControlPixelFormat; for (int k = 0; k < this.ImageControlCount; k++) { ImageControl ic = new ImageControl(_count, image_width, image_height, _scale, pixel_format); imageFlowPanel.Controls.Add(ic); } this._current_state = State.Running; })); break; } break; case "Pause": // pausing just _current_state = State.Paused; break; case "Stop": // stop the visualizer and clear out the images on the main thread _current_state = State.Stopped; drawn_atleast_once = false; this.Invoke(new Action(() => { this.imageFlowPanel.Controls.Clear(); })); break; case "Zoom": // update image controls on the main thread var delta = (int)m["delta"]; // scale must be at least 1 _scale = Math.Max(delta + _scale, 1); UpdateImageControlDimensions(); break; } } else { // sleep when the message queue is empty Thread.Sleep(50); } if (_current_state == State.Running && drawn_atleast_once == false) { drawn_atleast_once = true; time_since_last_draw = 0.0; Drawing(); prev = DateTime.Now; } if (_current_state == State.Running && time_since_last_draw >= DrawInterval) { if (this.Parent != null && this.Parent.Visible == true) { if (parent_previously_visible == false) { // sleep awhile before drawing if we just flipped to this tab Thread.Sleep(500); } // reset time_since_last_draw and update time_since_last_draw = 0.0; Drawing(); prev = DateTime.Now; } parent_previously_visible = this.Parent != null ? this.Parent.Visible : false; } } }