@SuppressWarnings("rawtypes") public void updateFromData( Object obj, ByteBuffer byteBuffer, float[] floatValues, String[] stringValues, Indexes index) throws IllegalArgumentException, IllegalAccessException { Reporter r = null; if (BuildCraftCore.trackNetworkUsage) { if (!report.containsKey(clas.getName())) report.put(clas.getName(), new Reporter()); r = report.get(clas.getName()); r.clas = clas; } else r = new Reporter(); r.occurences++; for (Field f : shortFields) { f.setShort(obj, byteBuffer.readShort()); r.bytes += 2; r.dataInt += 1; } for (Field f : intFields) { f.setInt(obj, byteBuffer.readInt()); r.bytes += 4; r.dataInt += 1; } for (Field f : booleanFields) { f.setBoolean(obj, byteBuffer.readUnsignedByte() == 1); r.bytes += 1; r.dataInt += 1; } for (Field f : enumFields) { f.set(obj, ((Class) f.getGenericType()).getEnumConstants()[byteBuffer.readUnsignedByte()]); r.bytes += 1; r.dataInt += 1; } for (Field f : unsignedByteFields) { f.setInt(obj, byteBuffer.readUnsignedByte()); r.bytes += 1; r.dataInt += 1; } for (Field f : floatFields) { f.setFloat(obj, floatValues[index.floatIndex]); index.floatIndex++; r.bytes += 4; r.dataFloat += 1; } for (Field f : doubleFields) { f.setDouble(obj, floatValues[index.floatIndex]); index.floatIndex++; r.bytes += 4; r.dataFloat += 1; } for (Field f : stringFields) { f.set(obj, stringValues[index.stringIndex]); r.bytes += stringValues[index.stringIndex].length(); index.stringIndex++; r.dataString += 1; } for (ClassMapping c : objectFields) { boolean isNull = byteBuffer.readUnsignedByte() == 0; r.bytes += 1; r.dataInt += 1; if (isNull) { for (int i = 0; i < c.sizeBytes; ++i) byteBuffer.readUnsignedByte(); index.floatIndex += c.sizeFloat; index.stringIndex += c.sizeString; } else c.updateFromData(c.field.get(obj), byteBuffer, floatValues, stringValues, index); } for (Field f : doubleArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { ((double[]) f.get(obj))[i] = floatValues[index.floatIndex]; index.floatIndex++; r.bytes += 4; r.dataFloat += 1; } } for (Field f : shortArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { ((short[]) f.get(obj))[i] = byteBuffer.readShort(); r.bytes += 2; r.dataInt += 1; } } for (Field f : intArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { ((int[]) f.get(obj))[i] = byteBuffer.readInt(); r.bytes += 4; r.dataInt += 1; } } for (Field f : booleanArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { ((boolean[]) f.get(obj))[i] = byteBuffer.readUnsignedByte() == 1; r.bytes += 1; r.dataInt += 1; } } for (Field f : unsignedByteArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { ((int[]) f.get(obj))[i] = byteBuffer.readUnsignedByte(); r.bytes += 1; r.dataInt += 1; } } for (Field f : stringArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); String[] strs = (String[]) f.get(obj); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { strs[i] = stringValues[index.stringIndex]; r.bytes += stringValues[index.stringIndex].length(); index.stringIndex++; r.dataString += 1; } } for (ClassMapping c : objectArrayFields) { TileNetworkData updateAnnotation = c.field.getAnnotation(TileNetworkData.class); Object[] cpts = (Object[]) c.field.get(obj); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { boolean isNull = byteBuffer.readUnsignedByte() == 0; r.bytes += 1; r.dataInt += 1; if (isNull) { for (int j = 0; j < c.sizeBytes; ++j) byteBuffer.readUnsignedByte(); index.floatIndex += c.sizeFloat; index.stringIndex += c.sizeString; } else c.updateFromData(cpts[i], byteBuffer, floatValues, stringValues, index); } } }
@SuppressWarnings({"rawtypes", "unchecked"}) public ClassMapping(final Class<? extends Object> c) { clas = c; Field[] fields = c.getFields(); try { for (Field f : fields) { if (!isSynchronizedField(f)) continue; Type t = f.getGenericType(); // ??? take into account enumerations here! if (t instanceof Class && !((Class) t).isArray()) { Class fieldClass = (Class) t; if (fieldClass.equals(short.class)) { sizeBytes += 2; shortFields.add(f); } else if (fieldClass.equals(int.class)) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); if (updateAnnotation.intKind() == TileNetworkData.UNSIGNED_BYTE) { sizeBytes += 1; unsignedByteFields.add(f); } else { sizeBytes += 4; intFields.add(f); } } else if (fieldClass.equals(boolean.class)) { sizeBytes += 1; booleanFields.add(f); } else if (Enum.class.isAssignableFrom(fieldClass)) { sizeBytes += 1; enumFields.add(f); } else if (fieldClass.equals(String.class)) { sizeString++; stringFields.add(f); } else if (fieldClass.equals(float.class)) { sizeFloat++; floatFields.add(f); } else if (fieldClass.equals(double.class)) { sizeFloat++; doubleFields.add(f); } else { // ADD SOME SAFETY HERE - if we're not child of Object ClassMapping mapping = new ClassMapping(fieldClass); mapping.field = f; objectFields.add(mapping); sizeBytes += 1; // to catch null / not null. sizeBytes += mapping.sizeBytes; sizeFloat += mapping.sizeFloat; sizeString += mapping.sizeString; } } if (t instanceof Class && ((Class) t).isArray()) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); if (updateAnnotation.staticSize() == -1) throw new RuntimeException("arrays must be provided with an explicit size"); Class fieldClass = (Class) t; Class cptClass = fieldClass.getComponentType(); if (cptClass.equals(double.class)) { sizeFloat += updateAnnotation.staticSize(); doubleArrayFields.add(f); } else if (cptClass.equals(short.class)) { sizeBytes += updateAnnotation.staticSize() * 2; shortArrayFields.add(f); } else if (cptClass.equals(int.class)) { updateAnnotation = f.getAnnotation(TileNetworkData.class); if (updateAnnotation.intKind() == TileNetworkData.UNSIGNED_BYTE) { sizeBytes += updateAnnotation.staticSize(); unsignedByteArrayFields.add(f); } else { sizeBytes += updateAnnotation.staticSize() * 4; intArrayFields.add(f); } } else if (cptClass.equals(String.class)) { sizeString += updateAnnotation.staticSize(); stringArrayFields.add(f); } else if (cptClass.equals(boolean.class)) { sizeBytes += updateAnnotation.staticSize(); booleanArrayFields.add(f); } else { // ADD SOME SAFETY HERE - if we're not child of Object ClassMapping mapping = new ClassMapping(cptClass); mapping.field = f; objectArrayFields.add(mapping); sizeBytes += updateAnnotation.staticSize(); // to catch // null / // not null. sizeBytes += updateAnnotation.staticSize() * mapping.sizeBytes; sizeFloat += updateAnnotation.staticSize() * mapping.sizeFloat; sizeString += updateAnnotation.staticSize() * mapping.sizeString; } } } } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
@SuppressWarnings("rawtypes") public void setData( Object obj, ByteBuffer byteBuffer, float[] floatValues, String[] stringValues, Indexes index) throws IllegalArgumentException, IllegalAccessException { Reporter r = null; if (BuildCraftCore.trackNetworkUsage) { if (!report.containsKey(clas.getName())) report.put(clas.getName(), new Reporter()); r = report.get(clas.getName()); r.clas = clas; } else r = new Reporter(); r.occurences++; for (Field f : shortFields) { byteBuffer.writeShort(f.getShort(obj)); r.bytes += 2; r.dataInt += 1; } for (Field f : intFields) { byteBuffer.writeInt(f.getInt(obj)); r.bytes += 4; r.dataInt += 1; } for (Field f : booleanFields) { byteBuffer.writeUnsignedByte(f.getBoolean(obj) ? 1 : 0); r.bytes += 1; r.dataInt += 1; } for (Field f : enumFields) { byteBuffer.writeUnsignedByte(((Enum) f.get(obj)).ordinal()); r.bytes += 1; r.dataInt += 1; } for (Field f : unsignedByteFields) { byteBuffer.writeUnsignedByte(f.getInt(obj)); r.bytes += 1; r.dataInt += 1; } for (Field f : floatFields) { floatValues[index.floatIndex] = f.getFloat(obj); index.floatIndex++; r.bytes += 4; r.dataFloat += 1; } for (Field f : doubleFields) { floatValues[index.floatIndex] = (float) f.getDouble(obj); index.floatIndex++; r.bytes += 4; r.dataFloat += 1; } for (Field f : stringFields) { stringValues[index.stringIndex] = (String) f.get(obj); r.bytes += stringValues[index.stringIndex].length(); index.stringIndex++; r.dataString += 1; } for (ClassMapping c : objectFields) { Object cpt = c.field.get(obj); if (cpt == null) { byteBuffer.writeUnsignedByte(0); for (int i = 0; i < c.sizeBytes; ++i) { byteBuffer.writeUnsignedByte(0); r.bytes += 1; r.dataInt += 1; } index.floatIndex += c.sizeFloat; index.stringIndex += c.sizeString; } else { byteBuffer.writeUnsignedByte(1); r.bytes += 1; r.dataInt += 1; c.setData(cpt, byteBuffer, floatValues, stringValues, index); } } for (Field f : doubleArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { floatValues[index.floatIndex] = (float) ((double[]) f.get(obj))[i]; index.floatIndex++; r.bytes += 4; r.dataFloat += 1; } } for (Field f : shortArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { byteBuffer.writeShort(((short[]) f.get(obj))[i]); r.bytes += 2; r.dataInt += 1; } } for (Field f : intArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { byteBuffer.writeInt(((int[]) f.get(obj))[i]); r.bytes += 4; r.dataInt += 1; } } for (Field f : booleanArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { byteBuffer.writeUnsignedByte(((boolean[]) f.get(obj))[i] ? 1 : 0); r.bytes += 1; r.dataInt += 1; } } for (Field f : unsignedByteFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { byteBuffer.writeUnsignedByte(((int[]) f.get(obj))[i]); r.bytes += 1; r.dataInt += 1; } } for (Field f : stringArrayFields) { TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); for (int i = 0; i < updateAnnotation.staticSize(); ++i) { stringValues[index.stringIndex] = ((String[]) f.get(obj))[i]; r.bytes += stringValues[index.stringIndex].length(); index.stringIndex++; r.dataString += 1; } } for (ClassMapping c : objectArrayFields) { TileNetworkData updateAnnotation = c.field.getAnnotation(TileNetworkData.class); Object[] cpts = (Object[]) c.field.get(obj); for (int i = 0; i < updateAnnotation.staticSize(); ++i) if (cpts[i] == null) { byteBuffer.writeUnsignedByte(0); for (int j = 0; j < c.sizeBytes; ++j) { byteBuffer.writeUnsignedByte(0); r.bytes += 1; r.dataInt += 1; } index.floatIndex += c.sizeFloat; index.stringIndex += c.sizeString; } else { byteBuffer.writeUnsignedByte(1); r.bytes += 1; r.dataInt += 1; c.setData(cpts[i], byteBuffer, floatValues, stringValues, index); } } }