package de.renew.engine.thread;

import java.util.function.Supplier;

import de.renew.simulator.api.ISimulationLockExecutor;


/**
 * This implementation of {@link ISimulationLockExecutor} is responsible for managing the simulator's lock.
 * It is provided to the interface module through the {@link SimulationLockExecutorProvider}.
 * The facade for this class is {@link de.renew.simulator.api.SimulationLockExecutor}.
 */
class SimulationLockExecutorImpl implements ISimulationLockExecutor {

    /**
     * This lock is used to synchronize access to all method calls that operate
     * on the simulation state. For usage details see {@link #lock()} und {@link #unlock()}.
     */
    private static final InheritableSimulationThreadLock LOCK =
        new InheritableSimulationThreadLock();

    @Override
    public void lock() {
        LOCK.lock();
    }

    @Override
    public void unlock() {
        LOCK.unlock();
    }

    @Override
    public void runWithLock(Runnable runnable) {
        LOCK.lock();
        try {
            runnable.run();
        } finally {
            LOCK.unlock();
        }
    }

    @Override
    public <T> T supplyWithLock(Supplier<T> supplier) {
        LOCK.lock();
        try {
            return supplier.get();
        } finally {
            LOCK.unlock();
        }
    }
}
