async Task SequenceRunner(VibrationPattern pattern, CancellationToken token) { int sequence_index = 0; while (!token.IsCancellationRequested) { //either loop the sequence or end. if (sequence_index >= pattern.Time.Count) { if (!pattern.Loop) { break; } sequence_index = 0; } int time = (int)pattern.Time[sequence_index]; //1. build payload. List <double> payload = new List <double>(); for (var i = 0; i < VibrationMotorCount; i++) { var motor_index = i; //if there is only one motor entry, only use that. if (pattern.Speeds.Count == 1) { motor_index = 0; } //if a motor entry/value was not supplied in the pattern, no big deal, assume zero. var motor_entry = pattern.Speeds.ElementAtOrDefault(motor_index); var motor_speed = motor_entry.ElementAtOrDefault(sequence_index); payload.Add(Math.Clamp(motor_speed * 0.01f * _power_multiplier, 0f, 1f)); } //2. send the payload if (!_busy) { _ = SetBusy(); await _device.SendVibrateCmd(payload); } //3. sleep await Task.Delay(time); //4. rinse and repeat sequence_index++; } }
/// <summary> /// Plays a vibration sequence on the device. /// </summary> public bool SendVibrateSequence(VibrationPattern pattern) { if (pattern.MotorCount == 0) { return(false); } if (!pattern.Validate()) { return(false); } if (_runner != null) { _runner.Cancel(); } _runner = new CancellationTokenSource(); _ = SequenceRunner(pattern, _runner.Token); return(true); }