Skip to content
This repository has been archived by the owner on Mar 30, 2018. It is now read-only.

Commit

Permalink
Moved all those degeneration and repair threads, etc. to one worker
Browse files Browse the repository at this point in the history
thread. This should limit those evil thread lockups.
  • Loading branch information
mkalus committed Jan 23, 2012
1 parent 3a404a0 commit ee2e8c2
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 120 deletions.
4 changes: 2 additions & 2 deletions src/main/java/de/beimax/simplespleef/game/GameStandard.java
Expand Up @@ -39,7 +39,7 @@
import de.beimax.simplespleef.game.arenarestoring.ArenaRestorer;
import de.beimax.simplespleef.game.arenarestoring.HardArenaRestorer;
import de.beimax.simplespleef.game.arenarestoring.SoftRestorer;
import de.beimax.simplespleef.game.floortracking.FloorThread;
import de.beimax.simplespleef.game.floortracking.FloorWorker;
import de.beimax.simplespleef.game.floortracking.FloorTracker;
import de.beimax.simplespleef.util.*;

Expand Down Expand Up @@ -1447,7 +1447,7 @@ protected void saveArena() {
if (floorTracker == null) // create floor tracker, if needed
floorTracker = new FloorTracker();
// create a new tracker/restorer
floorTracker.addFloorThread((FloorThread) arenaRestorer);
floorTracker.addFloorThread((FloorWorker) arenaRestorer);
}
}

