/// <summary> /// SimVar result updated, find any subscribed clients and send, if value has changed or send is forced /// </summary> /// <param name="result">Latest value for a SimVar Request</param> /// <param name="forceSend">Should value always sent, even if value is unchanged?</param> public void SendVariable(SimVarRequestResult result, bool forceSend = false) { // Find any Clients requesting this variable and send latest result to them if (latestValues.Any(x => x.Request.Name == result.Request.Name && x.Request.Unit == result.Request.Unit)) { if (forceSend || latestValues.Any(x => x.Request.Name == result.Request.Name && x.Request.Unit == result.Request.Unit && x.Value != result.Value)) { // Value has been changed - rmember latest value and send to all subscribed clients latestValues.Single(x => x.Request.Name == result.Request.Name && x.Request.Unit == result.Request.Unit).Value = result.Value; var clientResponse = new ClientRequestResult { Request = new RemoteCockpitClasses.ClientRequest { Name = result.Request.Name, Unit = result.Request.Unit }, Result = result.Value }; var subscribedClients = clients.Where(x => x.Requests.Any(y => y.Name == result.Request.Name && y.Unit == result.Request.Unit)); var resultString = JsonConvert.SerializeObject(clientResponse) + "\r\r"; foreach (var client in subscribedClients) { WriteLog(string.Format("Sending Value: Client: {0}; Name: {1}; Value: {2}", client.Client.ConnectionID, result.Request.Name, result.Value)); try { client.Client.workSocket.Send(Encoding.UTF8.GetBytes(resultString)); } catch//(Exception ex) { // Often happens if the connection is dropped - should be removed from subscribedClients list } } } } }
public void ValueUpdate(ClientRequestResult value) { // Update our control to display latest value if (value.Request.Name == "INDICATED ALTITUDE") { if ((int)(double)value.Result != CurrentAltitude) { CurrentAltitude = (int)(double)value.Result; needleMoveSpeed = ((CurrentAltitude > lastAltitude ? ((double)CurrentAltitude - (double)lastAltitude) : ((double)lastAltitude - (double)CurrentAltitude)) / 2000); if (control?.Controls?.ContainsKey("Needle") == true) { //UpdateNeedle(control.Controls["Needle"]); // Only need to start the timer if it isn't already running if (animateTimer == null || !animateTimer.Enabled) { animateTimer = new System.Timers.Timer(50); animateTimer.Elapsed += MoveNeedle; animateTimer.AutoReset = true; animateTimer.Enabled = true; animateTimer.Start(); } } } } }
public void ResultUpdate(ClientRequestResult requestResult) { try { if (usedInstrumentPlugins != null) { try { foreach (var instrument in usedInstrumentPlugins) { Task.Run(() => { if (requestResult.Request.Name == "UPDATE FREQUENCY" && requestResult.Request.Unit == "millisecond") { try { instrument.UpdateFrequency = int.Parse(requestResult.Result?.ToString() ?? "3000"); } catch { } } else if (instrument.RequiredValues.Any(x => x.Name == requestResult.Request.Name && x.Unit == requestResult.Request.Unit)) { try { instrument.ValueUpdate(requestResult); UpdateCockpitItem(instrument.Control); } catch (Exception ex) { ConsoleLog(string.Format("Instrument Update Failed.\rInstrument: {0}\rSimVar: {1}\rError: {2}", instrument.Name, requestResult.Request.Name, ex.Message)); } } }); } } catch (Exception ex) { ConsoleLog(string.Format("ResultUpdate Error: {0}", ex.Message)); } UpdateCockpitItem(this); } } catch { } }
/// <summary> /// Whenever a value associated with one of our RequiredValues is updated by FS, /// it will be passed to this control via this method. /// This method should provide a low overhead, such as simply adding or updating a local variable with the new value. /// It should NOT be used to redraw the control itself. /// </summary> /// <param name="value">Required Variable Value</param> public void ValueUpdate(ClientRequestResult value) { try { if (!values.Any(x => x.Request.Name == value.Request.Name && x.Request.Unit == value.Request.Unit)) { lock (values) values.Add(value); } else { lock (values) values.First(x => x.Request.Name == value.Request.Name && x.Request.Unit == value.Request.Unit).Result = value.Result; } } catch { // Likely something is being disposed or updated - we'll need to add/update the value next time } }
private void UpdateLatestValues(ref ClientRequestResult previousResult, ClientRequestResult latestResult, ClientRequestLimits limits, double stepValue) { if ((double)previousResult.Result != (double)latestResult.Result && stepValue != 0) { var nextVal = (double)previousResult.Result + stepValue; if (nextVal > limits.Max) { nextVal = nextVal - limits.Max + limits.Min; } if (nextVal < limits.Min) { nextVal = limits.Max + nextVal - limits.Min; } // Need to modify this to check if nextValue has exceeded latestResult - taking Limits into account // e.g. if stepValue = -10, latestResult = 0 and previousResult = 9; nextValue becomes 359 // but we should detect we have passed latestResult and reset nextValue to zero if (stepValue < 0) { if (nextVal <= (double)latestResult.Result && nextVal >= (double)latestResult.Result + stepValue) { // Direct - does not pass boundary nextVal = (double)latestResult.Result; lastValue = true; } } else { if (nextVal >= (double)latestResult.Result && nextVal <= (double)latestResult.Result + stepValue) { // Direct - does not pass boundary nextVal = (double)latestResult.Result; lastValue = true; } } previousResult.Result = nextVal; if (lastValue) { RemoveTimer(); } } }
public void ValueUpdate(ClientRequestResult value) { try { if (!values.Any(x => x.Request.Name == value.Request.Name && x.Request.Unit == value.Request.Unit)) { lock (values) values.Add(value); } else { lock (values) values.First(x => x.Request.Name == value.Request.Name && x.Request.Unit == value.Request.Unit).Result = value.Result; } if (value.Request.Name == "AIRSPEED INDICATED") { if ((double)value.Result != CurrentAirspeed) { CurrentAirspeed = (double)value.Result; needleMoveSpeed = ((CurrentAirspeed > LastAirspeed ? (CurrentAirspeed - LastAirspeed) : (LastAirspeed - CurrentAirspeed)) / 200); if (control?.Controls?.ContainsKey("Needle") == true) { //UpdateNeedle(control.Controls["Needle"]); // Only need to start the timer if it isn't already running if (animateTimer == null || !animateTimer.Enabled) { animateTimer = new System.Timers.Timer(30); animateTimer.Elapsed += MoveNeedle; animateTimer.AutoReset = true; animateTimer.Enabled = true; animateTimer.Start(); } } } } } catch { // Likely something is being disposed or updated - we'll need to add/update the value next time } }
private void UpdateValuesGrid(ClientRequestResult requestResult) { if (dgValues.InvokeRequired) { MethodInvoker del = delegate { UpdateValuesGrid(requestResult); }; dgValues.Invoke(del); return; } try { var row = dgValues.Rows.Cast <DataGridViewRow>() .Where(x => x.Cells["SimVar"] != null && x.Cells["SimVar"].Value?.ToString() == requestResult.Request.Name).FirstOrDefault(); if (row == null) { // Add new row for this SimVar try { row = dgValues.Rows[dgValues.Rows.Add()]; row.Cells["SimVar"].Value = requestResult.Request.Name; } catch //(Exception ex) { } } if (row.Cells["Value"] != null) { row.Cells["Value"].Value = requestResult.Result?.ToString(); } if (row.Cells["Updated"] != null) { row.Cells["Updated"].Value = requestResult.LastUpdated.TimeOfDay.ToString(); } dgValues.Update(); } catch { } }
private void SimVarValue_Changed(object sender, DataGridViewCellEventArgs e) { if (e != null && e.RowIndex > -1 && e.ColumnIndex > -1) { var row = dgSimVarValues.Rows[e.RowIndex]; var val = row.Cells["VariableValue"].Value; val = val ?? 0; double dblVal; ClientRequestResult newValue; if (double.TryParse(val.ToString(), out dblVal)) { newValue = new ClientRequestResult { Request = new ClientRequest { Name = row.Cells["VariableName"].Value?.ToString(), Unit = row.Cells["VariableUnit"].Value?.ToString() }, Result = dblVal }; } else { DebugMessage(this, string.Format("Invalid value supplied for SimVar: {0} ({1})", row.Cells["VariableName"].Value, val)); newValue = new ClientRequestResult { Request = new ClientRequest { Name = row.Cells["VariableName"].Value?.ToString(), Unit = row.Cells["VariableUnit"].Value?.ToString() }, Result = 0 }; } instrument.ValueUpdate(newValue); } }
/// <summary> /// 接收请求处理 /// </summary> /// <param name="transmit">传输对象</param> private async void ReceiveRequestHandler(Transmit transmit) { switch (transmit.Parameter) { case "Client;AddSocket": SocketResult socketResult = await socketManager.CreateConnectionAsync(); if (socketResult != null) { switch (socketResult.State) { case ConnectionState.Success: Task task = Task.Run(() => SecondaryReceiver(socketResult.Socket)); break; case ConnectionState.Failed: break; case ConnectionState.Timeout: break; case ConnectionState.Error: break; } } break; case "Client;RequestResult": RequestResult requestResult = transmit.Object as RequestResult; if (requestResult != null) { ClientRequestResult?.Invoke(this, new RequestResultEventArgs(requestResult)); } break; } }
private void ReceiveResultFromServer(object sender, ClientRequestResult requestResult) { string message = string.Format("Value Update: {0}({1}) = {2}", requestResult.Request.Name, requestResult.Request.Unit, requestResult.Result); DebugMessage(this, message); if (requestResults.Any(x => x.Request.Name == requestResult.Request.Name && x.Request.Unit == requestResult.Request.Unit)) { lock (requestResults) { requestResults.First(x => x.Request.Name == requestResult.Request.Name && x.Request.Unit == requestResult.Request.Unit).Result = requestResult.Result; } } else { requestResults.Add(requestResult); } UpdateValuesGrid(requestResult); // Received a new value for a request - identify which plugins need this variable and send it if (requestResult.Request.Name == "FS CONNECTION") { // Just informing us the current connection state to the Flight Simulator = display it on screen var existingConnectionState = this.Controls.Find("cbFSRunning", true); foreach (Control connectionStateLabel in existingConnectionState) { if ((bool)requestResult.Result) { if (!((CheckBox)existingConnectionState.First()).Checked) { // Re-request all previous variables after reconnect foreach (var variableRequest in requestResults.Where(x => x.Request.Name != "FS CONNECTION")) { RequestVariable(variableRequest.Request); } } UpdateObject(connectionStateLabel, "Checked", true); } else { UpdateObject(connectionStateLabel, "Checked", false); } } } if (requestResult.Request.Name == "TITLE") { // New aircraft selected if (requestResult.Result != null && cmbCockpitLayout.Items.Contains(requestResult.Result?.ToString()) && cbAutoCockpitLayout.Checked) { // User wants to auto-select the aircraft UpdateObject(cmbCockpitLayout, "SelectedIndex", cmbCockpitLayout.Items.IndexOf(requestResult.Result?.ToString())); //cmbCockpitLayout.SelectedIndex = cmbCockpitLayout.Items.IndexOf(requestResult.Result?.ToString()); if (cockpit != null) { // Cockpit already display - reload with the new layout ReloadCockpit(requestResult.Result.ToString()); } } } else { if (cockpit != null) { cockpit.ResultUpdate(requestResult); } } }