Package cz.matfyz.aai.fantom.message

Source Code of cz.matfyz.aai.fantom.message.MessageMoveBase$ActorMove

/*
   This file is part of Fantom.

    Fantom 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.

    Fantom 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 Fantom.  If not, see <http://www.gnu.org/licenses/>.
*/
package cz.matfyz.aai.fantom.message;

import java.util.ArrayList;
import java.util.Properties;

import cz.matfyz.aai.fantom.game.Actor;
import cz.matfyz.aai.fantom.game.Graph;
import cz.matfyz.aai.fantom.game.TransportType;
import cz.matfyz.aai.fantom.game.Graph.Node;
import cz.matfyz.aai.fantom.server.ProtocolException;

/**
* Base class for messages informing about movements ('move' and 'update')
*/
public abstract class MessageMoveBase extends Message {

  /**
   * The name of the property that contains ID of the actor.
   */
  public static final String PROPERTY_ACTOR = "actor";
 
  /**
   * The name of the property that contains the ID of the target node.
   */
  public static final String PROPERTY_TO_NODE = "to";
 
  /**
   * The name of the property that contains the type of transport used
   * for the movement.
   */
  public static final String PROPERTY_TRANSPORT_TYPE = "transport";

  /**
   * Contains specification of the movement of a single actor.
   */
  public static class ActorMove {
    /**
     * The moved actor.
     */
    private Actor actor;
    /**
     * The target node for the actor.
     */
    private Node targetNode;
    /**
     * The transport type used in the movement.
     */
    private TransportType transportType;
   
    /**
     * Returns the moved actor.
     * @return the moved actor.
     */
    public Actor getActor() {
      return this.actor;
    }
   
    /**
     * Returns the target node.
     * @return the target node.
     */
    public Node getTargetNode() {
      return this.targetNode;
    }
   
    /**
     * Returns the transport type used for the movement.
     * @return the transport type used for the movement.
     */
    public TransportType getTransportType() {
      return this.transportType;
    }
   
    /**
     * Loads the properties of the movement from serialized data, and matches
     * it to the objects in the given graph.
     *
     * @param graph the graph, to which the movement is matched.
     * @param properties the serialized data of the movement.
     * @throws ProtocolException if there is a problem with loading the movement.
     */
    protected void loadProperties(Graph graph, Properties properties) throws ProtocolException {
      if(graph == null)
        throw new IllegalArgumentException("graph must not be null");
      if(properties == null)
        throw new IllegalArgumentException("properties must not be null");
     
      String actorId = properties.getProperty(PROPERTY_ACTOR);
      if(actorId == null || actorId.isEmpty())
        throw new ProtocolException("No actor ID was specified", null);
      this.actor = graph.getActor(actorId);
      if(this.actor == null)
        throw new ProtocolException("The actor '" + actorId + "' does not exist", null);
     
      String targetId = properties.getProperty(PROPERTY_TO_NODE);
      if(targetId != null && !targetId.isEmpty()) {
        this.targetNode = graph.getNode(targetId);
        if(this.targetNode == null)
          throw new ProtocolException("The node '" + targetId + "' does not exist", null);
      }
     
      String transportName = properties.getProperty(PROPERTY_TRANSPORT_TYPE);
      if(transportName != null && !transportName.isEmpty()) {
        this.transportType = graph.getTransportType(transportName);
        if(this.transportType == null)
          throw new ProtocolException("The transport type '" + transportName + "' does not exist", null);
      }
      else if(targetNode == null)
        throw new ProtocolException("Neither transport type nor target node was not specified", null);
    }
   
    /**
     * Serializes the information about the movement.
     * @return the serialized information about the movement.
     */
    public Properties serialize() {
      Properties res = new Properties();
      res.setProperty(PROPERTY_ACTOR, actor.getId());
      if(targetNode != null)
        res.setProperty(PROPERTY_TO_NODE, targetNode.getId());
      if(transportType != null)
        res.setProperty(PROPERTY_TRANSPORT_TYPE, transportType.getName());
     
      return res;
    }
   
    /**
     * Creates a new actor movement object.
     *
     * @param actor the actor that performs the movement.
     * @param target the target of the movement.
     * @param transport the type of transport used for the movement.
     */
    public ActorMove(Actor actor, Node target, TransportType transport) {
      if(actor == null)
        throw new IllegalArgumentException("actor must not be null");
      if(transport == null && target == null)
        throw new IllegalArgumentException("either transport or target must not be null");
     
      this.actor = actor;
      this.targetNode = target;
      this.transportType = transport;
    }
   
    /**
     * Creates a new actor movement object and loads it from properties.
     *
     * @param graph the game graph, for which the move is loaded.
     * @param properties the serialized data of the movement.
     * @throws ProtocolException if there is a problem with loading the
     *         movement.
     */
    public ActorMove(Graph graph, Properties properties) throws ProtocolException {
      loadProperties(graph, properties);
    }
  }

  /**
   * The list of moves contained in this message.
   */
  private ActorMove[] moves;
 
  /**
   * Contains the raw message data.
   */
  private Properties[] messageData;

  /**
   * Returns the specifications of moves sent in the message.
   *
   * @return the specifications of moves sent in the message.
   */
  public ActorMove[] getMoves() {
    return this.moves;
  }
 
  /**
   * Loads the serialized data of the message.
   *
   * @param graph the graph, for which the data are loaded.
   * @param messageData the serialized message data.
   * @throws ProtocolException if there is a problem with loading the
   *         data of the message.
   */
  protected void loadProperties(Graph graph, Properties[] messageData) throws ProtocolException {
    ArrayList<ActorMove> actorMoves = new ArrayList<ActorMove>();
    for(int i = 0; i < messageData.length; i++) {
      if(messageData[i].containsKey(PROPERTY_ACTOR)) {
        actorMoves.add(new ActorMove(graph, messageData[i]));
      }
    }
    moves = actorMoves.toArray(new ActorMove[actorMoves.size()]);
  }
 
  @Override
  public Properties[] serialize() {
    if(messageData == null) {
      assert moves != null : "Both messageData and moves is null";
      messageData = new Properties[moves.length + 1];
      for(int i = 0; i < moves.length; i++)
        messageData[i+1] = moves[i].serialize();
     
      Properties header = new Properties();
      header.setProperty(PROPERTY_MESSAGE_TYPE, getMessageType());
      messageData[0] = header;
    }
    return messageData;
  }

  /**
   * Initializes a new instance of the message from serialized data.
   *
   * @param graph the game graph, for which the message is loaded.
   * @param messageData the data of the message.
   * @throws ProtocolException if there is a problem with loading the
   *         data of the message.
   */
  public MessageMoveBase(Graph graph, Properties[] messageData) throws ProtocolException {
    initialize();
    loadProperties(graph, messageData);
    this.messageData = messageData;
  }
 
  /**
   * Initializes a new instance of the message for the given moves.
   *
   * @param moves the moves, for which the message is initialized.
   */
  public MessageMoveBase(ActorMove[] moves) {
    initialize();
    if(moves == null)
      throw new IllegalArgumentException("moves must not be null");
    for(int i = 0; i < moves.length; i++) {
      if(moves[i] == null)
        throw new IllegalArgumentException("moves must not contain null values");
    }
    this.moves = moves;
  }
 
  /**
   * Performs initialization of inner structures of the message. Derived
   * classes should override this method.
   */
  protected void initialize() {
   
  }
}
TOP

Related Classes of cz.matfyz.aai.fantom.message.MessageMoveBase$ActorMove

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.