/*
* Strongback
* Copyright 2015, Strongback and individual contributors by the @authors tag.
* See the COPYRIGHT.txt in the distribution for a full listing of individual
* contributors.
*
* Licensed under the MIT License; you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.strongback.components;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import org.strongback.annotation.ThreadSafe;
/**
* A relay is a device that can be turned on and off. Note that a relay has one of 5 possible states:
* <ol>
* <li>ON - the relay is in the "on" position;</li>
* <li>OFF - the relay is in the "off" position;</li>
* <li>SWITCHING_ON - the relay was in the "off" position but has been changed and is not yet in the "on" position;</li>
* <li>SWITCHING_OFF - the relay was in the "on" position but has been changed and is not yet in the "off" position; and</li>
* <li>UNKNOWN - the relay position is not known</li>
* </ol>
* <p>
* Not all Relay implementations use all relay states. Very simple relays that have no delay will simply only use
* {@link State#ON} and {@link State#OFF}, while relays that have some delay might also use {@link State#SWITCHING_ON} and
* {@link State#SWITCHING_OFF}. Those relay implementations that may not know their position upon startup may start out in the
* UNKNOWN state.
*
* @author Zach Anderson
*
*/
@ThreadSafe
public interface Relay {
static enum State {
/** The relay is presently switching into the "ON" state but has not yet completed the change. */
SWITCHING_ON,
/** The relay is presently in the "on" position. */
ON,
/** The relay is presently switching into the "OFF" state but has not yet completed the change. */
SWITCHING_OFF,
/** The relay is presently in the "off" position. */
OFF,
/** The actual state of the relay is not known. */
UNKOWN
}
/**
* Get the current state of this relay.
*
* @return the current state; never null
*/
State state();
/**
* Turn on this relay.
*
* @return this object to allow chaining of methods; never null
*/
Relay on();
/**
* Turn off this relay.
*
* @return this object to allow chaining of methods; never null
*/
Relay off();
/**
* Check whether this relay is known to be on. This is equivalent to calling {@code state() == State.ON}.
*
* @return {@code true} if this relay is on; or {@code false} otherwise
*/
default boolean isOn() {
return state() == State.ON;
}
/**
* Check whether this relay is known to be off. This is equivalent to calling {@code state() == State.OFF}.
*
* @return {@code true} if this relay is off; or {@code false} otherwise
*/
default boolean isOff() {
return state() == State.OFF;
}
/**
* Check if this relay is switching on. This is equivalent to calling {@code state() == State.SWITCHING_ON}.
*
* @return {@code true} if this relay is in the process of switching from off to on; or {@code false} otherwise
*/
default boolean isSwitchingOn() {
return state() == State.SWITCHING_ON;
}
/**
* Check if this relay is switching off. This is equivalent to calling {@code state() == State.SWITCHING_OFF}.
*
* @return {@code true} if this relay is in the process of switching from on to off; or {@code false} otherwise
*/
default boolean isSwitchingOff() {
return state() == State.SWITCHING_OFF;
}
/**
* Obtain a relay that remains in one fixed state, regardless of any calls to {@link #on()} or {@link #off()}.
*
* @param state the fixed state; may not be null
* @return the constant relay; never null
*/
static Relay fixed(State state) {
return new Relay() {
@Override
public State state() {
return state;
}
@Override
public Relay on() {
return this;
}
@Override
public Relay off() {
return this;
}
};
}
/**
* Obtain a relay that instantaneously switches from one state to another using the given functions.
*
* @param switcher the function that switches the state, where <code>true</code> represents {@link State#ON} and
* <code>false</code> represents {@link State#OFF}; may not be null
* @param onState the function that returns <code>true</code> if the current state is {@link State#ON}, or
* <code>false</code> otherwise; may not be null
* @return the relay; never null
*/
static Relay instantaneous(Consumer<Boolean> switcher, BooleanSupplier onState) {
return new Relay() {
@Override
public State state() {
return onState.getAsBoolean() ? State.ON : State.OFF;
}
@Override
public Relay on() {
switcher.accept(Boolean.TRUE);
return this;
}
@Override
public Relay off() {
switcher.accept(Boolean.FALSE);
return this;
}
};
}
}