package mods.eln.sim;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent;
import mods.eln.misc.Utils;
import mods.eln.sim.mna.RootSystem;
import mods.eln.sim.mna.component.Component;
import mods.eln.sim.mna.state.State;
import mods.eln.sim.process.destruct.IDestructable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Simulator /* ,IPacketHandler */ {
public RootSystem mna;
private ArrayList<IProcess> slowProcessList;
private List<IProcess> slowPreProcessList;
private ArrayList<IProcess> electricalProcessList;
private ArrayList<IProcess> thermalFastProcessList, thermalSlowProcessList;
private ArrayList<ThermalConnection> thermalFastConnectionList, thermalSlowConnectionList;
private ArrayList<ThermalLoad> thermalFastLoadList, thermalSlowLoadList;
private Set<IDestructable> destructableSet;
boolean run;
public double electricalPeriod, thermalPeriod, callPeriod;
int electricalInterSystemOverSampling;
int nodeCount = 0;
int simplifyCMin = 0;
int simplifyCMax = 100;
double avgTickTime = 0;
long electricalNsStack = 0, thermalFastNsStack = 0, slowNsStack = 0, thermalSlowNsStack = 0;
double timeout = 0;
double electricalTimeout = 0;
double thermalTimeout = 0;
private int printTimeCounter = 0;
public ArrayList<IProcess> getElectricalProcessList() {
return electricalProcessList;
}
public double getMinimalThermalC(double Rs, double Rp) {
return thermalPeriod * 3 / ((1 / (1 / Rp + 1 / Rs)));
}
public boolean checkThermalLoad(double thermalRs, double thermalRp, double thermalC) {
if (thermalC < getMinimalThermalC(thermalRs, thermalRp)) {
Utils.println("checkThermalLoad ERROR");
while (true)
;
// return false;
}
return true;
}
public Simulator(double callPeriod, double electricalPeriod, int electricalInterSystemOverSampling, double thermalPeriod) {
this.callPeriod = callPeriod;
this.electricalPeriod = electricalPeriod;
this.electricalInterSystemOverSampling = electricalInterSystemOverSampling;
this.thermalPeriod = thermalPeriod;
FMLCommonHandler.instance().bus().register(this);
mna = new RootSystem(electricalPeriod, electricalInterSystemOverSampling);
slowProcessList = new ArrayList<IProcess>();
slowPreProcessList = new ArrayList<IProcess>();
electricalProcessList = new ArrayList<IProcess>();
// electricalConnectionList = new ArrayList<ElectricalConnection>();
// electricalLoadList = new ArrayList<ElectricalLoad>();
thermalFastProcessList = new ArrayList<IProcess>();
thermalSlowProcessList = new ArrayList<IProcess>();
thermalFastConnectionList = new ArrayList<ThermalConnection>();
thermalFastLoadList = new ArrayList<ThermalLoad>();
thermalSlowConnectionList = new ArrayList<ThermalConnection>();
thermalSlowLoadList = new ArrayList<ThermalLoad>();
destructableSet = new HashSet<IDestructable>();
run = false;
}
public void init() {
nodeCount = 0;
mna = new RootSystem(electricalPeriod, electricalInterSystemOverSampling);
slowProcessList.clear();
slowPreProcessList.clear();
electricalProcessList.clear();
// electricalConnectionList.clear();
// electricalLoadList.clear();
thermalFastProcessList.clear();
thermalSlowProcessList.clear();
thermalFastConnectionList.clear();
thermalFastLoadList.clear();
thermalSlowConnectionList.clear();
thermalSlowLoadList.clear();
destructableSet.clear();
run = true;
}
public void stop() {
nodeCount = 0;
mna = null;
slowProcessList.clear();
slowPreProcessList.clear();
electricalProcessList.clear();
// electricalConnectionList.clear();
// electricalLoadList.clear();
thermalFastProcessList.clear();
thermalSlowProcessList.clear();
thermalFastConnectionList.clear();
thermalFastLoadList.clear();
thermalSlowConnectionList.clear();
thermalSlowLoadList.clear();
destructableSet.clear();
run = false;
}
public void addElectricalComponent(Component c) {
if (c != null) {
mna.addComponent(c);
// electricalConnectionList.add(connection);
// connection.L1.electricalConnections.add(connection);
// connection.L2.electricalConnections.add(connection);
}
}
public void removeElectricalComponent(Component c) {
if (c != null) {
mna.removeComponent(c);
// electricalConnectionList.remove(connection);
// connection.L1.electricalConnections.remove(connection);
// connection.L2.electricalConnections.remove(connection);
}
}
public void addThermalConnection(ThermalConnection connection) {
if (connection != null) {
if (connection.L1.isSlow() == connection.L2.isSlow()) {
if (connection.L1.isSlow())
thermalSlowConnectionList.add(connection);
else
thermalFastConnectionList.add(connection);
} else {
Utils.println("***** addThermalConnection ERROR ****");
}
}
}
public void removeThermalConnection(ThermalConnection connection) {
if (connection != null) {
thermalSlowConnectionList.remove(connection);
thermalFastConnectionList.remove(connection);
}
}
public void addElectricalLoad(State load) {
if (load != null) {
mna.addState(load);
}
}
public void removeElectricalLoad(State load) {
if (load != null) {
mna.removeState(load);
}
}
public void addThermalLoad(ThermalLoad load) {
if (load != null) {
if (load.isSlow())
thermalSlowLoadList.add(load);
else
thermalFastLoadList.add(load);
}
}
public void removeThermalLoad(ThermalLoad load) {
if (load != null) {
thermalSlowLoadList.remove(load);
thermalFastLoadList.remove(load);
}
}
public void addSlowProcess(IProcess process) {
if (process != null) slowProcessList.add(process);
}
public void removeSlowProcess(IProcess process) {
if (process != null) slowProcessList.remove(process);
}
public void addSlowPreProcess(IProcess process) {
if (process != null) slowPreProcessList.add(process);
}
public void removeSlowPreProcess(IProcess process) {
if (process != null) slowPreProcessList.remove(process);
}
public void addElectricalProcess(IProcess process) {
if (process != null) electricalProcessList.add(process);
}
public void removeElectricalProcess(IProcess process) {
if (process != null) electricalProcessList.remove(process);
}
public void addThermalFastProcess(IProcess process) {
if (process != null) thermalFastProcessList.add(process);
}
public void removeThermalFastProcess(IProcess process) {
if (process != null) thermalFastProcessList.remove(process);
}
public void addThermalSlowProcess(IProcess process) {
if (process != null) thermalSlowProcessList.add(process);
}
public void removeThermalSlowProcess(IProcess process) {
if (process != null) thermalSlowProcessList.remove(process);
}
public void addAllElectricalConnection(Iterable<ElectricalConnection> connection) {
if (connection != null) {
for (ElectricalConnection c : connection) {
addElectricalComponent(c);
}
}
}
public void removeAllElectricalConnection(Iterable<ElectricalConnection> connection) {
if (connection != null) {
for (ElectricalConnection c : connection) {
removeElectricalComponent(c);
}
}
}
public void addAllElectricalComponent(Iterable<Component> cList) {
if (cList != null) {
for (Component c : cList) {
addElectricalComponent(c);
}
}
}
public void removeAllElectricalComponent(Iterable<Component> cList) {
if (cList != null) {
for (Component c : cList) {
removeElectricalComponent(c);
}
}
}
public void addAllThermalConnection(Iterable<ThermalConnection> connection) {
if (connection != null) {
for (ThermalConnection c : connection) {
addThermalConnection(c);
}
}
}
public void removeAllThermalConnection(Iterable<ThermalConnection> connection) {
if (connection != null) {
for (ThermalConnection c : connection) {
removeThermalConnection(c);
}
}
}
public void addAllElectricalLoad(Iterable<ElectricalLoad> load) {
if (load != null) {
for (ElectricalLoad l : load) {
addElectricalLoad(l);
}
}
}
public void removeAllElectricalLoad(Iterable<ElectricalLoad> load) {
if (load != null) {
for (ElectricalLoad l : load) {
removeElectricalLoad(l);
}
}
}
public void addAllThermalLoad(Iterable<ThermalLoad> load) {
if (load != null) {
for (ThermalLoad c : load) {
addThermalLoad(c);
}
}
}
public void removeAllThermalLoad(Iterable<ThermalLoad> load) {
if (load != null) {
for (ThermalLoad c : load) {
removeThermalLoad(c);
}
}
}
public void addAllSlowProcess(ArrayList<IProcess> process) {
if (process != null) slowProcessList.addAll(process);
}
public void removeAllSlowProcess(ArrayList<IProcess> process) {
if (process != null) slowProcessList.removeAll(process);
}
public void addAllElectricalProcess(ArrayList<IProcess> process) {
if (process != null) electricalProcessList.addAll(process);
}
public void removeAllElectricalProcess(ArrayList<IProcess> process) {
if (process != null) electricalProcessList.removeAll(process);
}
public void addAllThermalFastProcess(ArrayList<IProcess> process) {
if (process != null) thermalFastProcessList.addAll(process);
}
public void removeAllThermalFastProcess(ArrayList<IProcess> process) {
if (process != null) thermalFastProcessList.removeAll(process);
}
public void addAllThermalSlowProcess(ArrayList<IProcess> process) {
if (process != null) thermalSlowProcessList.addAll(process);
}
public void removeAllThermalSlowProcess(ArrayList<IProcess> process) {
if (process != null) thermalSlowProcessList.removeAll(process);
}
// private ArrayList<Double> conectionSerialConductance = new ArrayList<Double>();
public boolean pleaseCrash = false;
@SubscribeEvent
public void tick(ServerTickEvent event) {
if (event.phase != Phase.START) return;
if (pleaseCrash) throw new StackOverflowError();
long stackStart;
long startTime = System.nanoTime();
for (Object o : slowPreProcessList.toArray()) {
IProcess process = (IProcess) o;
process.process(1.0 / 20);
}
timeout += callPeriod;
while (timeout > 0) {
if (timeout < electricalTimeout && timeout < thermalTimeout) {
thermalTimeout -= timeout;
electricalTimeout -= timeout;
timeout = 0;
break;
}
double dt;
if (electricalTimeout <= thermalTimeout) {
dt = electricalTimeout;
electricalTimeout += electricalPeriod;
stackStart = System.nanoTime();
mna.step();
for (IProcess p : electricalProcessList) {
p.process(electricalPeriod);
}
electricalNsStack += System.nanoTime() - stackStart;
} else {
dt = thermalTimeout;
thermalTimeout += thermalPeriod;
stackStart = System.nanoTime();
// / Utils.print("*");
thermalStep(thermalPeriod, thermalFastConnectionList, thermalFastProcessList, thermalFastLoadList);
thermalFastNsStack += System.nanoTime() - stackStart;
}
thermalTimeout -= dt;
electricalTimeout -= dt;
timeout -= dt;
}
{
stackStart = System.nanoTime();
thermalStep(0.05, thermalSlowConnectionList, thermalSlowProcessList, thermalSlowLoadList);
thermalSlowNsStack += System.nanoTime() - stackStart;
}
stackStart = System.nanoTime();
for (Object o : slowProcessList.toArray()) {
IProcess process = (IProcess) o;
process.process(0.05);
}
for (IDestructable d : destructableSet) {
d.destructImpl();
}
destructableSet.clear();
slowNsStack += System.nanoTime() - stackStart;
avgTickTime += 1.0 / 20 * ((int) (System.nanoTime() - startTime) / 1000);
/*stackStart = System.nanoTime();
for (int idx = 0; idx < 100; idx++) {
ByteArrayOutputStream bos = new ByteArrayOutputStream(8);
DataOutputStream stream = new DataOutputStream(bos);
try {
for (int idx2 = 0; idx2 < 10; idx2++)
stream.writeInt(idx2+0xAAAAAAAA);
} catch (IOException e) {
e.printStackTrace();
}
MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
for (Object obj : server.getConfigurationManager().playerEntityList) {
EntityPlayerMP player = (EntityPlayerMP) obj;
WorldServer worldServer = (WorldServer) MinecraftServer.getServer().worldServerForDimension(player.dimension);
PlayerManager playerManager = worldServer.getPlayerManager();
Utils.sendPacketToClient(bos, player);
}
//S3FPacketCustomPayload packet = new S3FPacketCustomPayload(Eln.channelName, bos.toByteArray());
//Eln.instance.eventChannel.sendToAll(new FMLProxyPacket(packet));
}
Utils.println((System.nanoTime() - stackStart) / 1000);*/
if (++printTimeCounter == 20) {
printTimeCounter = 0;
electricalNsStack /= 20;
thermalFastNsStack /= 20;
thermalSlowNsStack /= 20;
slowNsStack /= 20;
Utils.println("ticks " + new DecimalFormat("#").format((int) avgTickTime) + " us" + " E " + electricalNsStack / 1000 + " TF " + thermalFastNsStack / 1000 + " TS " + thermalSlowNsStack / 1000 + " S " + slowNsStack / 1000
+ " " + mna.getSubSystemCount() + " SS"
+ " " + electricalProcessList.size() + " EP"
+ " " + thermalFastLoadList.size() + " TFL"
+ " " + thermalFastConnectionList.size() + " TFC"
+ " " + thermalFastProcessList.size() + " TFP"
+ " " + thermalSlowLoadList.size() + " TSL"
+ " " + thermalSlowConnectionList.size() + " TSC"
+ " " + thermalSlowProcessList.size() + " TSP"
+ " " + slowProcessList.size() + " SP"
);
avgTickTime = 0;
electricalNsStack = 0;
thermalFastNsStack = 0;
slowNsStack = 0;
thermalSlowNsStack = 0;
}
}
public boolean isRegistred(ElectricalLoad load) {
return mna.isRegistred(load);
}
void thermalStep(double dt, Iterable<ThermalConnection> connectionList, Iterable<IProcess> processList, Iterable<ThermalLoad> loadList) {
for (ThermalConnection c : connectionList) {
double i;
i = (c.L2.Tc - c.L1.Tc) / ((c.L2.Rs + c.L1.Rs));
c.L1.PcTemp += i;
c.L2.PcTemp -= i;
c.L1.PrsTemp += Math.abs(i);
c.L2.PrsTemp += Math.abs(i);
}
if (processList != null) {
for (IProcess process : processList) {
process.process(dt);
}
}
for (ThermalLoad load : loadList) {
load.PcTemp -= load.Tc / load.Rp;
load.Tc += load.PcTemp * dt / load.C;
load.Pc = load.PcTemp;
load.Prs = load.PrsTemp;
load.Psp = load.PspTemp;
load.PcTemp = 0;
load.PrsTemp = 0;
load.PspTemp = 0;
}
}
}