001package jmri.jmrix.pi.simulator;
002
003import java.util.ArrayList;
004import java.util.List;
005import java.util.function.Consumer;
006
007/**
008 * Simulates a digital input GPIO pin for the JMRI Raspberry Pi simulator.
009 * Pure JMRI implementation — no Pi4J dependency.
010 * <p>
011 * The initial state is HIGH so that sensors constructed in tests start as
012 * {@code Sensor.ACTIVE}, preserving the behaviour of the former
013 * {@code PiGpioProviderScaffold} which returned {@code PinState.HIGH}.
014 *
015 * @author Daniel Bergqvist Copyright (C) 2022
016 */
017public class GpioPinDigitalInputSimulator {
018
019    /** Starts HIGH to match legacy scaffold behaviour in tests. */
020    private boolean high = true;
021
022    private final List<Consumer<Boolean>> listeners = new ArrayList<>();
023
024    public boolean isHigh() {
025        return high;
026    }
027
028    /**
029     * Change the simulated pin state and notify all registered listeners.
030     *
031     * @param high {@code true} = HIGH, {@code false} = LOW
032     */
033    public void setState(boolean high) {
034        this.high = high;
035        for (Consumer<Boolean> listener : new ArrayList<>(listeners)) {
036            listener.accept(high);
037        }
038    }
039
040    public void addListener(Consumer<Boolean> listener) {
041        listeners.add(listener);
042    }
043
044    public void removeListener(Consumer<Boolean> listener) {
045        listeners.remove(listener);
046    }
047}