001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.wpilibj.event;
006
007import java.util.Collection;
008import java.util.ConcurrentModificationException;
009import java.util.LinkedHashSet;
010
011/**
012 * A declarative way to bind a set of actions to a loop and execute them when the loop is polled.
013 */
014public final class EventLoop {
015  private final Collection<Runnable> m_bindings = new LinkedHashSet<>();
016  private boolean m_running;
017
018  /** Default constructor. */
019  public EventLoop() {}
020
021  /**
022   * Bind a new action to run when the loop is polled.
023   *
024   * @param action the action to run.
025   */
026  public void bind(Runnable action) {
027    if (m_running) {
028      throw new ConcurrentModificationException("Cannot bind EventLoop while it is running");
029    }
030    m_bindings.add(action);
031  }
032
033  /** Poll all bindings. */
034  @SuppressWarnings("PMD.UnusedAssignment")
035  public void poll() {
036    try {
037      m_running = true;
038      m_bindings.forEach(Runnable::run);
039    } finally {
040      m_running = false;
041    }
042  }
043
044  /** Clear all bindings. */
045  public void clear() {
046    if (m_running) {
047      throw new ConcurrentModificationException("Cannot clear EventLoop while it is running");
048    }
049    m_bindings.clear();
050  }
051}