package li.cil.oc.api.network;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * This annotation can be used for methods in an {@link Environment} to mark
 * them for exposure to Lua.
 * <p/>
 * Any method exposed like this can be enumerated and called from a computer
 * that can see the node of the environment.
 * <p/>
 * Note that methods annotated with this interface must have the following
 * signature:
 * <pre>
 *     Object[] f(Computer computer, Arguments arguments);
 * </pre>
 *
 * @see Context
 * @see Arguments
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LuaCallback {
    /**
     * The name under which to make the callback available in Lua.
     */
    String value() default "";

    /**
     * Whether this function may be called directly from the computer's executor
     * thread instead of from the server thread.
     * <p/>
     * You will have to ensure anything your callback does is thread safe when
     * setting this to <tt>true</tt>. Use this for minor lookups, for example.
     * This is mainly intended to allow functions to perform faster than when
     * called 'synchronously' (where the call takes at least one server tick).
     * <p/>
     * Keep in mind that the node {@link Network} is <em>not</em> thread safe!
     * Be sure you know what you're doing if you're working with a node's
     * network in a direct callback.
     */
    boolean direct() default false;

    /**
     * The maximum number of direct calls that may be performed on this
     * component in a single <em>tick</em>.
     * <p/>
     * This can be used to throttle call speed. For example, this is used by
     * graphics cards to limit the amount of net traffic can be generated by
     * updating the screen they are bound to.
     * <p/>
     * You should generally apply a limit if the callback allocates persisting
     * memory (i.e. memory that isn't freed once the call returns), sends
     * network messages, or uses any other kind of resource for which it'd be
     * bad if it were to be used from the Lua side in an unchecked, unregulated
     * manner.
     * <p/>
     * Note that the limit does <em>not</em> apply when the method is invoked
     * via a direct call to {@link Component#invoke(String, Context, Object...)}
     * from the host side. Also, this limit is per-computer, so the method may
     * be invoked more often than this per tick, if different computers call it.
     * <p/>
     * An exception to that rule is {@link Connector#changeBuffer(double)},
     * which is synchronized, so you can consume/produce power in direct calls.
     */
    int limit() default Integer.MAX_VALUE;
}