Expand Down
Expand Up @@ -156,7 +156,7 @@ public void run() {
* called by updatePlayer to update a block
* @param block
*/
public synchronized void updateBlock(Block block) {
public void updateBlock(Block block) {
if (block == null) return; //no NPEs
if (block.getType() != Material.AIR &&
(checkedBlock == null || block.getX() != checkedBlock.getX() || block.getY() != checkedBlock.getY() || block.getZ() != checkedBlock.getZ())) { // ignore air...
Expand Down
Expand Up @@ -11,15 +11,15 @@

import de.beimax.simplespleef.SimpleSpleef;
import de.beimax.simplespleef.game.Game;
import de.beimax.simplespleef.game.floortracking.FloorThread;
import de.beimax.simplespleef.game.floortracking.FloorWorker;
import de.beimax.simplespleef.util.Cuboid;
import de.beimax.simplespleef.util.SerializableBlockData;

/**
* @author mkalus
*
*/
public class SoftRestorer implements ArenaRestorer, FloorThread {
public class SoftRestorer implements ArenaRestorer, FloorWorker {
/**
* flag to stop thread - actually starts restoration
*/
Expand All @@ -34,31 +34,22 @@ public class SoftRestorer implements ArenaRestorer, FloorThread {
* cuboid to store/restore
*/
private Cuboid cuboid;

/**
* thread has finished restoring?
*/
private boolean isStopped = false;

/**
* keeps the data of the changed blocks
*/
private LinkedList<BlockChange> changedBlocks;

/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
if (game == null || cuboid == null) return; //ignore invalid stuff

// wait until game has stopped
while (!startRestoring)
try {
Thread.sleep(500); // sleep for half a second before doing anything else
} catch (InterruptedException e) {}
}

/* (non-Javadoc)
* @see de.beimax.simplespleef.game.floortracking.FloorThread#initializeThread(de.beimax.simplespleef.game.Game, java.util.List)
*/
@Override
public void initializeThread(Game game, List<Block> floor) {
public void initialize(Game game, List<Block> floor) {
//Do nothing
}

Expand Down Expand Up @@ -116,6 +107,22 @@ private class BlockChange {
private Location location;
private SerializableBlockData blockData;
}

@Override
public void tick() {
if (game == null || cuboid == null) return; //ignore invalid stuff

// wait for the restoration process to start
if (!startRestoring) return;

restoreArena();
}

@Override
public boolean isStopped() {
return isStopped;
}


/**
* restorer thread
Expand All @@ -130,23 +137,24 @@ public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {}

synchronized (changedBlocks) {
// cycle through changes and restore
for (BlockChange changedBlock : changedBlocks) {

for (BlockChange changedBlock : changedBlocks) {
synchronized (changedBlock) {
Block block = changedBlock.location.getBlock();
block.setTypeId(changedBlock.blockData.getTypeId());
block.setData(changedBlock.blockData.getData());
// every 10 cycles, wait a little
if ((count++ % 10) == 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
}
block.setData(changedBlock.blockData.getData());
}

// every 10 cycles, wait a little
if ((count++ % 10) == 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}

// say that the thread has finished
isStopped = true;
//System.out.println("Finished");
// call game handler to finish the game off
SimpleSpleef.getGameHandler().gameOver(game);
Expand Down
Expand Up @@ -3,13 +3,17 @@
*/
package de.beimax.simplespleef.game.floortracking;

import java.util.List;

import org.bukkit.block.Block;

import de.beimax.simplespleef.game.Game;

/**
* @author mkalus
*
*/
public abstract class FloorBaseThread implements FloorThread {
public abstract class FloorBaseWorker implements FloorWorker {
/**
* seconds after which thread actually starts doing something
*/
Expand Down Expand Up @@ -38,57 +42,47 @@ public abstract class FloorBaseThread implements FloorThread {
/**
* flag to stop thread
*/
private boolean stop = false;
protected boolean stop = false;

/**
* Constructor
* @param startAfter
* @param tickTime
*/
public FloorBaseThread(int startAfter, int tickTime, FloorTracker tracker) {
public FloorBaseWorker(int startAfter, int tickTime, FloorTracker tracker) {
this.startAfter = startAfter;
this.tickTime = tickTime;
this.tracker = tracker;
}

/* (non-Javadoc)
* @see java.lang.Runnable#run()
/**
* initialize thread
*/
@Override
public void run() {
// first, wait for thread to start
public void initialize(Game game, List<Block> floor) {
startAt = System.currentTimeMillis() + ((long) startAfter * 1000);
while (!stop && System.currentTimeMillis() < startAt)
try {
Thread.sleep(500); // sleep for half a second before doing anything else
} catch (InterruptedException e) {}
nextTick = startAt;
}

/**
* do a tick
*/
@Override
public void tick() {
long now = System.currentTimeMillis();
// first, wait for worker to start and wait for the next tick
if (now < startAt || now < nextTick) return;

// now do the actual tick work
nextTick = System.currentTimeMillis();
while (!stop) {
while (!stop && System.currentTimeMillis() < nextTick)
try {
Thread.sleep(200); // sleep for a fifth of a second before doing anything else
} catch (InterruptedException e) {}
// execute tick
tick();
// update tick
nextTick = nextTick + ((long) tickTime * 1000);
}
executeTick();
// update tick
nextTick = nextTick + ((long) tickTime * 1000);
}

/**
* do a tick within the thread
*/
public abstract void tick();

/* (non-Javadoc)
* @see de.beimax.simplespleef.game.floortracking.FloorThread#stopTracking()
*/
@Override
public void stopTracking() {
stop = true;
}
public abstract void executeTick();

/**
* Notify the tracker about a block change - called by tick() when a block changes,
Expand All @@ -98,4 +92,9 @@ public void stopTracking() {
protected void notifyTracker(Block block, int oldType, byte oldData) {
tracker.notifyChangedBlock(block, oldType, oldData, this);
}

@Override
public boolean isStopped() {
return stop;
}
}
Expand Up @@ -17,7 +17,7 @@
* @author mkalus
*
*/
public class FloorDissolveThread extends FloorBaseThread {
public class FloorDissolveWorker extends FloorBaseWorker {
/**
* areas of the floor that are non-air
*/
Expand All @@ -28,15 +28,16 @@ public class FloorDissolveThread extends FloorBaseThread {
* @param startAfter
* @param tickTime
*/
public FloorDissolveThread(int startAfter, int tickTime, FloorTracker tracker) {
public FloorDissolveWorker(int startAfter, int tickTime, FloorTracker tracker) {
super(startAfter, tickTime, tracker);
}

/* (non-Javadoc)
* @see de.beimax.simplespleef.game.floortracking.FloorThread#initializeThread(de.beimax.simplespleef.game.Game, java.util.List)
*/
@Override
public synchronized void initializeThread(Game game, List<Block> floor) {
public void initialize(Game game, List<Block> floor) {
super.initialize(game, floor);
for (Block block : floor) {
if (block == null) continue; // no NPEs
if (block.getType() != Material.AIR) // add location to nonAir locations
Expand All @@ -49,35 +50,31 @@ public synchronized void initializeThread(Game game, List<Block> floor) {
*/
@Override
public void updateBlock(Block block, int oldType, byte oldData) {
synchronized (block) {
if (block == null) return; // no NPEs
Location loc = block.getLocation();
if (nonAir.contains(loc)) {
if (block.getType() == Material.AIR) // dissolve to air
nonAir.remove(loc); // remove because it is air anyway
} else if (block.getType() != Material.AIR) // non air added - add to dissolveable parts of arena
nonAir.add(loc);
}
if (block == null) return; // no NPEs
Location loc = block.getLocation();
if (nonAir.contains(loc)) {
if (block.getType() == Material.AIR) // dissolve to air
nonAir.remove(loc); // remove because it is air anyway
} else if (block.getType() != Material.AIR) // non air added - add to dissolveable parts of arena
nonAir.add(loc);
}

/* (non-Javadoc)
* @see de.beimax.simplespleef.game.floortracking.FloorBaseThread#tick()
*/
@Override
public void tick() {
public void executeTick() {
// get a random entry
Location location = getRandomEntry();
if (location != null) {
Block block = location.getBlock();
// get old data
int oldType = block.getTypeId();
byte oldData = block.getData();
synchronized (block) {
// dissolve to air
block.setType(Material.AIR);
block.setData((byte) 0);
nonAir.remove(location);
}
// dissolve to air
block.setType(Material.AIR);
block.setData((byte) 0);
nonAir.remove(location);
// notify others
notifyTracker(block, oldType, oldData);
}
Expand All @@ -99,4 +96,9 @@ private Location getRandomEntry() {
return null; // if all locations have been dissolved
}

@Override
public void stopTracking() {
nonAir = null;
stop = true;
}
}

0 comments on commit ee2e8c2

Please sign in to comment.