package de.renew.simulator.api;

import java.util.function.Supplier;

/**
 * This interface is responsible for managing the simulation lock and performing actions with it.
 */
public interface ISimulationLockExecutor {

    /**
     * Locks the simulation lock. If the lock is already locked, the caller has to wait.
     */
    void lock();

    /**
     * Unlocks the simulation lock.
     */
    void unlock();

    /**
     * Runs the given runnable. Before running, the simulation lock is locked.
     * Afterwards, the lock is unlocked again.
     *
     * @param runnable the runnable to run
     */
    void runWithLock(Runnable runnable);

    /**
     * Runs the given supplier and returns its result. Before running, the simulation lock is locked.
     * Afterwards, the lock is unlocked again.
     *
     * @param supplier the supplier to run
     * @param <T> the result's type
     * @return the supplier's result
     */
    <T> T supplyWithLock(Supplier<T> supplier);
}
