package de.renew.net;

import de.renew.simulatorontology.simulation.StepIdentifier;
import de.renew.unify.Impossible;

/**
 * An {@code INetInstantiator} is used to create instances of nets.
 */
public interface INetInstantiator {
    /**
     * Create one instance of the net of this {@code INetInstantiator}, but does not yet confirm
     * its creation. Used for creating instances that may have to be
     * discarded early.
     * <p>
     * When instantiating nets from Java code outside the simulation
     * engine, in most cases {@link #buildInstance} is the better choice.
     *
     * @return a newly allocated {@code NetInstance}
     * @exception Impossible if an initial marking expression
     *            evaluation fails.
     */
    NetInstance makeInstance() throws Impossible;

    /**
     * Creates an instance of the net of this {@code INetInstantiator} and confirms it.
     * <p>
     * Unlike the method {@link #makeInstance}, this
     * method immediately confirms the creation of the
     * generated net instance, so that external users do not need
     * to know about confirmation issues.
     * <p>
     * If the current simulation step is not known, call the method
     * {@link #buildInstance()} instead of this one.
     *
     * @param stepIdentifier  the simulation step to which this
     *                        instantiation belongs.
     * @return a newly allocated {@code NetInstance}
     */
    NetInstance buildInstance(StepIdentifier stepIdentifier);

    /**
     * Creates an instance of the net of this {@code INetInstantiator} and confirms it.
     * The method delegates to {@link #buildInstance(StepIdentifier)} with
     * a fresh {@code stepIdentifier} obtained from the current
     * simulation environment.
     *
     * @return a newly allocated {@code NetInstance}
     */
    NetInstance buildInstance();
}
