Advertisement
Guest User

Untitled

a guest
Nov 21st, 2019
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.94 KB | None | 0 0
  1. import java.util.HashMap;
  2. import java.util.LinkedList;
  3. import java.util.List;
  4. import java.util.Map;
  5.  
  6. public class ChainReaction implements ChainReactionInterface {
  7.     private final Map<Integer, Node> nodes = new HashMap<>();
  8.     private volatile int workingThreads = 0;
  9.     private volatile int initializations = 0;
  10.     private volatile boolean simulationStarted = false;
  11.     private DamagePropagationInterface damagePropagationInterface;
  12.  
  13.     @Override
  14.     public synchronized void addObject(int id) {
  15.         nodes.put(id, new Node(id));
  16.     }
  17.  
  18.     @Override
  19.     public synchronized void neighbour(int idA, int idB) {
  20.         if (idA != idB) {
  21.             Node nodeA = nodes.get(idA);
  22.             Node nodeB = nodes.get(idB);
  23.  
  24.             nodeA.addNeighbor(nodeB);
  25.             nodeB.addNeighbor(nodeA);
  26.         }
  27.     }
  28.  
  29.     @Override
  30.     public boolean resultReady() {
  31.         return simulationStarted && initializations == 0 && workingThreads == 0;
  32.     }
  33.  
  34.     @Override
  35.     public boolean isDestroyed(int id) {
  36.         return nodes.get(id).isDestroyed();
  37.     }
  38.  
  39.     @Override
  40.     public synchronized void setDamagePropagator(DamagePropagationInterface dpi) {
  41.         this.damagePropagationInterface = dpi;
  42.     }
  43.  
  44.     @Override
  45.     public void destroyed(int id) {
  46.         synchronized (this) {
  47.             initializations++;
  48.         }
  49.         simulationStarted = true;
  50.  
  51.         Node node = nodes.get(id);
  52.         boolean destroyed = false;
  53.         if (node.isLive()) {
  54.             synchronized (node) {
  55.                 if (node.isLive()) {
  56.                     node.destroy();
  57.                     destroyed = true;
  58.                 }
  59.             }
  60.         }
  61.  
  62.         if (destroyed) {
  63.             findNeighboursToDestroy(node).stream()
  64.                     .map(DestroyingRunnable::new)
  65.                     .forEach(this::startTrackedThread);
  66.         }
  67.  
  68.         synchronized (this) {
  69.             initializations--;
  70.         }
  71.     }
  72.  
  73.     private List<Node> findNeighboursToDestroy(Node node) {
  74.         List<Node> neighboursToDestroy = new LinkedList<>();
  75.         for (Node neighbour : node.getNeighbours()) {
  76.             if (neighbour.isLive()) {
  77.                 synchronized (neighbour) {
  78.                     if (neighbour.isLive() && damagePropagationInterface.destroyedBy(node.id, neighbour.id)) {
  79.                         neighbour.markToDestroy();
  80.                         neighboursToDestroy.add(neighbour);
  81.                     }
  82.                 }
  83.             }
  84.         }
  85.         return neighboursToDestroy;
  86.     }
  87.  
  88.     private void startTrackedThread(DestroyingRunnable runnable) {
  89.         new Thread(new TrackingRunnable(runnable)).start();
  90.     }
  91.  
  92.     private class DestroyingRunnable implements Runnable {
  93.         private final Node node;
  94.  
  95.         private DestroyingRunnable(Node node) {
  96.             this.node = node;
  97.         }
  98.  
  99.         @Override
  100.         public void run() {
  101.             node.destroy();
  102.  
  103.             List<Node> neighboursToProcess = findNeighboursToDestroy(node);
  104.             if (!neighboursToProcess.isEmpty()) {
  105.                 neighboursToProcess.subList(1, neighboursToProcess.size()).stream()
  106.                         .map(DestroyingRunnable::new)
  107.                         .forEach(ChainReaction.this::startTrackedThread);
  108.  
  109.                 new DestroyingRunnable(neighboursToProcess.get(0)).run();
  110.             }
  111.         }
  112.     }
  113.  
  114.     private class TrackingRunnable implements Runnable {
  115.         private final Runnable runnable;
  116.  
  117.         private TrackingRunnable(Runnable runnable) {
  118.             this.runnable = runnable;
  119.         }
  120.  
  121.         @Override
  122.         public void run() {
  123.             try {
  124.                 synchronized (ChainReaction.this) {
  125.                     workingThreads++;
  126.                 }
  127.                 runnable.run();
  128.             } finally {
  129.                 synchronized (ChainReaction.this) {
  130.                     workingThreads--;
  131.                 }
  132.             }
  133.         }
  134.     }
  135.  
  136.     private static class Node {
  137.         private final int id;
  138.         private final List<Node> neighbours = new LinkedList<>();
  139.         private volatile NodeState state = NodeState.LIVE;
  140.  
  141.         private Node(int id) {
  142.             this.id = id;
  143.         }
  144.  
  145.         private List<Node> getNeighbours() {
  146.             return neighbours;
  147.         }
  148.  
  149.         private void addNeighbor(Node neighbor) {
  150.             neighbours.add(neighbor);
  151.         }
  152.  
  153.         private boolean isLive() {
  154.             return state == NodeState.LIVE;
  155.         }
  156.  
  157.         private boolean isDestroyed() {
  158.             return state == NodeState.DESTROYED;
  159.         }
  160.  
  161.         private void markToDestroy() {
  162.             state = NodeState.MARKED_TO_DESTROY;
  163.         }
  164.  
  165.         private void destroy() {
  166.             System.out.println("DESTROYED " + id);
  167.             state = NodeState.DESTROYED;
  168.         }
  169.  
  170.         private enum NodeState {
  171.             LIVE, MARKED_TO_DESTROY, DESTROYED
  172.         }
  173.     }
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement