package com.github.czyzby.lml.parser.impl.tag.macro; import com.badlogic.gdx.utils.ObjectMap; import com.github.czyzby.kiwi.util.gdx.collection.GdxArrays; import com.github.czyzby.lml.parser.LmlParser; import com.github.czyzby.lml.parser.tag.LmlTag; /** Allows to repeat chosen template part multiple times. Expects an int attribute: runs amount. Allows to access its * iteration index. For example: <blockquote> * * <pre> * <:loop 3>txt{loop:index} </:loop> * </pre> * * </blockquote>This loop will print: "txt0 txt1 txt2 ". * * <p> * Tip: if you need to iterate over non-standard number range, use {@link ForEachLmlMacroTag} with a range argument * instead: <blockquote> * * <pre> * <:each index=[4,-2]>{index} </:each> * </pre> * * </blockquote>This will prints: "4 3 2 1 0 -1 -2 ". (If the start of the range is bigger than the end, value will be * decremented on each iteration turn. For example, [-2,4] range would print "-2 -1 0 1 2 3 4 "). * * @author MJ */ public class LoopLmlMacroTag extends AbstractLoopLmlMacroTag { private final int stepsAmount; private int currentIndex; public LoopLmlMacroTag(final LmlParser parser, final LmlTag parentTag, final StringBuilder rawTagData) { super(parser, parentTag, rawTagData); stepsAmount = getStepsAmount(); } private int getStepsAmount() { if (GdxArrays.isEmpty(getAttributes())) { getParser().throwErrorIfStrict("Loop macro needs at least one attribute: runs amount."); return 0; } final int amount; if (hasAttribute(TIMES_ATTRIBUTE)) { amount = getParser().parseInt(getAttribute(TIMES_ATTRIBUTE), getActor()); } else { amount = getParser().parseInt(getAttributes().first(), getActor()); } if (amount < 0) { getParser().throwErrorIfStrict("Loop macro runs amount cannot be negative."); return 0; } return amount; } @Override protected boolean hasNext() { return currentIndex < stepsAmount; } @Override protected int getIndex() { return currentIndex; } @Override protected void next(final ObjectMap<String, String> arguments) { currentIndex++; } @Override public String[] getExpectedAttributes() { return new String[] { TIMES_ATTRIBUTE }; } }