Package games.stendhal.server.script

Source Code of games.stendhal.server.script.DumpTransitionsEx

/* $Id: DumpTransitionsEx.java,v 1.19 2011/05/01 19:50:06 martinfuchs Exp $ */
package games.stendhal.server.script;

import games.stendhal.common.parser.Expression;
import games.stendhal.server.core.engine.SingletonRepository;
import games.stendhal.server.core.scripting.ScriptImpl;
import games.stendhal.server.entity.npc.ConversationStates;
import games.stendhal.server.entity.npc.SpeakerNPC;
import games.stendhal.server.entity.npc.fsm.PostTransitionAction;
import games.stendhal.server.entity.npc.fsm.PreTransitionCondition;
import games.stendhal.server.entity.npc.fsm.Transition;
import games.stendhal.server.entity.player.Player;
import games.stendhal.server.events.TransitionGraphEvent;
import games.stendhal.server.util.UniqueIdentifierMap;

import java.util.List;
import java.util.Map;

import marauroa.common.game.RPEvent;

import org.apache.commons.lang.StringEscapeUtils;

/**
* Dumps the transition table of an NPC for "dot" http://www.graphviz.org/ to
* display a nice graph.
*
* @author hendrik
*/
public class DumpTransitionsEx extends ScriptImpl {

  private StringBuilder dumpedTable;
  private UniqueIdentifierMap<PreTransitionCondition> conditions;
  private UniqueIdentifierMap<PostTransitionAction> actions;

  @Override
  public void execute(final Player admin, final List<String> args) {

    if (args.size() < 1) {
      admin.sendPrivateText("/script DumpTransitionsEx.class <npcname>");
      return;
    }

    final StringBuilder npcName = new StringBuilder();
    for (final String arg : args) {
      npcName.append(arg + " ");
    }
    final SpeakerNPC npc = SingletonRepository.getNPCList().get(npcName.toString().trim());
    if (npc == null) {
      admin.sendPrivateText("There is no NPC called " + npcName);
      return;
    }
    dump(npc);

    String data = dumpedTable.toString();
    final RPEvent event = new TransitionGraphEvent(data);
    admin.addEvent(event);
  }

  /**
   * Returns the transition diagram as string.
   *
   * @param npc
   *            SpeakerNPC
   * @return transition diagram
   */
  public String getDump(final SpeakerNPC npc) {
    dump(npc);
    return dumpedTable.toString();
  }

  private void dump(final SpeakerNPC npc) {
    dumpedTable = new StringBuilder();
    conditions = new UniqueIdentifierMap<PreTransitionCondition>("C");
    actions = new UniqueIdentifierMap<PostTransitionAction>("A");

    dumpHeader();
    dumpNPC(npc);
    dumpCaption();
    dumpFooter();
  }

  private void dumpHeader() {
    dumpedTable.append("digraph finite_state_machine {\r\n");
    dumpedTable.append("rankdir=LR\r\n");
  }

  private void dumpNPC(final SpeakerNPC npc) {
    final List<Transition> transitions = npc.getTransitions();
    for (final Transition transition : transitions) {
      dumpedTable.append(getStateName(transition.getState()) + " -> "
          + getStateName(transition.getNextState()));

      for(Expression expr : transition.getTriggers()) {
        final String transitionName = getExtendedTransitionName(transition, expr.toString());

        dumpedTable.append(" [ label = \"" + transitionName.replace("{", "\\{").replace("}", "\\}") + "\" ];\r\n");
      }
    }
  }

  private String getExtendedTransitionName(final Transition transition, String transitionName) {
    if (transition.getCondition() != null) {
      String key = conditions.add(transition.getCondition());

      if (!transition.isPreferred()) {
        key = "-" + key;
      }

      transitionName = "(" + key + ") " + transitionName;
    }

    if (transition.getAction() != null) {
      final String key = actions.add(transition.getAction());
      transitionName = transitionName + " (" + key + ")";
    }

    return transitionName;
  }

  private static String getStateName(final ConversationStates number) {
    return number.toString();
//    final Integer num = Integer.valueOf(number);
//    final Field[] fields = ConversationStates.class.getFields();
//    for (final Field field : fields) {
//      try {
//        if (field.get(null).equals(num)) {
//          return field.getName();
//        }
//      } catch (final IllegalArgumentException e) {
//        logger.error(e, e);
//      } catch (final IllegalAccessException e) {
//        logger.error(e, e);
//      }
//    }
//    return Integer.toString(number);
  }

  private void dumpFooter() {
    dumpedTable.append("}");
  }

  private void dumpCaption() {
    dumpedTable.append("\r\n");
    dumpedTable.append("\"caption\" [\r\n");
    dumpedTable.append("label = \"");
    dumpedTable.append("Caption");
    for (final Map.Entry<String, PreTransitionCondition> entry : conditions) {
      dumpedTable.append(" | " + entry.getKey() + "\t"
          + captionEntryToString(entry.getValue().toString()));
    }
    for (final Map.Entry<String, PostTransitionAction> entry : actions) {
      dumpedTable.append(" | " + entry.getKey() + "\t"
          + captionEntryToString(entry.getValue()));
    }
    dumpedTable.append("\"\r\n");
    dumpedTable.append("shape = \"record\"\r\n");
    dumpedTable.append("];\r\n");
  }

  private String captionEntryToString(final Object entry) {
    final String prefix = "games.stendhal.server.";
    String entryName = entry.toString();
    entryName = StringEscapeUtils.escapeHtml(entryName);
    if (entryName.startsWith(prefix)) {
      entryName = entryName.substring(prefix.length());
    }
    entryName = entryName.replace("{", "\\{").replace("}", "\\}");
    return entryName;
  }
}
TOP

Related Classes of games.stendhal.server.script.DumpTransitionsEx

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.