/*******************************************************************************
* Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*
* Contributors:
* Pavel Savara & Flemming N. Larsen
* - Initial implementation
*******************************************************************************/
package net.sf.robocode.recording;
import net.sf.robocode.battle.BattleProperties;
import net.sf.robocode.security.HiddenAccess;
import net.sf.robocode.serialization.IXmlSerializable;
import net.sf.robocode.serialization.SerializableOptions;
import net.sf.robocode.serialization.XmlReader;
import net.sf.robocode.serialization.XmlWriter;
import robocode.BattleResults;
import robocode.BattleRules;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @author Pavel Savara (original)
* @author Flemming N. Larsen (original)
*/
public class BattleRecordInfo implements Serializable, IXmlSerializable {
private static final long serialVersionUID = 1L;
public int robotCount;
public int roundsCount;
public BattleRules battleRules;
public Integer[] turnsInRounds;
public List<BattleResults> results;
public void writeXml(XmlWriter writer, SerializableOptions options) throws IOException {
writer.startElement("recordInfo"); {
writer.writeAttribute("robotCount", robotCount);
writer.writeAttribute("roundsCount", roundsCount);
if (!options.skipVersion) {
writer.writeAttribute("ver", serialVersionUID);
}
writer.startElement("rules"); {
writer.writeAttribute("battlefieldWidth", battleRules.getBattlefieldWidth());
writer.writeAttribute("battlefieldHeight", battleRules.getBattlefieldHeight());
writer.writeAttribute("numRounds", battleRules.getNumRounds());
writer.writeAttribute("gunCoolingRate", battleRules.getGunCoolingRate(), options.trimPrecision);
writer.writeAttribute("inactivityTime", battleRules.getInactivityTime());
writer.writeAttribute("ver", serialVersionUID);
}
writer.endElement();
writer.startElement("rounds"); {
for (int n : turnsInRounds) {
writer.startElement("turns"); {
writer.writeAttribute("value", Integer.toString(n));
}
writer.endElement();
}
}
writer.endElement();
if (results != null) {
writer.startElement("results"); {
for (BattleResults result : results) {
new BattleResultsWrapper(result).writeXml(writer, options);
}
}
writer.endElement();
}
}
writer.endElement();
}
public XmlReader.Element readXml(XmlReader reader) {
return reader.expect("recordInfo", new XmlReader.Element() {
public IXmlSerializable read(XmlReader reader) {
final BattleRecordInfo recordInfo = new BattleRecordInfo();
reader.expect("robotCount", new XmlReader.Attribute() {
public void read(String value) {
recordInfo.robotCount = Integer.parseInt(value);
}
});
reader.expect("roundsCount", new XmlReader.Attribute() {
public void read(String value) {
recordInfo.roundsCount = Integer.parseInt(value);
}
});
new BattleRulesWrapper(recordInfo).readXml(reader);
reader.expect("rounds", new XmlReader.ListElement() {
final ArrayList<Integer> ints = new ArrayList<Integer>();
public IXmlSerializable read(XmlReader reader) {
// prototype
return new IntValue("turns");
}
public void add(IXmlSerializable child) {
ints.add(((IntValue) child).intValue);
}
public void close() {
recordInfo.turnsInRounds = new Integer[ints.size()];
ints.toArray(recordInfo.turnsInRounds);
}
});
reader.expect("results", new XmlReader.ListElement() {
public IXmlSerializable read(XmlReader reader) {
recordInfo.results = new ArrayList<BattleResults>();
// prototype
return new BattleResultsWrapper();
}
public void add(IXmlSerializable child) {
recordInfo.results.add((BattleResults) child);
}
public void close() {}
});
return recordInfo;
}
});
}
public class IntValue implements IXmlSerializable {
IntValue(String name) {
this.name = name;
}
private final String name;
public int intValue;
public void writeXml(XmlWriter writer, SerializableOptions options) throws IOException {}
public XmlReader.Element readXml(XmlReader reader) {
return reader.expect(name, new XmlReader.Element() {
public IXmlSerializable read(XmlReader reader) {
final IntValue recordInfo = new IntValue(name);
reader.expect("value", new XmlReader.Attribute() {
public void read(String value) {
recordInfo.intValue = Integer.parseInt(value);
}
});
return recordInfo;
}
});
}
}
/**
* This class is used for wrapping a robocode.BattleResults object and provides
* methods for XML serialization that are hidden from the BattleResults class,
* which is a part of the public Robot API for Robocode.
*
* @author Flemming N. Larsen (original)
*/
class BattleResultsWrapper extends BattleResults implements IXmlSerializable {
private static final long serialVersionUID = BattleResults.serialVersionUID;
public BattleResultsWrapper() {
super(null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
public BattleResultsWrapper(BattleResults results) {
super(results.getTeamLeaderName(), results.getRank(), results.getScore(), results.getSurvival(),
results.getLastSurvivorBonus(), results.getBulletDamage(), results.getBulletDamageBonus(),
results.getRamDamage(), results.getRamDamageBonus(), results.getFirsts(), results.getSeconds(),
results.getThirds());
}
public void writeXml(XmlWriter writer, SerializableOptions options) throws IOException {
writer.startElement("result"); {
writer.writeAttribute("teamLeaderName", teamLeaderName);
writer.writeAttribute("rank", rank);
writer.writeAttribute("score", score, options.trimPrecision);
writer.writeAttribute("survival", survival, options.trimPrecision);
writer.writeAttribute("lastSurvivorBonus", lastSurvivorBonus, options.trimPrecision);
writer.writeAttribute("bulletDamage", bulletDamage, options.trimPrecision);
writer.writeAttribute("bulletDamageBonus", bulletDamageBonus, options.trimPrecision);
writer.writeAttribute("ramDamage", ramDamage, options.trimPrecision);
writer.writeAttribute("ramDamageBonus", ramDamageBonus, options.trimPrecision);
writer.writeAttribute("firsts", firsts);
writer.writeAttribute("seconds", seconds);
writer.writeAttribute("thirds", thirds);
if (!options.skipVersion) {
writer.writeAttribute("ver", serialVersionUID);
}
}
writer.endElement();
}
public XmlReader.Element readXml(XmlReader reader) {
return reader.expect("result", new XmlReader.Element() {
public IXmlSerializable read(XmlReader reader) {
final BattleResultsWrapper rules = new BattleResultsWrapper();
reader.expect("teamLeaderName", new XmlReader.Attribute() {
public void read(String value) {
rules.teamLeaderName = value;
}
});
reader.expect("rank", new XmlReader.Attribute() {
public void read(String value) {
rules.rank = Integer.parseInt(value);
}
});
reader.expect("score", new XmlReader.Attribute() {
public void read(String value) {
rules.score = Double.parseDouble(value);
}
});
reader.expect("survival", new XmlReader.Attribute() {
public void read(String value) {
rules.survival = Double.parseDouble(value);
}
});
reader.expect("lastSurvivorBonus", new XmlReader.Attribute() {
public void read(String value) {
rules.lastSurvivorBonus = Double.parseDouble(value);
}
});
reader.expect("bulletDamage", new XmlReader.Attribute() {
public void read(String value) {
rules.bulletDamage = Double.parseDouble(value);
}
});
reader.expect("bulletDamageBonus", new XmlReader.Attribute() {
public void read(String value) {
rules.bulletDamageBonus = Double.parseDouble(value);
}
});
reader.expect("ramDamage", new XmlReader.Attribute() {
public void read(String value) {
rules.ramDamage = Double.parseDouble(value);
}
});
reader.expect("ramDamageBonus", new XmlReader.Attribute() {
public void read(String value) {
rules.ramDamageBonus = Double.parseDouble(value);
}
});
reader.expect("firsts", new XmlReader.Attribute() {
public void read(String value) {
rules.firsts = Integer.parseInt(value);
}
});
reader.expect("seconds", new XmlReader.Attribute() {
public void read(String value) {
rules.seconds = Integer.parseInt(value);
}
});
reader.expect("thirds", new XmlReader.Attribute() {
public void read(String value) {
rules.thirds = Integer.parseInt(value);
}
});
return rules;
}
});
}
}
private static class BattleRulesWrapper implements IXmlSerializable {
BattleRulesWrapper(BattleRecordInfo recinfo) {
this.recinfo = recinfo;
}
final BattleProperties props = new BattleProperties();
final BattleRecordInfo recinfo;
public void writeXml(XmlWriter writer, SerializableOptions options) throws IOException {}
public XmlReader.Element readXml(XmlReader reader) {
return reader.expect("rules",
new XmlReader.ElementClose() {
public IXmlSerializable read(XmlReader reader) {
reader.expect("battlefieldWidth", new XmlReader.Attribute() {
public void read(String value) {
props.setBattlefieldWidth(Integer.parseInt(value));
}
});
reader.expect("battlefieldHeight", new XmlReader.Attribute() {
public void read(String value) {
props.setBattlefieldHeight(Integer.parseInt(value));
}
});
reader.expect("numRounds", new XmlReader.Attribute() {
public void read(String value) {
props.setNumRounds(Integer.parseInt(value));
}
});
reader.expect("inactivityTime", new XmlReader.Attribute() {
public void read(String value) {
props.setInactivityTime(Integer.parseInt(value));
}
});
reader.expect("gunCoolingRate", new XmlReader.Attribute() {
public void read(String value) {
props.setGunCoolingRate(Double.parseDouble(value));
}
});
return BattleRulesWrapper.this;
}
public void close() {
recinfo.battleRules = HiddenAccess.createRules(props.getBattlefieldWidth(),
props.getBattlefieldHeight(), props.getNumRounds(), props.getGunCoolingRate(),
props.getInactivityTime(), props.getHideEnemyNames());
}
});
}
}
}