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  public void poll() {
035    try {
036      m_running = true;
037      m_bindings.forEach(Runnable::run);
038    } finally {
039      m_running = false;
040    }
041  }
042
043  /** Clear all bindings. */
044  public void clear() {
045    if (m_running) {
046      throw new ConcurrentModificationException("Cannot clear EventLoop while it is running");
047    }
048    m_bindings.clear();
049  }
050}