/* * This file is part of Skript. * * Skript is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Skript is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Skript. If not, see <http://www.gnu.org/licenses/>. * * * Copyright 2011-2013 Peter Güttinger * */ package ch.njol.skript.lang.function; import java.util.Arrays; import org.eclipse.jdt.annotation.Nullable; import ch.njol.skript.classes.ClassInfo; import ch.njol.util.coll.CollectionUtils; /** * @author Peter Güttinger */ public abstract class Function<T> { final String name; final Parameter<?>[] parameters; @Nullable final ClassInfo<T> returnType; final boolean single; public Function(final String name, final Parameter<?>[] parameters, final @Nullable ClassInfo<T> returnType, final boolean single) { this.name = name; this.parameters = parameters; this.returnType = returnType; this.single = single; } public String getName() { return name; } @SuppressWarnings("null") public Parameter<?> getParameter(final int index) { return parameters[index]; } public Parameter<?>[] getParameters() { return parameters; } @Nullable public ClassInfo<T> getReturnType() { return returnType; } public boolean isSingle() { return single; } // TODO allow setting parameters by name public int getMinParameters() { for (int i = parameters.length - 1; i >= 0; i--) { if (parameters[i].def == null) return i + 1; } return 0; } public int getMaxParameters() { return parameters.length; } // FIXME what happens with a delay in a function? /** * @param params An array with at least {@link #getMinParameters()} elements and at most {@link #getMaxParameters()} elements. * @return The result of the function */ @SuppressWarnings("null") @Nullable public final T[] execute(final Object[][] params) { final FunctionEvent e = new FunctionEvent(); if (params.length > parameters.length) { assert false : params.length; return null; } final Object[][] ps = params.length < parameters.length ? Arrays.copyOf(params, parameters.length) : params; assert ps != null; for (int i = 0; i < parameters.length; i++) { final Parameter<?> p = parameters[i]; final Object[] val = i < params.length ? params[i] : p.def != null ? p.def.getArray(e) : null; if (val == null || val.length == 0) return null; ps[i] = val; } final T[] r = execute(e, ps); assert returnType == null ? r == null : r == null || (r.length <= 1 || !single) && !CollectionUtils.contains(r, null) && returnType.getC().isAssignableFrom(r.getClass().getComponentType()) : this + "; " + Arrays.toString(r); return r == null || r.length > 0 ? r : null; } /** * @param e * @param params An array containing as many arrays as this function has parameters. The contained arrays are neither null nor empty, and are of type Object[] (i.e. not of the * actual parameters' types). * @return Whatever this function is supposed to return. May be null or empty, but must not contain null elements. */ @Nullable public abstract T[] execute(FunctionEvent e, final Object[][] params); @Override public String toString() { return "function " + name; } }