|
|
## Prequisite Information
|
|
|
|
|
|
\<apiname\> is a placeholder for a suitable name of the new API.
|
|
|
|
|
|
E.g., the PolygonAPI is used to access the geometry of ScenarioElements, whereas the VadereAPI accesses Vadere-specific properties of, for example, ScenarioElements.
|
|
|
|
|
|
## Required New Files
|
|
|
|
|
|
The following files have to be created:
|
|
|
|
|
|
- in _VadereManager/src/org/vadere/manager/traci/commandHandler_:
|
|
|
|
|
|
<apiname>CommandHandlerTest.java
|
|
|
|
|
|
- in VadereManager/tests/org/vadere/manager/traci/commandHandler/annotation:
|
|
|
|
|
|
<apiname>Handler.java
|
|
|
<apiname>Handlers.java
|
|
|
|
|
|
- in _VadereManager/src/org/vadere/manager/traci/commandHandler/variables_:
|
|
|
|
|
|
<apiname>CommandHandlerTest.java
|
|
|
|
|
|
Furthermore, a new API also requires new unit tests, which are implemented
|
|
|
|
|
|
- in _VadereManager/tests/org/vadere/manager/traci/commandHandler_:
|
|
|
|
|
|
<apiname>CommandHandlerTest.java
|
|
|
|
|
|
## Required New Code Lines in Existing Files
|
|
|
|
|
|
APINAME should be replaced with \<apiname\> in capital letters.
|
|
|
|
|
|
- in _VadereManager/src/org/vadere/manager/traci/commandHandler/CommandExecutor.java_:
|
|
|
|
|
|
The following lines have to be added in the CommandExecutor constructor.
|
|
|
|
|
|
```
|
|
|
cmdMap.put(TraCICmd.GET_APINAME_VALUE.id, ApiNameCommandHandler.instance::processGet);
|
|
|
cmdMap.put(TraCICmd.SET_APINAME_STATE.id, ApiNameCommandHandler.instance::processSet);
|
|
|
cmdMap.put(TraCICmd.SUB_APINAME_VARIABLE.id, ApiNameCommandHandler.instance::processValueSub);
|
|
|
```
|
|
|
|
|
|
- in _VadereManager/src/org/vadere/manager/traci/TraCICmd.java_:
|
|
|
|
|
|
The following are new fields of the Enum.
|
|
|
|
|
|
```
|
|
|
GET_APINAME_VALUE(0xf0, CmdType.VALUE_GET),
|
|
|
RESPONSE_GET_APINAME_VALUE(0xf1, CmdType.RESPONSE),
|
|
|
SET_APINAME_STATE(0xf2, CmdType.VALUE_SET),
|
|
|
SUB_APINAME_VARIABLE(0xf3, CmdType.VALUE_SUB),
|
|
|
RESPONSE_SUB_APINAME_VARIABLE(0xf4, CmdType.RESPONSE),
|
|
|
```
|
|
|
|
|
|
Replace the id byte with a suitable value.
|
|
|
|
|
|
## Implement New Commands
|
|
|
|
|
|
In the _\<apiname\>CommandHandler.java_, create an annotated method like the following:
|
|
|
|
|
|
|
|
|
@ApiNameHandler(cmd = TraCICmd.GET_PERSON_VALUE, var = ApiNameVar.COMMAND_NAME, name = "commandName")
|
|
|
public TraCICommand process_commandName(TraCIGetCommand cmd, RemoteManager remoteManager) {
|
|
|
remoteManager.accessState((manager, state) -> {
|
|
|
// every interaction with the simulation state is done inside here
|
|
|
});
|
|
|
return cmd;
|
|
|
}
|
|
|
|
|
|
In _\<apiname\>Var.java_, create a new field of the Enum like the following:
|
|
|
|
|
|
COMMAND_NAME(0x00, TraCIDataType.STRING)
|
|
|
|
|
|
Then change the id (0x00).
|
|
|
|
|
|
## Usefull Starting Points to Implement New API
|
|
|
|
|
|
The following classes can be copied, pasted and adapted/extended according to the new API.
|
|
|
|
|
|
### Implementation of the \<apiname\>CommandHandler.java
|
|
|
|
|
|
```
|
|
|
package org.vadere.manager.traci.commandHandler;
|
|
|
|
|
|
import org.vadere.annotation.traci.client.TraCIApi;
|
|
|
import org.vadere.manager.RemoteManager;
|
|
|
import org.vadere.manager.traci.TraCICmd;
|
|
|
import org.vadere.manager.traci.TraCIDataType;
|
|
|
import org.vadere.manager.traci.commandHandler.annotation.ApiNameHandler;
|
|
|
import org.vadere.manager.traci.commandHandler.annotation.ApiNameHandlers;
|
|
|
import org.vadere.manager.traci.commandHandler.variables.ApiNameVar;
|
|
|
import org.vadere.manager.traci.commands.TraCICommand;
|
|
|
import org.vadere.manager.traci.commands.TraCIGetCommand;
|
|
|
import org.vadere.manager.traci.commands.TraCISetCommand;
|
|
|
import org.vadere.manager.traci.respons.TraCIGetResponse;
|
|
|
import org.vadere.util.logging.Logger;
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Handel GET/SET {@link org.vadere.manager.traci.commands.TraCICommand}s for the ApiName API
|
|
|
*/
|
|
|
@TraCIApi(
|
|
|
name = "ApiNameAPI",
|
|
|
nameShort = "api",
|
|
|
singleAnnotation = ApiNameHandler.class,
|
|
|
multipleAnnotation = ApiNameHandlers.class,
|
|
|
cmdEnum = TraCICmd.class,
|
|
|
varEnum = ApiNameVar.class
|
|
|
)
|
|
|
public class ApiNameCommandHandler extends CommandHandler<ApiNameVar> {
|
|
|
|
|
|
public static ApiNameCommandHandler instance;
|
|
|
|
|
|
private static Logger logger = Logger.getLogger(ApiNameCommandHandler.class);
|
|
|
|
|
|
static {
|
|
|
instance = new ApiNameCommandHandler();
|
|
|
}
|
|
|
|
|
|
private ApiNameCommandHandler() {
|
|
|
super();
|
|
|
init(ApiNameHandler.class, ApiNameHandlers.class);
|
|
|
}
|
|
|
|
|
|
public static void main(String[] arg) {
|
|
|
ApiNameCommandHandler h = instance;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected void init_HandlerSingle(Method m) {
|
|
|
ApiNameHandler an = m.getAnnotation(ApiNameHandler.class);
|
|
|
putHandler(an.cmd(), an.var(), m);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected void init_HandlerMult(Method m) {
|
|
|
ApiNameHandler[] ans = m.getAnnotation(ApiNameHandlers.class).value();
|
|
|
for (ApiNameHandler a : ans) {
|
|
|
putHandler(a.cmd(), a.var(), m);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public TraCIGetResponse responseOK(TraCIDataType responseDataType, Object responseData) {
|
|
|
return responseOK(responseDataType, responseData, TraCICmd.GET_PERSON_VALUE, TraCICmd.RESPONSE_GET_APINAME_VALUE);
|
|
|
}
|
|
|
|
|
|
public TraCIGetResponse responseERR(String err) {
|
|
|
return responseERR(err, TraCICmd.GET_APINAME_VALUE, TraCICmd.RESPONSE_GET_APINAME_VALUE);
|
|
|
}
|
|
|
|
|
|
@ApiNameHandler(cmd = TraCICmd.GET_PERSON_VALUE, var = ApiNameVar.COMMAND_NAME, name = "commandName")
|
|
|
public TraCICommand process_commandName(TraCIGetCommand cmd, RemoteManager remoteManager) {
|
|
|
remoteManager.accessState((manager, state) -> {
|
|
|
// every interaction with the simulation state is done inside here
|
|
|
});
|
|
|
return cmd;
|
|
|
}
|
|
|
|
|
|
|
|
|
public TraCICommand process_NotImplemented(TraCIGetCommand cmd, RemoteManager remoteManager) {
|
|
|
return super.process_NotImplemented(cmd, remoteManager);
|
|
|
}
|
|
|
|
|
|
public TraCICommand processValueSub(TraCICommand rawCmd, RemoteManager remoteManager) {
|
|
|
return processValueSub(rawCmd, remoteManager, this::processGet,
|
|
|
TraCICmd.GET_APINAME_VALUE, TraCICmd.RESPONSE_SUB_APINAME_VARIABLE);
|
|
|
}
|
|
|
|
|
|
public TraCICommand processGet(TraCICommand cmd, RemoteManager remoteManager) {
|
|
|
TraCIGetCommand getCmd = (TraCIGetCommand) cmd;
|
|
|
|
|
|
ApiNameVar var = ApiNameVar.fromId(getCmd.getVariableIdentifier());
|
|
|
Method m = getHandler(getCmd.getTraCICmd(), var);
|
|
|
|
|
|
return invokeHandler(m, this, getCmd, remoteManager);
|
|
|
}
|
|
|
|
|
|
public TraCICommand processSet(TraCICommand cmd, RemoteManager remoteManager) {
|
|
|
TraCISetCommand setCmd = (TraCISetCommand) cmd;
|
|
|
|
|
|
ApiNameVar var = ApiNameVar.fromId(setCmd.getVariableId());
|
|
|
Method m = getHandler(setCmd.getTraCICmd(), var);
|
|
|
|
|
|
return invokeHandler(m, this, setCmd, remoteManager);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### Implementation of the \<apiname\>Var.java
|
|
|
|
|
|
```
|
|
|
package org.vadere.manager.traci.commandHandler.variables;
|
|
|
|
|
|
import org.vadere.manager.TraCIException;
|
|
|
import org.vadere.manager.traci.TraCIDataType;
|
|
|
|
|
|
public enum ApiNameVar {
|
|
|
|
|
|
COMMAND_NAME(0x00, TraCIDataType.STRING), // get
|
|
|
// ... more variables
|
|
|
;
|
|
|
|
|
|
|
|
|
public int id;
|
|
|
public TraCIDataType type;
|
|
|
|
|
|
ApiNameVar(int id, TraCIDataType retVal) {
|
|
|
this.id = id;
|
|
|
this.type = retVal;
|
|
|
}
|
|
|
|
|
|
|
|
|
public static ApiNameVar fromId(int id){
|
|
|
for(ApiNameVar var : values()){
|
|
|
if (var.id == id)
|
|
|
return var;
|
|
|
}
|
|
|
throw new TraCIException(String.format("No apiname var found with id: %02X", id));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public String toString() {
|
|
|
return "ApiNameVar{" +
|
|
|
name() +
|
|
|
": id=" + id +
|
|
|
", type=" + type +
|
|
|
'}';
|
|
|
}
|
|
|
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### Implementation of the \<apiname\>Handler.java and \<apiname\>Handlers.java
|
|
|
|
|
|
```
|
|
|
package org.vadere.manager.traci.commandHandler.annotation;
|
|
|
|
|
|
import org.vadere.manager.traci.TraCICmd;
|
|
|
import org.vadere.manager.traci.commandHandler.variables.ApiNameVar;
|
|
|
import org.vadere.manager.traci.commandHandler.variables.ControlVar;
|
|
|
|
|
|
import java.lang.annotation.ElementType;
|
|
|
import java.lang.annotation.Repeatable;
|
|
|
import java.lang.annotation.Retention;
|
|
|
import java.lang.annotation.RetentionPolicy;
|
|
|
import java.lang.annotation.Target;
|
|
|
|
|
|
@Target(ElementType.METHOD)
|
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
|
@Repeatable(ApiNameHandlers.class)
|
|
|
|
|
|
public @interface ApiNameHandler {
|
|
|
TraCICmd cmd();
|
|
|
ApiNameVar var() default ApiNameVar.COMMAND_NAME;
|
|
|
String name(); // name of client function.
|
|
|
}
|
|
|
```
|
|
|
|
|
|
```
|
|
|
package org.vadere.manager.traci.commandHandler.annotation;
|
|
|
|
|
|
import java.lang.annotation.ElementType;
|
|
|
import java.lang.annotation.Retention;
|
|
|
import java.lang.annotation.RetentionPolicy;
|
|
|
import java.lang.annotation.Target;
|
|
|
|
|
|
@Target(ElementType.METHOD)
|
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
|
public @interface ApiNameHandlers {
|
|
|
ApiNameHandler[] value();
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### Implementation of the \<apiname\>HandlerTest.java
|
|
|
|
|
|
```
|
|
|
package org.vadere.manager.traci.commandHandler;
|
|
|
|
|
|
import org.junit.Test;
|
|
|
|
|
|
|
|
|
public class ApiNameCommandHandlerTest extends CommandHandlerTest {
|
|
|
|
|
|
private ApiNameCommandHandler apiNameCmdHandler = ApiNameCommandHandler.instance;
|
|
|
|
|
|
@Test
|
|
|
public void process_commandName() {
|
|
|
// implement tests
|
|
|
}
|
|
|
}
|
|
|
``` |
|
|
\ No newline at end of file |