Skip to content

Commit

Permalink
Simplify dirty state propogation by keeping consist
Browse files Browse the repository at this point in the history
  • Loading branch information
cam72cam committed Oct 4, 2023
1 parent 4f2c45c commit 1c61d9a
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -229,17 +229,23 @@ public final void setCoupledUUID(CouplerType coupler, UUID id) {
.sendToObserving(this);
}

EntityCoupleableRollingStock coupled = id != null ? findByUUID(id) : null;

switch (coupler) {
case FRONT:
coupledFront = id;
if (coupledFront == null) {
lastKnownFront = null;
} else if (coupled != null){
lastKnownFront = new Vec3i(coupled.getPosition());
}
break;
case BACK:
coupledBack = id;
if (coupledBack == null) {
lastKnownRear = null;
} else if (coupled != null){
lastKnownFront = new Vec3i(coupled.getPosition());
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ public static Map<UUID, SimulationState> iterate(Map<UUID, SimulationState> stat
// Propagate dirty flag
boolean canBeUnloaded = consist.stream().allMatch(p -> p.state.velocity == 0 && state.forcesNewtons() < state.frictionNewtons());
consist.forEach(p -> p.state.canBeUnloaded = canBeUnloaded);
List<UUID> ids = consist.stream().map(x -> x.state.config.id).collect(Collectors.toList());
consist.forEach(p -> p.state.consist = ids);

boolean dirty = consist.stream().anyMatch(p -> p.state.dirty);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,73 +74,16 @@ public static void simulate(World world) {
state.update(entity);
stateMaps.get(i).put(entity.getUUID(), state);
if (state.dirty) {
dirty.add(entity.getUUID());
dirty.addAll(state.consist);
}
}
}
if (i < 40) {
stateMaps.get(i).get(entity.getUUID()).dirty = true;
dirty.addAll(stateMaps.get(i).get(entity.getUUID()).consist);
}
}
}

// This finds the full list of dirty stock that needs to be recomputed.
// It is *highly* optimized to run in under 0.5ms per 100 pieces of stock.
// It could be tuned further, but I suspect this is good enough for now
for (int i = 0; i < allStock.size(); i++) {
int lastSize = dirty.size();

for (UUID uuid : stateMaps.get(0).keySet()) {
boolean isDirty = dirty.contains(uuid);

// This makes an assumption that stock only has a single value for a coupler in 40 ticks
// Worst case is the potential for a missed dirty flag which will interact with the Mismatch check
UUID front = null;
UUID rear = null;

for (Map<UUID, SimulationState> stateMap : stateMaps) {
if (front != null && rear != null) {
break;
}

SimulationState state = stateMap.get(uuid);
if (state != null) {
if (front == null && state.interactingFront != null) {
front = state.interactingFront;
}
if (rear == null && state.interactingRear != null) {
rear = state.interactingRear;
}
}
}

if (!isDirty) {
if (front != null && dirty.contains(front)) {
dirty.add(uuid);
isDirty = true;
}
}
if (!isDirty) {
if (rear != null && dirty.contains(rear)) {
dirty.add(uuid);
isDirty = true;
}
}

if (isDirty) {
if (front != null && !dirty.contains(front)) {
dirty.add(front);
}
if (rear != null && !dirty.contains(rear)) {
dirty.add(rear);
}
}
}
if (lastSize == dirty.size()) {
break;
}
}

for (UUID uuid : dirty) {
SimulationState state = stateMaps.get(0).get(uuid);
if (state != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class SimulationState {
public boolean frontPulling;
public boolean rearPushing;
public boolean rearPulling;
public List<UUID> consist;

public static class Configuration {
public UUID id;
Expand Down Expand Up @@ -199,6 +200,8 @@ public SimulationState(EntityCoupleableRollingStock stock) {

calculateBlockCollisions(Collections.emptyList());
blocksToBreak = Collections.emptyList();

consist = Collections.singletonList(config.id);
}

private SimulationState(SimulationState prev) {
Expand Down Expand Up @@ -229,6 +232,8 @@ private SimulationState(SimulationState prev) {
interferingResistance = prev.interferingResistance;
blocksToBreak = Collections.emptyList();
directResistance = prev.directResistance;

consist = prev.consist;
}

public void calculateCouplerPositions() {
Expand Down

0 comments on commit 1c61d9a

Please sign in to comment.