/** * Set SimObject data from a managed class * * @param data value * @param objectId object id * @throws IOException IO Error * @throws IllegalDataDefinition if the class of <code>data</code> was not registered (see {@link * #registerClass(Class)}) * @throws NullPointerException if data is null */ public <T> void setSimObjectData(T data, int objectId) throws IOException, IllegalDataDefinition { Class<?> cl = data.getClass(); if (!definitionIds.containsKey(cl)) throw new IllegalDataDefinition("Class not defined in this wrapper."); int dataLen = classDataSize(cl); DataWrapper dw = new DataWrapper(dataLen); wrap(data, dw); int defId = ((Integer) definitionIds.get(cl)).intValue(); simConnect.setDataOnSimObject(defId, objectId, false, 1, dw); }
/** * Request SimObject data from a class. The class must be registered before using this method (see * {@link #registerClass(Class)}). See {@link SimConnect#requestDataOnSimObject(Enum, Enum, int, * SimConnectPeriod)} for more informations on this simconnect request. * * @param cl class to use. must be registered * @param objectId object ID, or {@link SimConnectConstants#OBJECT_ID_USER} for user aircraft * @param requestId forced request id * @param period period, see {@link SimConnectPeriod} * @param onlyWhenChanged set to true if you want to receive data only if it was changed * @return ID of request (here <code>requestId</code>) * @throws IOException simconnect error * @throws IllegalDataDefinition if this class was not registered */ public int requestSimObjectData( Class<?> cl, int requestId, int objectId, SimConnectPeriod period, boolean onlyWhenChanged) throws IOException, IllegalDataDefinition { if (!definitionIds.containsKey(cl)) throw new IllegalDataDefinition("Class not defined. call registerClass() first"); int defId = ((Integer) definitionIds.get(cl)).intValue(); int flags = onlyWhenChanged ? SimConnectConstants.DATA_REQUEST_FLAG_CHANGED : SimConnectConstants.DATA_REQUEST_FLAG_DEFAULT; simConnect.requestDataOnSimObject(requestId, defId, objectId, period, flags, 0, 0, 0); return requestId; }
/** * Register a class prior to use. This is mandatory before calling {@link * #requestSimObjectData(Class, int, SimConnectPeriod, boolean)} or {@link * #unwrap(RecvSimObjectData)} or {@link #setSimObjectData(Object, int)} * * @param c class to use * @param dataDefID force data definition ID * @return data definition ID (here <code>dataDefID</code>) * @throws IllegalDataDefinition if the class <code>c</code> contains invalid or non-mappable * fields * @throws IOException SimConnect IO Errors */ public int registerClass(int dataDefID, Class<?> c) throws IOException, IllegalDataDefinition { // // don't do it twice if (definitionIds.containsKey(c)) { return definitionIds.get(c).intValue(); } int fieldAdded = 0; for (Field f : c.getDeclaredFields()) { if (f.isAnnotationPresent(FlightSimData.class)) { // register field FlightSimData fsd = f.getAnnotation(FlightSimData.class); String variable = fsd.variable(); String units = fsd.units(); // determinate field simconnect type from its class SimConnectDataType type = SimConnectDataType.INVALID; if (f.getType().equals(Float.class) || f.getType().equals(float.class)) type = SimConnectDataType.FLOAT32; else if (f.getType().equals(Double.class) || f.getType().equals(double.class)) type = SimConnectDataType.FLOAT64; else if (f.getType().equals(Integer.class) || f.getType().equals(int.class)) type = SimConnectDataType.INT32; else if (f.getType().equals(Long.class) || f.getType().equals(long.class)) type = SimConnectDataType.INT64; else if (f.getType().equals(Boolean.class) || f.getType().equals(boolean.class)) type = SimConnectDataType.INT32; else if (f.getType().equals(Short.class) || f.getType().equals(short.class)) type = SimConnectDataType.INT32; else if (f.getType().equals(LatLonAlt.class)) type = SimConnectDataType.LATLONALT; else if (f.getType().equals(XYZ.class)) type = SimConnectDataType.XYZ; else if (f.getType().equals(Waypoint.class)) type = SimConnectDataType.WAYPOINT; else if (f.getType().equals(MarkerState.class)) type = SimConnectDataType.MARKERSTATE; else if (f.getType().equals(String.class)) { int len = fsd.stringWidth(); switch (len) { case 8: type = SimConnectDataType.STRING8; break; case 32: type = SimConnectDataType.STRING32; break; case 64: type = SimConnectDataType.STRING64; break; case 128: type = SimConnectDataType.STRING128; break; case 256: type = SimConnectDataType.STRING256; break; case 260: type = SimConnectDataType.STRING260; break; default: throw new IllegalDataDefinition("Invalid string length (" + len + ")"); } } if (type == SimConnectDataType.INVALID) { throw new IllegalDataDefinition("Invalid field type (" + f.getType().getName() + ")"); } // // build simconnect data def simConnect.addToDataDefinition(dataDefID, variable, units, type); fieldAdded++; } } // register it if we had something to write if (fieldAdded > 0) definitionIds.put(c, dataDefID); return requestID; }