package com.github.czyzby.lml.parser.impl.tag.macro; import com.badlogic.gdx.scenes.scene2d.Actor; import com.github.czyzby.lml.parser.LmlParser; import com.github.czyzby.lml.parser.impl.tag.MockLmlTag; import com.github.czyzby.lml.parser.tag.LmlTag; import com.github.czyzby.lml.util.LmlUtilities; /** Expanded evaluate macro. Instead of just finding and executing a method, it will expect that the method returns an * instance of {@link Actor} that should be appended. Returned actor will be A) added as a child to the tag in which the * macro is invoked, B) added to the result actors collection if the macro is not in a tag. Evaluation works similarly: * first argument is the method ID; if there is text between macro tags, method consuming string is invoked with the raw * data between tags; otherwise, method consuming parent actor is invoked. Second macro attribute becomes actor's ID. * For example: <blockquote> * * <pre> * <table><:actor methodName/></table> * </pre> * * </blockquote> This will look for a method mapped to "methodName" and invoke it with the Table (parent's actor) as its * argument. The returned actor will be added to the table. * * <blockquote> * * <pre> * <:actor methodId actorId>Method argument</:actor> * </pre> * * </blockquote>This will look for a method mapped to "methodId" and invoke it with a string parameter: * "Method argument" (which was between macro tags). The actor's ID will be set as "actorId", as specified by second * macro attribute. Since this macro is not in another tag, this actor will be added directly to the result collection * and will not be appended by any parent. * <p> * This macro can be also used with named parameters: <blockquote> * * <pre> * <:actor method="methodId" id="actorId">Method argument</:actor> * </pre> * * </blockquote> * * @author MJ */ public class ActorLmlMacroTag extends EvaluateLmlMacroTag { public ActorLmlMacroTag(final LmlParser parser, final LmlTag parentTag, final StringBuilder rawTagData) { super(parser, parentTag, rawTagData); } @Override protected void processMethodResult(final Object result) { if (result instanceof Actor) { final Actor actor = (Actor) result; addActorId(actor); final LmlTag parent = getParent(); if (parent != null) { // Macro is inside another tag. Delegating child handling to the parent. parent.handleChild(new MockLmlTag(actor, parent)); } else { // Macro is not in a tag. Adding actor to the result. getParser().addActor(actor); } } else { getParser().throwErrorIfStrict("Actor macro has to reference a method that returns a valid Actor object."); } } /** @param actor if the macro has a second attribute, it will set it as this actor's ID. */ protected void addActorId(final Actor actor) { if (hasAssignmentArgumentName()) { final String id = getAssignmentArgumentName(); LmlUtilities.setActorId(actor, id); getParser().getActorsMappedByIds().put(id, actor); } } }