/// <summary> /// Every n loops, issue the specified credit value /// </summary> /// <param name="loops">Count of loops between credits</param> /// <param name="count">Run this many times. -1 to loop forever.</param> /// <param name="creditIndices">Credits to issue</param> public T CreditEveryNLoops(int loops, int count, params byte[] creditIndices) { // Create a new validator so we have perfect control of the state var validator = new ApexValidator(Config); // Setup a semaphore to wait for this many polling loops var sem = new EmulationLoopSemaphore(_token) { SignalAt = loops * count }; // Start in idling state _emulator.CurrentState = Rs232State.Idling; _emulator.CurrentEvents = Rs232Event.None; var next = 0; _emulator.OnPollResponseSent += sem.LoopCallback; sem.OnLoopCalled += (sender, args) => { switch (_emulator.CurrentState) { case Rs232State.None: _emulator.CurrentState = Rs232State.Idling; _emulator.CurrentEvents = Rs232Event.None; break; case Rs232State.Idling: if (sem.Iterations % loops == 0) { _emulator.CurrentState = Rs232State.Accepting; _emulator.CurrentEvents = Rs232Event.None; } break; case Rs232State.Accepting: _emulator.CurrentState = Rs232State.Stacking; _emulator.CurrentEvents = Rs232Event.None; break; case Rs232State.Stacking: _emulator.CurrentState = Rs232State.Idling; _emulator.CurrentEvents = Rs232Event.Stacked; _emulator.Credit = creditIndices[next++ % creditIndices.Length]; break; } }; validator.StartPollingLoop(); // Wait for signal sem.Gate.WaitOne(); // Cleanup validator.StopPollingLoop(); _emulator.OnPollResponseSent -= sem.LoopCallback; return(_emulator); }
/// <summary> /// Runs polling loop this many times at a minimum. /// Due to timing limitations, this is a minimum run count /// and their may be 1 or more extra loops executed. /// </summary> /// <param name="loops">Loops to run</param> /// <returns></returns> public T RunIdleFor(int loops) { // Setup a semaphore to wait for this many polling loops var sem = new EmulationLoopSemaphore(_token) { SignalAt = loops }; _emulator.OnPollResponseSent += sem.LoopCallback; sem.OnLoopCalled += (sender, args) => { // Always be idle _emulator.CurrentState = Rs232State.Idling; }; // Create a new validator so we have perfect control of the state var validator = new ApexValidator(Config); validator.StartPollingLoop(); // Wait for signal sem.Gate.WaitOne(); // Cleanup validator.StopPollingLoop(); _emulator.OnPollResponseSent -= sem.LoopCallback; return(_emulator); }