package EnvironmentPluginAPI.CustomNetworkMessages;
import java.io.Serializable;
import java.util.Arrays;
/**
* The basic network message.
* <br/><br/>
* All communication in the MARLA system between MARLA-Server and -Client is realized by messages inheriting from this
* class.
* <br/><br/>
* If no custom message responsible for transporting an environment plugin implementation of "enviroment state" or
* "action description" is found in the environment plugin, MARLA will use default messages. Those messages simply
* serialize all it's contents. This implies that all classes, that are part of an environment plugin and may be
* contained in an "environment state" and/or an "action description" message, must implement the java.io.Serializable
* interface. This is an adequate practice for most network messages.
* <br/><br/>
* If you are, however, interested in <b>customizing</b> the serialization process (mostly if you expect noticeable
* compression and thus increased network throughput from doing so), you have to do 3 things:<br/><br/>
* 1. (optional) Provide a custom implementation for a message by deriving from NetworkMessage<br/>
* 2. (optional, and only if 1 was done) Tag the custom message with the @CustomMessage annotation<br/>
* 2. Implement the interface where there is optimization potential<br/><br/>
*
* Since the full object tree of the messages is serialized, you can do step 3 anywhere you want. But because the optimal
* serialization of an object tree can become a non-trivial task, we encourage plugins to implement logic related to
* that in a dedicated message class.
* <br/><br/>
* NOTICE: To be recognized by the MARLA plugin loader, you must tag those implementations with the Annotation
* @see EnvironmentPluginAPI.Contract.IEnvironmentState
* @see EnvironmentPluginAPI.Contract.IActionDescription
* @see EnvironmentPluginAPI.CustomNetworkMessages.CustomMessage
* @see java.io.Externalizable
*
*/
public abstract class NetworkMessage implements Serializable {
public static byte[] EMPTY_BYTES = new byte[]{};
public static byte[] ZERO = new byte[]{0};
public static byte[] ONE = new byte[]{1};
public static byte[] TWO = new byte[]{2};
private int clientId;
/**
* creates a basic message.
*
* @param clientId see getClientID()
*/
public NetworkMessage(int clientId) {
this.clientId = clientId;
}
protected void setClientId(int clientId) {
this.clientId = clientId;
}
/**
* in client mode: The MARLA-Client id from which the message was sent<br/>
* in server mode: The MARLA-Client id to which the message is targeted
*
* @return the client id. -1 if unknown, 0..Integer.MAX_VALUE else
*/
public int getClientId() {
return clientId;
}
/**
* Concatenates the given byte arrays to a new one.
*
* @param first the front part, != null
* @param second the rear part, != null
* @return a byte array of length a.length + b.length containing the values of a in the front and the values of b in
* the rear. not null
*/
public static byte[] concatByteArrays(byte[] first, byte[] second) {
byte[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
}