/*
* 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 org.eclipse.jdt.annotation.Nullable;
import ch.njol.skript.ScriptLoader;
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.config.SectionNode;
import ch.njol.skript.effects.EffReturn;
import ch.njol.skript.lang.Trigger;
import ch.njol.skript.lang.function.Functions.FunctionData;
import ch.njol.skript.lang.util.SimpleEvent;
import ch.njol.skript.variables.Variables;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* @author Peter Güttinger
*/
public class ScriptFunction<T> extends Function<T> {
final Trigger trigger;
@SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
public ScriptFunction(final String name, final Parameter<?>[] parameters, final SectionNode node, @Nullable final ClassInfo<T> returnType, final boolean single) {
super(name, parameters, returnType, single);
// here to allow recursion
Functions.functions.put(name, new FunctionData(this));
Functions.currentFunction = this;
try {
trigger = new Trigger(node.getConfig().getFile(), "function " + name, new SimpleEvent(), ScriptLoader.loadItems(node));
} finally {
Functions.currentFunction = null;
}
}
private boolean returnValueSet = false;
@Nullable
private T[] returnValue = null;
/**
* Should only be called by {@link EffReturn}.
*
* @param e
* @param value
*/
public final void setReturnValue(final FunctionEvent e, final @Nullable T[] value) {
assert !returnValueSet;
returnValueSet = true;
returnValue = value;
}
// REMIND track possible types of local variables (including undefined variables) (consider functions, commands, and EffChange) - maybe make a general interface for this purpose
// REM: use patterns, e.g. {_a%b%} is like "a.*", and thus subsequent {_axyz} may be set and of that type.
@Override
@Nullable
public T[] execute(final FunctionEvent e, final Object[][] params) {
for (int i = 0; i < parameters.length; i++) {
final Parameter<?> p = parameters[i];
final Object[] val = params[i];
if (p.single) {
Variables.setVariable(p.name, val[0], e, true);
} else {
for (int j = 0; j < val.length; j++) {
Variables.setVariable(p.name + "::" + (j + 1), val[j], e, true);
}
}
}
trigger.execute(e);
returnValueSet = false;
return returnValue;
}
}