From 8438d5780c6593b77cd34a225137890f8a936c46 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Sun, 9 Mar 2014 14:06:58 -0500 Subject: [PATCH] Changing threading from per-region to per-world Remove complicated AsyncManager system --- pom.xml | 4 +- .../PlayerControlledMovementComponent.java | 6 +- .../flowpowered/engine/FlowClientImpl.java | 2 +- .../com/flowpowered/engine/FlowEngine.java | 3 +- .../flowpowered/engine/FlowEngineImpl.java | 33 +- .../flowpowered/engine/FlowServerImpl.java | 9 +- .../engine/entity/EntityManager.java | 2 +- .../engine/geo/region/FlowRegion.java | 50 +-- .../engine/geo/region/RegionSource.java | 9 +- .../geo/world/FlowServerWorldManager.java | 12 +- .../engine/geo/world/FlowWorld.java | 31 +- .../engine/geo/world/FlowWorldManager.java | 20 +- .../flowpowered/engine/player/FlowPlayer.java | 74 +++- .../engine/render/FlowRenderer.java | 11 +- .../engine/scheduler/FlowScheduler.java | 31 +- .../engine/scheduler/FlowTaskManager.java | 9 +- .../IllegalWorldTickSequenceException.java} | 16 +- .../engine/scheduler/MainThread.java | 347 +----------------- .../scheduler/MarkedNamedThreadFactory.java | 10 +- .../engine/scheduler/WorldThread.java | 166 +++++++++ .../scheduler/WorldTickStage.java} | 84 +---- .../engine/scheduler/render/RenderThread.java | 4 + .../engine/util/thread/AsyncManager.java | 41 --- .../util/thread/CompleteAsyncManager.java | 27 -- .../util/thread/CopySnapshotManager.java | 31 -- .../util/thread/DynamicUpdateManager.java | 40 -- .../engine/util/thread/FinalizeManager.java | 32 -- .../engine/util/thread/LightingManager.java | 33 -- .../thread/LoggingThreadPoolExecutor.java | 5 + .../engine/util/thread/PhysicsManager.java | 33 -- .../util/thread/PreSnapshotManager.java | 33 -- .../engine/util/thread/StartTickManager.java | 33 -- .../thread/coretasks/CopySnapshotTask.java | 50 --- .../util/thread/coretasks/FinalizeTask.java | 45 --- .../coretasks/GlobalDynamicUpdatesTask.java | 57 --- .../thread/coretasks/GlobalPhysicsTask.java | 50 --- .../util/thread/coretasks/LightingTask.java | 50 --- .../coretasks/LocalDynamicUpdatesTask.java | 51 --- .../LocalManagerRunnableFactory.java | 36 -- .../thread/coretasks/LocalPhysicsTask.java | 45 --- .../thread/coretasks/ManagerRunnable.java | 63 ---- .../coretasks/ManagerRunnableFactory.java | 37 -- .../thread/coretasks/PreSnapshotTask.java | 45 --- .../SequencedManagerRunnableFactory.java | 36 -- .../util/thread/coretasks/StartTickTask.java | 55 --- .../snapshotable/SnapshotableHashMap.java | 3 - .../snapshotable/SnapshotableHashSet.java | 2 - .../SnapshotableLinkedHashMap.java | 2 - 48 files changed, 327 insertions(+), 1541 deletions(-) rename src/main/java/com/flowpowered/{api/scheduler/IllegalTickSequenceException.java => engine/scheduler/IllegalWorldTickSequenceException.java} (72%) create mode 100644 src/main/java/com/flowpowered/engine/scheduler/WorldThread.java rename src/main/java/com/flowpowered/{api/scheduler/TickStage.java => engine/scheduler/WorldTickStage.java} (62%) delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/AsyncManager.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/CompleteAsyncManager.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/CopySnapshotManager.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/DynamicUpdateManager.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/FinalizeManager.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/LightingManager.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/PhysicsManager.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/PreSnapshotManager.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/StartTickManager.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/CopySnapshotTask.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/FinalizeTask.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/GlobalDynamicUpdatesTask.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/GlobalPhysicsTask.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/LightingTask.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalDynamicUpdatesTask.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalManagerRunnableFactory.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalPhysicsTask.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/ManagerRunnable.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/ManagerRunnableFactory.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/PreSnapshotTask.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/SequencedManagerRunnableFactory.java delete mode 100644 src/main/java/com/flowpowered/engine/util/thread/coretasks/StartTickTask.java diff --git a/pom.xml b/pom.xml index 94de5f2..e3dd926 100644 --- a/pom.xml +++ b/pom.xml @@ -295,8 +295,8 @@ maven-compiler-plugin 3.1 - 1.7 - 1.7 + 1.8 + 1.8 -Xlint:all -Xlint:-path diff --git a/src/main/java/com/flowpowered/api/component/entity/PlayerControlledMovementComponent.java b/src/main/java/com/flowpowered/api/component/entity/PlayerControlledMovementComponent.java index d0a5cbb..f14edaf 100644 --- a/src/main/java/com/flowpowered/api/component/entity/PlayerControlledMovementComponent.java +++ b/src/main/java/com/flowpowered/api/component/entity/PlayerControlledMovementComponent.java @@ -42,15 +42,15 @@ public class PlayerControlledMovementComponent extends EntityComponent { @Override public void onTick(float dt) { - Player controller = this.controller; - if (controller == null) { + Player player = this.controller; + if (player == null) { return; } final Vector3f right = getRight(getOwner().getPhysics().getRotation()); final Vector3f up = getUp(getOwner().getPhysics().getRotation()); final Vector3f forward = getForward(getOwner().getPhysics().getRotation()); Vector3f translation = Vector3f.ZERO; - List input = controller.getInput(); + List input = player.getInput(); for (InputSnapshot snapshot : input) { if (!snapshot.isMouseGrabbed()) { continue; diff --git a/src/main/java/com/flowpowered/engine/FlowClientImpl.java b/src/main/java/com/flowpowered/engine/FlowClientImpl.java index fc0996c..67d1858 100644 --- a/src/main/java/com/flowpowered/engine/FlowClientImpl.java +++ b/src/main/java/com/flowpowered/engine/FlowClientImpl.java @@ -60,7 +60,7 @@ public void init() { // TEST CODE FlowWorld world = new FlowWorld(this, "TestWorld"); worldManager.addWorld(world); - getScheduler().addAsyncManager(world); + world.getThread().start(); } @Override diff --git a/src/main/java/com/flowpowered/engine/FlowEngine.java b/src/main/java/com/flowpowered/engine/FlowEngine.java index fc4d63d..ee0d9ec 100644 --- a/src/main/java/com/flowpowered/engine/FlowEngine.java +++ b/src/main/java/com/flowpowered/engine/FlowEngine.java @@ -29,7 +29,6 @@ import com.flowpowered.engine.geo.world.FlowWorldManager; import com.flowpowered.engine.plugins.FlowPluginManager; import com.flowpowered.engine.scheduler.FlowScheduler; -import com.flowpowered.engine.util.thread.snapshotable.SnapshotManager; public interface FlowEngine extends Engine { @@ -45,5 +44,5 @@ public interface FlowEngine extends Engine { @Override FlowWorldManager getWorldManager(); - SnapshotManager getSnapshotManager(); + void copySnapshot(); } diff --git a/src/main/java/com/flowpowered/engine/FlowEngineImpl.java b/src/main/java/com/flowpowered/engine/FlowEngineImpl.java index c9b7a40..bd118c9 100644 --- a/src/main/java/com/flowpowered/engine/FlowEngineImpl.java +++ b/src/main/java/com/flowpowered/engine/FlowEngineImpl.java @@ -35,23 +35,18 @@ import com.flowpowered.events.EventManager; import com.flowpowered.events.SimpleEventManager; import com.flowpowered.api.material.MaterialRegistry; -import com.flowpowered.api.scheduler.TickStage; import com.flowpowered.api.util.SyncedStringMap; -import com.flowpowered.commons.bit.ShortBitMask; import com.flowpowered.engine.filesystem.FlowFileSystem; import com.flowpowered.engine.scheduler.FlowScheduler; -import com.flowpowered.engine.util.thread.CopySnapshotManager; -import com.flowpowered.engine.util.thread.snapshotable.SnapshotManager; import uk.org.lidalia.slf4jext.Level; -public abstract class FlowEngineImpl implements FlowEngine, CopySnapshotManager { +public abstract class FlowEngineImpl implements FlowEngine { private final FlowApplication args; private final EventManager eventManager; private final FlowFileSystem fileSystem; private final FlowPluginManager pluginManager; private FlowScheduler scheduler; - protected final SnapshotManager snapshotManager = new SnapshotManager(); private SyncedStringMap itemMap; private PrintStream realSystemOut; private PrintStream realSystemErr; @@ -92,7 +87,6 @@ public void init() { public void start() { pluginManager.loadPlugins(); pluginManager.enablePlugins(); - scheduler.addAsyncManager(this); scheduler.startMainThread(); System.out.println("Engine started."); } @@ -140,29 +134,6 @@ public String getName() { return "Flow Engine"; } - @Override - public SnapshotManager getSnapshotManager() { - return snapshotManager; - } - - @Override - public void copySnapshotRun(int sequence) { - snapshotManager.copyAllSnapshots(); - } - - @Override - public boolean checkSequence(TickStage stage, int sequence) { - switch (stage) { - case SNAPSHOT: - return sequence == 0; - } - return true; - } - - private final ShortBitMask STAGES = TickStage.SNAPSHOT; - @Override - public ShortBitMask getTickStages() { - return STAGES; + public void copySnapshot() { } - } diff --git a/src/main/java/com/flowpowered/engine/FlowServerImpl.java b/src/main/java/com/flowpowered/engine/FlowServerImpl.java index d2da07d..28cdfe8 100644 --- a/src/main/java/com/flowpowered/engine/FlowServerImpl.java +++ b/src/main/java/com/flowpowered/engine/FlowServerImpl.java @@ -45,7 +45,7 @@ public class FlowServerImpl extends FlowEngineImpl implements FlowServer { public FlowServerImpl(FlowApplication args) { super(args); - players = new SnapshotableLinkedHashMap<>(snapshotManager); + players = new SnapshotableLinkedHashMap<>(null); worldManager = new FlowServerWorldManager(this); } @@ -111,7 +111,7 @@ public FlowPlayer getPlayer(String name, boolean exact) { @Override public FlowPlayer addPlayer(String name, FlowSession session) { - FlowPlayer player = new FlowPlayer(snapshotManager, session, name); + FlowPlayer player = new FlowPlayer(session, name); players.put(player.getName(), player); session.setPlayer(player); @@ -127,4 +127,9 @@ protected void addPlayer(FlowPlayer player) { public FlowServerWorldManager getWorldManager() { return worldManager; } + + @Override + public void copySnapshot() { + players.copySnapshot(); + } } diff --git a/src/main/java/com/flowpowered/engine/entity/EntityManager.java b/src/main/java/com/flowpowered/engine/entity/EntityManager.java index 64e3bef..af8543d 100644 --- a/src/main/java/com/flowpowered/engine/entity/EntityManager.java +++ b/src/main/java/com/flowpowered/engine/entity/EntityManager.java @@ -146,7 +146,7 @@ public void preSnapshotRun() { } /** - * Snapshots the manager and all the entities managed in the SNAPSHOT tickstage. + * Snapshots the manager and all the entities managed in the SNAPSHOT WorldTickStage. */ public void copyAllSnapshots() { for (FlowEntity e : entities.get().values()) { diff --git a/src/main/java/com/flowpowered/engine/geo/region/FlowRegion.java b/src/main/java/com/flowpowered/engine/geo/region/FlowRegion.java index a778922..9a71f91 100644 --- a/src/main/java/com/flowpowered/engine/geo/region/FlowRegion.java +++ b/src/main/java/com/flowpowered/engine/geo/region/FlowRegion.java @@ -38,10 +38,7 @@ import com.flowpowered.api.material.BlockMaterial; import com.flowpowered.api.material.block.BlockFace; import com.flowpowered.api.player.Player; -import com.flowpowered.api.scheduler.TickStage; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; -import com.flowpowered.commons.bit.ShortBitMask; -import com.flowpowered.commons.bit.ShortBitSet; import com.flowpowered.commons.store.block.impl.AtomicPaletteBlockStore; import com.flowpowered.engine.FlowEngine; import com.flowpowered.engine.entity.EntityManager; @@ -57,7 +54,7 @@ import com.flowpowered.engine.geo.world.FlowWorld; import com.flowpowered.engine.physics.FlowLinkedWorldInfo; import com.flowpowered.engine.util.math.ReactConverter; -import com.flowpowered.engine.util.thread.CompleteAsyncManager; +import com.flowpowered.engine.scheduler.WorldTickStage; import com.flowpowered.events.Cause; import com.flowpowered.math.GenericMath; import com.flowpowered.math.vector.Vector3f; @@ -65,7 +62,7 @@ import org.spout.physics.engine.DynamicsWorld; import org.spout.physics.engine.linked.LinkedDynamicsWorld; -public class FlowRegion extends Region implements CompleteAsyncManager { +public class FlowRegion extends Region { private final RegionGenerator generator; /** * Reference to the persistent ByteArrayArray that stores chunk data @@ -142,9 +139,9 @@ public FlowChunk getChunk(final int x, final int y, final int z, final LoadOptio // If we're not waiting, then we don't care because it's async anyways if (loadopt.isWait()) { if (loadopt.generateIfNeeded()) { - TickStage.checkStage(TickStage.noneOf(TickStage.SNAPSHOT, TickStage.PRESNAPSHOT, TickStage.LIGHTING)); + ((FlowWorld) getWorld().get()).getThread().checkStage(WorldTickStage.noneOf(WorldTickStage.COPY_SNAPSHOT, WorldTickStage.PRESNAPSHOT, WorldTickStage.LIGHTING)); } else if (loadopt.loadIfNeeded()) { - TickStage.checkStage(TickStage.noneOf(TickStage.SNAPSHOT)); + ((FlowWorld) getWorld().get()).getThread().checkStage(WorldTickStage.noneOf(WorldTickStage.COPY_SNAPSHOT)); } } @@ -166,7 +163,7 @@ public FlowChunk getChunk(final int x, final int y, final int z, final LoadOptio return loadOrGenChunkImmediately(x, y, z, loadopt); } - engine.getScheduler().runCoreAsyncTask(new Runnable() { + engine.getScheduler().getTaskManager().runCoreAsyncTask(new Runnable() { @Override public void run() { loadOrGenChunkImmediately(x, y, z, loadopt); @@ -464,24 +461,20 @@ public EntityManager getEntityManager() { return entityManager; } - @Override public void finalizeRun() { entityManager.finalizeRun(); } - @Override public void preSnapshotRun() { entityManager.preSnapshotRun(); } - @Override - public void copySnapshotRun(int sequence) { + public void copySnapshotRun() { entityManager.copyAllSnapshots(); chunks.set(live.get()); snapshot.update(this); } - @Override public void startTickRun(int stage, long delta) { if (stage == 0) { updateEntities(delta); @@ -514,37 +507,6 @@ private void updateDynamics(float dt) { } } - @Override - public void runPhysics(int sequence) { - } - - @Override - public void runDynamicUpdates(long threshold, int sequence) { - } - - @Override - public void runLighting(int sequence) { - } - - @Override - public boolean checkSequence(TickStage stage, int seqence) { - if (stage == TickStage.SNAPSHOT) { - return seqence == -1; - } - return seqence == -1; - } - - @Override - public long getFirstDynamicUpdateTime() { - return 0; - } - - private static ShortBitSet ALL_STAGES = new ShortBitSet(Short.MAX_VALUE); - @Override - public ShortBitMask getTickStages() { - return ALL_STAGES; - } - public FlowWorld getFlowWorld() { return (FlowWorld) super.getWorld().refresh(engine.getWorldManager()); } diff --git a/src/main/java/com/flowpowered/engine/geo/region/RegionSource.java b/src/main/java/com/flowpowered/engine/geo/region/RegionSource.java index 59345b5..80cec41 100644 --- a/src/main/java/com/flowpowered/engine/geo/region/RegionSource.java +++ b/src/main/java/com/flowpowered/engine/geo/region/RegionSource.java @@ -34,7 +34,7 @@ import com.flowpowered.api.geo.ServerWorld; import com.flowpowered.api.geo.World; import com.flowpowered.api.geo.cuboid.Region; -import com.flowpowered.api.scheduler.TickStage; +import com.flowpowered.engine.scheduler.WorldTickStage; import com.flowpowered.api.util.thread.annotation.DelayedWrite; import com.flowpowered.api.util.thread.annotation.LiveRead; import com.flowpowered.commons.concurrent.TripleIntObjectReferenceArrayMap; @@ -63,7 +63,7 @@ public RegionSource(FlowEngine engine, FlowWorld world) { @DelayedWrite public void removeRegion(final FlowRegion r) { - TickStage.checkStage(TickStage.SNAPSHOT); + ((FlowWorld) r.getWorld().get()).getThread().checkStage(WorldTickStage.COPY_SNAPSHOT); if (!r.getWorld().equals(world)) { throw new IllegalArgumentException("Provided region's world is not the same world as this RegionSource's world!"); @@ -88,8 +88,6 @@ public void removeRegion(final FlowRegion r) { return; } - world.getEngine().getScheduler().removeAsyncManager(r); - if (regionsLoaded.decrementAndGet() < 0) { engine.getLogger().info("Regions loaded dropped below zero"); } @@ -108,7 +106,7 @@ public void removeRegion(final FlowRegion r) { public FlowRegion getRegion(int x, int y, int z, LoadOption loadopt) { if (loadopt != LoadOption.NO_LOAD) { // TEST CODE how do we handle async chunk additions on the client? - //TickStage.checkStage(TickStage.noneOf(TickStage.SNAPSHOT)); + //TickStage.checkStage(TickStage.noneOf(TickStage.COPY_SNAPSHOT)); } FlowRegion region = loadedRegions.get(x, y, z); @@ -129,7 +127,6 @@ public FlowRegion getRegion(int x, int y, int z, LoadOption loadopt) { return current; } - world.getEngine().getScheduler().addAsyncManager(region); return region; } /** diff --git a/src/main/java/com/flowpowered/engine/geo/world/FlowServerWorldManager.java b/src/main/java/com/flowpowered/engine/geo/world/FlowServerWorldManager.java index 4099f89..6ea990c 100644 --- a/src/main/java/com/flowpowered/engine/geo/world/FlowServerWorldManager.java +++ b/src/main/java/com/flowpowered/engine/geo/world/FlowServerWorldManager.java @@ -66,11 +66,11 @@ public boolean accept(Path entry) throws IOException { @Override public FlowServerWorld loadWorld(String name, WorldGenerator generator) { - if (loadedWorlds.get().containsKey((name))) { - return loadedWorlds.get().get(name); + if (loadedWorlds.containsKey((name))) { + return loadedWorlds.get(name); } - if (loadedWorlds.getLive().containsKey(name)) { - return loadedWorlds.getLive().get(name); + if (loadedWorlds.containsKey(name)) { + return loadedWorlds.get(name); } if (generator == null) { @@ -85,7 +85,6 @@ public FlowServerWorld loadWorld(String name, WorldGenerator generator) { return oldWorld; } - engine.getScheduler().addAsyncManager(world); //getEventManager().callDelayedEvent(new WorldLoadEvent(world)); return world; } @@ -124,7 +123,7 @@ public WorldGenerator getDefaultGenerator() { @Override public boolean unloadWorld(String name, boolean save) { - return unloadWorld((ServerWorld) loadedWorlds.getLive().get(name), save); + return unloadWorld((ServerWorld) loadedWorlds.get(name), save); } @Override @@ -137,7 +136,6 @@ public boolean unloadWorld(ServerWorld world, boolean save) { boolean success = loadedWorlds.remove(world.getName(), w); if (success) { if (save) { - engine.getScheduler().removeAsyncManager(w); //getEventManager().callDelayedEvent(new WorldUnloadEvent(world)); w.unload(save); } diff --git a/src/main/java/com/flowpowered/engine/geo/world/FlowWorld.java b/src/main/java/com/flowpowered/engine/geo/world/FlowWorld.java index 35ac2ea..dfde338 100644 --- a/src/main/java/com/flowpowered/engine/geo/world/FlowWorld.java +++ b/src/main/java/com/flowpowered/engine/geo/world/FlowWorld.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.UUID; -import com.flowpowered.commons.bit.ShortBitMask; import com.flowpowered.events.Cause; import com.flowpowered.api.component.BaseComponentOwner; @@ -43,7 +42,6 @@ import com.flowpowered.api.geo.discrete.Transform; import com.flowpowered.api.material.BlockMaterial; import com.flowpowered.api.scheduler.TaskManager; -import com.flowpowered.api.scheduler.TickStage; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; import com.flowpowered.engine.FlowEngine; import com.flowpowered.engine.entity.EntityManager; @@ -53,15 +51,14 @@ import com.flowpowered.engine.geo.chunk.FlowChunk; import com.flowpowered.engine.geo.region.FlowRegion; import com.flowpowered.engine.geo.snapshot.FlowWorldSnapshot; -import com.flowpowered.engine.util.thread.CopySnapshotManager; -import com.flowpowered.engine.util.thread.StartTickManager; +import com.flowpowered.engine.scheduler.WorldThread; import com.flowpowered.engine.util.thread.snapshotable.SnapshotManager; import com.flowpowered.engine.util.thread.snapshotable.SnapshotableLong; import com.flowpowered.math.GenericMath; import com.flowpowered.math.imaginary.Quaternionf; import com.flowpowered.math.vector.Vector3f; -public class FlowWorld extends BaseComponentOwner implements World, StartTickManager, CopySnapshotManager { +public class FlowWorld extends BaseComponentOwner implements World { // TEST CODE /** * Number of milliseconds in a day. @@ -78,6 +75,7 @@ public class FlowWorld extends BaseComponentOwner implements World, StartTickMan private final SnapshotableLong age; private final RegionSource regionSource; private final FlowWorldSnapshot snapshot; + private final WorldThread thread; public FlowWorld(FlowEngine engine, String name, UUID uid, long age) { super(engine); @@ -88,6 +86,7 @@ public FlowWorld(FlowEngine engine, String name, UUID uid, long age) { this.age = new SnapshotableLong(snapshotManager, age); this.regionSource = new RegionSource(engine, this); this.snapshot = new FlowWorldSnapshot(this); + this.thread = new WorldThread(engine.getScheduler(), this); } public FlowWorld(FlowEngine engine, String name) { @@ -430,34 +429,18 @@ public FlowWorldSnapshot getSnapshot() { return snapshot; } - @Override public void startTickRun(int stage, long delta) { if (stage == 0) { age.set((long) (age.get() + (delta / 1000000d * (MILLIS_IN_DAY / GAME_DAY_IRL)))); } } - @Override - public void copySnapshotRun(int sequence) { + public void copySnapshotRun() { snapshotManager.copyAllSnapshots(); // TODO: modified status snapshot.update(this); } - @Override - public boolean checkSequence(TickStage stage, int sequence) { - if (stage == TickStage.SNAPSHOT) { - return sequence == 0; - } - return sequence == -1; - } - - private static ShortBitMask STAGES = TickStage.allOf(TickStage.STAGE1, TickStage.SNAPSHOT); - @Override - public ShortBitMask getTickStages() { - return STAGES; - } - public void setChunk(int x, int y, int z, int[] blocks) { FlowRegion region = getRegionFromChunk(x, y, z, LoadOption.LOAD_GEN); region.setChunk(x, y, z, blocks); @@ -477,4 +460,8 @@ public void save() { public boolean isLoaded() { return true; } + + public WorldThread getThread() { + return thread; + } } diff --git a/src/main/java/com/flowpowered/engine/geo/world/FlowWorldManager.java b/src/main/java/com/flowpowered/engine/geo/world/FlowWorldManager.java index ec83e13..b4106a7 100644 --- a/src/main/java/com/flowpowered/engine/geo/world/FlowWorldManager.java +++ b/src/main/java/com/flowpowered/engine/geo/world/FlowWorldManager.java @@ -26,20 +26,20 @@ import java.util.ArrayList; import java.util.Collection; import java.util.UUID; - -import com.flowpowered.commons.StringUtil; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import com.flowpowered.api.geo.World; import com.flowpowered.api.geo.WorldManager; +import com.flowpowered.commons.StringUtil; import com.flowpowered.engine.FlowEngine; -import com.flowpowered.engine.util.thread.snapshotable.SnapshotableLinkedHashMap; public class FlowWorldManager implements WorldManager { protected final FlowEngine engine; - protected final SnapshotableLinkedHashMap loadedWorlds; + protected final ConcurrentMap loadedWorlds; public FlowWorldManager(FlowEngine engine) { - loadedWorlds = new SnapshotableLinkedHashMap<>(engine.getSnapshotManager()); + loadedWorlds = new ConcurrentHashMap<>(); this.engine = engine; } @@ -55,13 +55,13 @@ public World getWorld(String name) { @Override public World getWorld(String name, boolean exact) { if (exact) { - FlowWorld world = loadedWorlds.get().get(name); + FlowWorld world = loadedWorlds.get(name); if (world != null) { return world; } - return loadedWorlds.get().get(name); + return loadedWorlds.get(name); } else { - return StringUtil.getShortest(StringUtil.matchName(loadedWorlds.getValues(), name)); + return StringUtil.getShortest(StringUtil.matchName(loadedWorlds.values(), name)); } } @@ -72,7 +72,7 @@ public Collection matchWorld(String name) { @Override public FlowWorld getWorld(UUID uid) { - for (FlowWorld world : loadedWorlds.getValues()) { + for (FlowWorld world : loadedWorlds.values()) { if (world.getUID().equals(uid)) { return world; } @@ -83,7 +83,7 @@ public FlowWorld getWorld(UUID uid) { @Override public Collection getWorlds() { Collection w = new ArrayList<>(); - for (FlowWorld world : loadedWorlds.getValues()) { + for (FlowWorld world : loadedWorlds.values()) { w.add(world); } return w; diff --git a/src/main/java/com/flowpowered/engine/player/FlowPlayer.java b/src/main/java/com/flowpowered/engine/player/FlowPlayer.java index 4bc82b6..032533a 100644 --- a/src/main/java/com/flowpowered/engine/player/FlowPlayer.java +++ b/src/main/java/com/flowpowered/engine/player/FlowPlayer.java @@ -23,12 +23,17 @@ */ package com.flowpowered.engine.player; -import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.TimeUnit; import com.flowpowered.api.entity.Entity; +import com.flowpowered.api.geo.World; import com.flowpowered.api.geo.discrete.TransformProvider; import com.flowpowered.api.input.InputSnapshot; import com.flowpowered.api.input.KeyboardEvent; @@ -38,33 +43,35 @@ import com.flowpowered.api.player.PlayerSnapshot; import com.flowpowered.chat.ChatReceiver; import com.flowpowered.commands.CommandException; +import com.flowpowered.engine.geo.world.FlowWorld; import com.flowpowered.engine.network.FlowSession; -import com.flowpowered.engine.util.thread.snapshotable.SnapshotManager; -import com.flowpowered.engine.util.thread.snapshotable.Snapshotable; import com.flowpowered.permissions.PermissionDomain; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalListener; +import com.google.common.cache.RemovalNotification; public class FlowPlayer implements Player { protected final String name; protected final PlayerNetwork network; protected volatile TransformProvider transformProvider = TransformProvider.NullTransformProvider.INSTANCE; - private volatile List inputSnapshots = new ArrayList<>(); - private volatile List liveInput = new ArrayList<>();; + private volatile Map> inputSnapshots = new HashMap<>(); + private volatile Cache> liveInput = CacheBuilder.newBuilder() + .concurrencyLevel(4) + .weakKeys() + .removalListener(new RemovalListener>() { + @Override + public void onRemoval(RemovalNotification> rn) { + network.getSession().getEngine().getLogger().warn("World '" + rn.getKey() + "' evicted from input cache for player '" + name + "' because: " + rn.getCause()); + } + }) + .build(); private volatile InputSnapshot lastLiveInput = new InputSnapshot(); private final Object inputMutex = new Object(); - public FlowPlayer(SnapshotManager snapshotManager, FlowSession session, String name) { + public FlowPlayer(FlowSession session, String name) { this.name = name; this.network = new PlayerNetwork(session); - snapshotManager.add(new Snapshotable() { - @Override - public void copySnapshot() { - synchronized (inputMutex) { - inputSnapshots = Collections.unmodifiableList(liveInput); - // We will only be writing - liveInput = Collections.synchronizedList(new ArrayList()); - } - } - }); } @Override @@ -212,14 +219,45 @@ public void setTransformProvider(TransformProvider provider) { this.transformProvider = provider == null ? TransformProvider.NullTransformProvider.INSTANCE : provider; } + public void copyInput(FlowWorld world) { + synchronized (inputMutex) { + LinkedList snapshot = new LinkedList(); + inputSnapshots.put(world.getThread().getThread().getThreadGroup(), snapshot); + ConcurrentLinkedQueue get = liveInput.getIfPresent(world); + if (get == null) { + return; + } + while (!get.isEmpty()) { + snapshot.add(get.poll()); + } + } + } + + /** + * @return the input for the current thread + */ + // TODO: I want to store this by thread id, but this is called by asyncmanagers @Override public List getInput() { - return inputSnapshots; + ThreadGroup group = Thread.currentThread().getThreadGroup(); + List get = inputSnapshots.get(group); + if (get == null) { + get = Collections.EMPTY_LIST; + inputSnapshots.put(group, get); + } + return get; } public void addInputChanges(float dt, boolean mouseGrabbed, List keyEvents, List mouseEvents) { synchronized (inputMutex) { - liveInput.add((lastLiveInput = lastLiveInput.withChanges(dt, mouseGrabbed, keyEvents, mouseEvents))); + for (World world : network.getSession().getEngine().getWorldManager().getWorlds()) { + ConcurrentLinkedQueue get = liveInput.getIfPresent(world); + if (get == null) { + get = new ConcurrentLinkedQueue<>(); + liveInput.put((FlowWorld) world, get); + } + get.add((lastLiveInput = lastLiveInput.withChanges(dt, mouseGrabbed, keyEvents, mouseEvents))); + } } } } diff --git a/src/main/java/com/flowpowered/engine/render/FlowRenderer.java b/src/main/java/com/flowpowered/engine/render/FlowRenderer.java index 7592de9..35f8cc2 100644 --- a/src/main/java/com/flowpowered/engine/render/FlowRenderer.java +++ b/src/main/java/com/flowpowered/engine/render/FlowRenderer.java @@ -39,7 +39,9 @@ import com.flowpowered.api.render.Renderer; import com.flowpowered.commons.TPSMonitor; +import com.flowpowered.engine.FlowClient; import com.flowpowered.engine.geo.region.RegionGenerator; +import com.flowpowered.engine.geo.world.FlowWorld; import com.flowpowered.engine.scheduler.FlowScheduler; import com.flowpowered.engine.scheduler.render.RenderThread; import com.flowpowered.math.vector.Vector2i; @@ -261,7 +263,7 @@ private void addHUD() { e.printStackTrace(); return; } - final StringModel sandboxModel = new StringModel(context, graph.getProgram("font"), "FlowEngineFTPSInputPositionWRa0123456789.-: GenCountModels", ubuntu.deriveFont(Font.PLAIN, 15), windowSize.getX()); + final StringModel sandboxModel = new StringModel(context, graph.getProgram("font"), "FlowEngineFTPSInputPositionWRa0123456789.-: GenCountModelsN/A", ubuntu.deriveFont(Font.PLAIN, 15), windowSize.getX()); final float aspect = getAspectRatio(); sandboxModel.setPosition(new Vector3f(0.005, .97 * aspect, -0.1)); sandboxModel.setString("Flow Engine - WIP"); @@ -332,7 +334,12 @@ public void render() { private void updateHUD() { fpsMonitor.update(); fpsMonitorModel.setString("FPS: " + fpsMonitor.getTPS()); - tpsMonitorModel.setString("TPS: " + scheduler.getMainThread().getTPS()); + FlowWorld currentWorld = (FlowWorld) ((FlowClient) scheduler.getEngine()).getTransform().getPosition().getWorld().get(); + if (currentWorld != null) { + tpsMonitorModel.setString("TPS: " + currentWorld.getThread().getTPS()); + } else { + tpsMonitorModel.setString("TPS: N/A"); + } itpsMonitorModel.setString("Input TPS: " + scheduler.getInputThread().getTPS()); Camera camera = renderModelsNode.getAttribute("camera"); diff --git a/src/main/java/com/flowpowered/engine/scheduler/FlowScheduler.java b/src/main/java/com/flowpowered/engine/scheduler/FlowScheduler.java index 7bf3046..535a98a 100644 --- a/src/main/java/com/flowpowered/engine/scheduler/FlowScheduler.java +++ b/src/main/java/com/flowpowered/engine/scheduler/FlowScheduler.java @@ -27,14 +27,13 @@ import java.util.concurrent.Callable; import java.util.concurrent.Future; -import com.flowpowered.api.Engine; import com.flowpowered.api.scheduler.Scheduler; import com.flowpowered.api.scheduler.Task; import com.flowpowered.api.scheduler.TaskPriority; import com.flowpowered.engine.FlowClient; +import com.flowpowered.engine.FlowEngine; import com.flowpowered.engine.scheduler.input.InputThread; import com.flowpowered.engine.scheduler.render.RenderThread; -import com.flowpowered.engine.util.thread.AsyncManager; /** * A class which handles scheduling for the engine {@link FlowTask}s.

Tasks can be submitted to the scheduler for execution by the main thread. These tasks are executed during a period where @@ -59,7 +58,7 @@ public final class FlowScheduler implements Scheduler { */ public static final int TARGET_FPS = 60; private final FlowTaskManager taskManager; - private final Engine engine; + private final FlowEngine engine; // SchedulerElements private final MainThread mainThread; private RenderThread renderThread; @@ -68,7 +67,7 @@ public final class FlowScheduler implements Scheduler { /** * Creates a new task scheduler. */ - public FlowScheduler(Engine engine) { + public FlowScheduler(FlowEngine engine) { this.engine = engine; mainThread = new MainThread(this); taskManager = new FlowTaskManager(this); @@ -184,7 +183,7 @@ public FlowTaskManager getTaskManager() { return taskManager; } - public Engine getEngine() { + public FlowEngine getEngine() { return engine; } @@ -193,10 +192,6 @@ public boolean isServerOverloaded() { return false; } - public MainThread getMainThread() { - return mainThread; - } - public RenderThread getRenderThread() { return renderThread; } @@ -204,22 +199,4 @@ public RenderThread getRenderThread() { public InputThread getInputThread() { return inputThread; } - - /** - * Adds an async manager to the scheduler - */ - public void addAsyncManager(AsyncManager manager) { - mainThread.addAsyncManager(manager); - } - - /** - * Removes an async manager from the scheduler - */ - public void removeAsyncManager(AsyncManager manager) { - mainThread.removeAsyncManager(manager); - } - - public void runCoreAsyncTask(Runnable r) { - mainThread.executorService.submit(r); - } } diff --git a/src/main/java/com/flowpowered/engine/scheduler/FlowTaskManager.java b/src/main/java/com/flowpowered/engine/scheduler/FlowTaskManager.java index c97cff9..fd78d72 100644 --- a/src/main/java/com/flowpowered/engine/scheduler/FlowTaskManager.java +++ b/src/main/java/com/flowpowered/engine/scheduler/FlowTaskManager.java @@ -40,7 +40,6 @@ import com.flowpowered.api.scheduler.Task; import com.flowpowered.api.scheduler.TaskManager; import com.flowpowered.api.scheduler.TaskPriority; -import com.flowpowered.engine.util.thread.AsyncManager; public class FlowTaskManager implements TaskManager { private final FlowScheduler scheduler; @@ -64,13 +63,13 @@ public class FlowTaskManager implements TaskManager { private final AtomicLong upTime; public FlowTaskManager(FlowScheduler scheduler) { - this(scheduler, null, 0L); + this(scheduler, 0L); } /** * Creates a new task scheduler. */ - public FlowTaskManager(FlowScheduler scheduler, AsyncManager taskManager, long age) { + public FlowTaskManager(FlowScheduler scheduler, long age) { this.scheduler = scheduler; primaryThread = Thread.currentThread(); this.upTime = new AtomicLong(age); @@ -244,6 +243,10 @@ public boolean waitForAsyncTasks(long timeout) { return true; } + public void runCoreAsyncTask(Runnable runnable) { + asyncTaskExecutor.execute(runnable); + } + private static class TaskComparator implements Comparator { @Override public int compare(FlowTask o1, FlowTask o2) { diff --git a/src/main/java/com/flowpowered/api/scheduler/IllegalTickSequenceException.java b/src/main/java/com/flowpowered/engine/scheduler/IllegalWorldTickSequenceException.java similarity index 72% rename from src/main/java/com/flowpowered/api/scheduler/IllegalTickSequenceException.java rename to src/main/java/com/flowpowered/engine/scheduler/IllegalWorldTickSequenceException.java index 8a2a306..18ecd81 100644 --- a/src/main/java/com/flowpowered/api/scheduler/IllegalTickSequenceException.java +++ b/src/main/java/com/flowpowered/engine/scheduler/IllegalWorldTickSequenceException.java @@ -21,24 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.flowpowered.api.scheduler; +package com.flowpowered.engine.scheduler; -public class IllegalTickSequenceException extends RuntimeException { +public class IllegalWorldTickSequenceException extends RuntimeException { private static final long serialVersionUID = 1L; - public IllegalTickSequenceException(int allowedStages, int restrictedStages, Thread t, TickStage actualStage) { + public IllegalWorldTickSequenceException(int allowedStages, int restrictedStages, Thread t, WorldTickStage actualStage) { super(getMessage(allowedStages, restrictedStages, t, actualStage)); } - public IllegalTickSequenceException(int allowedStages, TickStage actualStage) { - super("Method called during (" + actualStage + ") when only (" + TickStage.getAllStages(allowedStages) + ") were allowed"); + public IllegalWorldTickSequenceException(int allowedStages, WorldTickStage actualStage) { + super("Method called during (" + actualStage + ") when only (" + WorldTickStage.getAllStages(allowedStages) + ") were allowed"); } - private static String getMessage(int allowedStages, int restrictedStages, Thread t, TickStage actualStage) { + private static String getMessage(int allowedStages, int restrictedStages, Thread t, WorldTickStage actualStage) { if (Thread.currentThread() != t) { - return "Method called by non-owning thread (" + Thread.currentThread() + ") during (" + actualStage + ") when only calls by (" + t + ") during (" + TickStage.getAllStages(allowedStages) + ") were allowed"; + return "Method called by non-owning thread (" + Thread.currentThread() + ") during (" + actualStage + ") when only calls by (" + t + ") during (" + WorldTickStage.getAllStages(allowedStages) + ") were allowed"; } else { - return "Method called during (" + actualStage + ") when only (" + TickStage.getAllStages(restrictedStages) + ") were allowed for owning thread " + t; + return "Method called during (" + actualStage + ") when only (" + WorldTickStage.getAllStages(restrictedStages) + ") were allowed for owning thread " + t; } } } diff --git a/src/main/java/com/flowpowered/engine/scheduler/MainThread.java b/src/main/java/com/flowpowered/engine/scheduler/MainThread.java index db90be8..d696161 100644 --- a/src/main/java/com/flowpowered/engine/scheduler/MainThread.java +++ b/src/main/java/com/flowpowered/engine/scheduler/MainThread.java @@ -23,381 +23,36 @@ */ package com.flowpowered.engine.scheduler; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -import com.flowpowered.api.Client; import com.flowpowered.api.Server; import com.flowpowered.api.geo.discrete.Transform; import com.flowpowered.api.player.Player; -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.commons.TPSMonitor; import com.flowpowered.commons.ticking.TickingElement; -import com.flowpowered.engine.geo.region.RegionGenerator; import com.flowpowered.engine.player.FlowPlayer; -import com.flowpowered.engine.util.ClientObserver; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.LoggingThreadPoolExecutor; -import com.flowpowered.engine.util.thread.coretasks.CopySnapshotTask; -import com.flowpowered.engine.util.thread.coretasks.FinalizeTask; -import com.flowpowered.engine.util.thread.coretasks.GlobalDynamicUpdatesTask; -import com.flowpowered.engine.util.thread.coretasks.GlobalPhysicsTask; -import com.flowpowered.engine.util.thread.coretasks.LightingTask; -import com.flowpowered.engine.util.thread.coretasks.LocalDynamicUpdatesTask; -import com.flowpowered.engine.util.thread.coretasks.LocalPhysicsTask; -import com.flowpowered.engine.util.thread.coretasks.ManagerRunnable; -import com.flowpowered.engine.util.thread.coretasks.ManagerRunnableFactory; -import com.flowpowered.engine.util.thread.coretasks.PreSnapshotTask; -import com.flowpowered.engine.util.thread.coretasks.StartTickTask; -import org.apache.logging.log4j.Logger; public class MainThread extends TickingElement { private final FlowScheduler scheduler; - private final Logger logger; - private final AtomicLong currentDelta = new AtomicLong(0); - private final ManagerRunnableFactory[] managerRunnableFactories = new ManagerRunnableFactory[] { - null,//TickStart has no ManagerRunnableFactory - new StartTickTask(0, currentDelta), - new StartTickTask(1, currentDelta), - new LocalDynamicUpdatesTask(), - new GlobalDynamicUpdatesTask(), - new LocalPhysicsTask(), - new GlobalPhysicsTask(), - new LightingTask(), - new FinalizeTask(), - new PreSnapshotTask(), - new CopySnapshotTask() - }; - - @SuppressWarnings("unchecked") - private final Set[][] managerRunnables = new Set[managerRunnableFactories.length][]; - // We are going to synchronize on this, don't need concurrent - private final List manageRunnableUpdates = new LinkedList<>(); - - /** - * Update count for physics and dynamic updates - */ - private final AtomicInteger updates = new AtomicInteger(0); - /** - * The threshold before physics and dynamic updates are aborted - */ - private final static int UPDATE_THRESHOLD = 100000; - /** - * A list of all AsyncManagers - */ - //private final List asyncManagers = new ConcurrentList<>(); - // scheduler executor service - protected final ExecutorService executorService; - private final TPSMonitor tpsMonitor = new TPSMonitor(); - private final ClientObserver observe; public MainThread(FlowScheduler scheduler) { super("MainThread", 20); this.scheduler = scheduler; - this.logger = scheduler.getEngine().getLogger(); - final int nThreads = Runtime.getRuntime().availableProcessors() * 2 + 1; - executorService = LoggingThreadPoolExecutor.newFixedThreadExecutorWithMarkedName(nThreads, "FlowScheduler - AsyncManager executor service", scheduler.getEngine().getLogger()); - if (scheduler.getEngine().getPlatform().isClient()) { - observe = new ClientObserver((Client) scheduler.getEngine()); - } else { - observe = null; - } } @Override public void onStart() { - tpsMonitor.start(); - - if (scheduler.getInputThread() != null) { - scheduler.getInputThread().subscribeToInput(); - } - updateManagers(); } @Override public void onStop() { - doCopySnapshot(); - RegionGenerator.shutdownExecutorService(); - RegionGenerator.awaitExecutorServiceTermination(logger); - - executorService.shutdown(); - - scheduler.getTaskManager().heartbeat(FlowScheduler.PULSE_EVERY << 2); - scheduler.getTaskManager().stop(); - - long delay = 2000; - while (!scheduler.getTaskManager().waitForAsyncTasks(delay)) { - logger.info("Unable to shutdown due to async tasks still running"); - if (delay < 8000) { - delay <<= 1; - } - } - - if (scheduler.getInputThread() != null) { - scheduler.getInputThread().unsubscribeToInput(); - } } - // TODO: config - private final boolean DYNAMIC_UPDATES = true; - private final boolean BLOCK_PHYSICS = true; - private final boolean LIGHTING = true; - @Override public void onTick(long delta) { - // Delta is in nanos, we want millis with rounding - delta = Math.round(delta * 1e-6d); - this.currentDelta.set(delta); - - TickStage.setStage(TickStage.TICKSTART); - - scheduler.getTaskManager().heartbeat(delta); - - runTasks(TickStage.STAGE1); - - runTasks(TickStage.STAGE2P); - - int totalUpdates = -1; - int lightUpdates = 0; - int dynamicUpdates = 0; - int physicsUpdates = 0; - updates.set(0); - int uD = 1; - int uP = 1; - while ((uD + uP) > 0 && totalUpdates < UPDATE_THRESHOLD) { - if (DYNAMIC_UPDATES) { - doDynamicUpdates(); - } - - uD = updates.getAndSet(0); - totalUpdates += uD; - dynamicUpdates += uD; - - if (BLOCK_PHYSICS) { - doPhysics(); - } - - uP = updates.getAndSet(0); - totalUpdates += uP; - physicsUpdates += uP; - } - - if (LIGHTING) { - doLighting(); - } - - if (totalUpdates >= UPDATE_THRESHOLD) { - logger.warn("Block updates per tick of " + totalUpdates + " exceeded the threshold " + UPDATE_THRESHOLD + "; " + dynamicUpdates + " dynamic updates, " + physicsUpdates + " block physics updates and " + lightUpdates + " lighting updates"); - } - - doFinalizeTick(); - if (scheduler.getEngine().getPlatform().isServer()) { for (Player p : ((Server) scheduler.getEngine()).getOnlinePlayers()) { Transform transform = p.getTransformProvider().getTransform(); ((FlowPlayer) p).getNetwork().preSnapshotRun(transform); } } - - if (scheduler.getEngine().getPlatform().isClient()) { - observe.update(); - } - - doCopySnapshot(); - updateManagers(); - - tpsMonitor.update(); - } - - - private void doPhysics() { - int passStartUpdates = updates.get() - 1; - int startUpdates = updates.get(); - while (passStartUpdates < updates.get() && updates.get() < startUpdates + UPDATE_THRESHOLD) { - passStartUpdates = updates.get(); - runTasks(TickStage.PHYSICS); - runTasks(TickStage.GLOBAL_PHYSICS); - } - } - - private void doDynamicUpdates() { - /*int passStartUpdates = updates.get() - 1; - int startUpdates = updates.get(); - - TickStage.setStage(TickStage.GLOBAL_DYNAMIC_BLOCKS); - - long earliestTime = FlowScheduler.END_OF_THE_WORLD; - - for (AsyncManager e : managers) { - long firstTime = e.getFirstDynamicUpdateTime(); - if (firstTime < earliestTime) { - earliestTime = firstTime; - } - } - - while (passStartUpdates < updates.get() && updates.get() < startUpdates + UPDATE_THRESHOLD) { - passStartUpdates = updates.get(); - - long threshold = earliestTime + FlowScheduler.PULSE_EVERY - 1; - - dynamicUpdatesTask.setThreshold(threshold); - - this.runTasks(managers, dynamicUpdatesTask, "Dynamic Blocks", TickStage.GLOBAL_DYNAMIC_BLOCKS, TickStage.DYNAMIC_BLOCKS); - }*/ - } - - private void doLighting() { - runTasks(TickStage.LIGHTING); - } - - - private void doFinalizeTick() { - runTasks(TickStage.FINALIZE); - } - - private void doCopySnapshot() { - runTasks(TickStage.PRESNAPSHOT); - runTasks(TickStage.SNAPSHOT); - } - - public void runTasks(final TickStage stage) { - TickStage.setStage(stage); - Set[] sequences = managerRunnables[stage.getOrder() - 1]; - if (sequences == null) { - return; - } - for (Set managers : sequences) { - if (managers == null) { - continue; - } - try { - final List> futures = executorService.invokeAll(managers); - // invokeAll means that it returns when all futures are done or cancelled - // We only want to report the exceptions, we don't want to wait - // TODO: modify LoggingThreadPoolExecutor to allow custom logging - /* - executorService.submit(new Runnable() { - @Override - public void run() { - for (int i = 0; i < futures.size(); i++) { - try { - futures.get(i).get(); - } catch (ExecutionException e) { - logger.warn("Exception thrown when executing a task in tick stage " + stage, e); - } catch (InterruptedException e) { - logger.warn("Interrupted when getting future", e); - } - } - } - }); - */ - } catch (InterruptedException e) { - logger.warn("Main thread interrupted while waiting on tick stage " + stage); - } - } - } - - /** - * Adds an async manager to the scheduler - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - public void addAsyncManager(AsyncManager manager) { - for (int stage = 0; stage < managerRunnableFactories.length; stage++) { - ManagerRunnableFactory taskFactory = managerRunnableFactories[stage]; - if (taskFactory == null) { - continue; - } - final int maxSequence = taskFactory.getMaxSequence(); - final int minSequence = taskFactory.getMinSequence(); - final int numSequences = maxSequence - minSequence + 1; - Set[] sequences = managerRunnables[stage]; - if (sequences == null) { - sequences = managerRunnables[stage] = new Set[numSequences]; - } - if (((manager.getTickStages().getMask() >> stage) & 1) == 0) { - continue; - } - for (int s = minSequence; s <= maxSequence; s++) { - if (manager.checkSequence(taskFactory.getTickStage(), s)) { - Set sequence = sequences[s - minSequence]; - if (sequence == null) { - // We can use HashSet because we're never going to modify this concurrently - sequences[s - minSequence] = sequence = new HashSet<>(); - } - synchronized (manageRunnableUpdates) { - manageRunnableUpdates.add(new ManagerRunnableUpdateEntry(stage, s - minSequence, taskFactory.getTask(manager, s), true)); - } - } - } - } - } - - /** - * Removes an async manager from the scheduler - */ - public void removeAsyncManager(AsyncManager manager) { - for (int stage = 0; stage < managerRunnableFactories.length; stage++) { - ManagerRunnableFactory taskFactory = managerRunnableFactories[stage]; - if (taskFactory == null) { - continue; - } - final int maxSequence = taskFactory.getMaxSequence(); - final int minSequence = taskFactory.getMinSequence(); - Set[] sequences = managerRunnables[stage]; - if (sequences == null) { - continue; - } - if (((manager.getTickStages().getMask() >> stage) & 1) == 0) { - continue; - } - for (int s = minSequence; s <= maxSequence; s++) { - Set sequence = sequences[s - minSequence]; - if (sequence != null) { - synchronized (manageRunnableUpdates) { - manageRunnableUpdates.add(new ManagerRunnableUpdateEntry(stage, s - minSequence, taskFactory.getTask(manager, s), false)); - } - } - } - } - } - - private void updateManagers() { - // Small and seldom possibility that there are sync updates to this that might conflict: use synchronized - synchronized (manageRunnableUpdates) { - if (manageRunnableUpdates.isEmpty()) { - return; - } - for (ManagerRunnableUpdateEntry e : manageRunnableUpdates) { - if (e.add) { - managerRunnables[e.stage][e.sequence].add(e.runnable); - } else { - managerRunnables[e.stage][e.sequence].remove(e.runnable); - } - } - manageRunnableUpdates.clear(); - } - } - - private static class ManagerRunnableUpdateEntry { - private final int stage, sequence; - private final ManagerRunnable runnable; - private final boolean add; - - private ManagerRunnableUpdateEntry(int stage, int sequence, ManagerRunnable runnable, boolean add) { - this.stage = stage; - this.sequence = sequence; - this.runnable = runnable; - this.add = add; - } - } - - public int getTPS() { - return tpsMonitor.getTPS(); + scheduler.getEngine().copySnapshot(); } } diff --git a/src/main/java/com/flowpowered/engine/scheduler/MarkedNamedThreadFactory.java b/src/main/java/com/flowpowered/engine/scheduler/MarkedNamedThreadFactory.java index 58b84d4..6dcbd4d 100644 --- a/src/main/java/com/flowpowered/engine/scheduler/MarkedNamedThreadFactory.java +++ b/src/main/java/com/flowpowered/engine/scheduler/MarkedNamedThreadFactory.java @@ -30,15 +30,21 @@ public class MarkedNamedThreadFactory implements ThreadFactory { private final AtomicInteger idCounter = new AtomicInteger(); private final String namePrefix; private final boolean daemon; + private final ThreadGroup group; - public MarkedNamedThreadFactory(String namePrefix, boolean daemon) { + public MarkedNamedThreadFactory(ThreadGroup group, String namePrefix, boolean daemon) { + this.group = group; this.namePrefix = namePrefix; this.daemon = daemon; } + public MarkedNamedThreadFactory(String namePrefix, boolean daemon) { + this(new ThreadGroup(namePrefix), namePrefix, daemon); + } + @Override public Thread newThread(Runnable runnable) { - Thread thread = new Thread(runnable, "Executor{" + namePrefix + "-" + idCounter.getAndIncrement() + "}"); + Thread thread = new Thread(group, runnable, "Executor{" + namePrefix + "-" + idCounter.getAndIncrement() + "}"); thread.setDaemon(daemon); return thread; } diff --git a/src/main/java/com/flowpowered/engine/scheduler/WorldThread.java b/src/main/java/com/flowpowered/engine/scheduler/WorldThread.java new file mode 100644 index 0000000..df2ce66 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/scheduler/WorldThread.java @@ -0,0 +1,166 @@ +/* + * This file is part of Flow Engine, licensed under the MIT License (MIT). + * + * Copyright (c) 2013 Spout LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.flowpowered.engine.scheduler; + + +import com.flowpowered.api.player.Player; +import com.flowpowered.commons.TPSMonitor; +import com.flowpowered.commons.bit.ShortBitMask; +import com.flowpowered.commons.ticking.TickingElement; +import com.flowpowered.engine.FlowServer; +import com.flowpowered.engine.geo.region.FlowRegion; +import com.flowpowered.engine.geo.region.RegionGenerator; +import com.flowpowered.engine.geo.world.FlowWorld; +import com.flowpowered.engine.player.FlowPlayer; +import org.apache.logging.log4j.Logger; + +public class WorldThread extends TickingElement { + private final FlowScheduler scheduler; + private final Logger logger; + private final TPSMonitor tpsMonitor = new TPSMonitor(); + private WorldTickStage currentStage = WorldTickStage.STAGE1; + private FlowWorld world; + + public WorldThread(FlowScheduler scheduler, FlowWorld world) { + super("WorldThread - " + world.getName(), 20); + this.world = world; + this.scheduler = scheduler; + this.logger = scheduler.getEngine().getLogger(); + } + + @Override + public void onStart() { + tpsMonitor.start(); + } + + @Override + public void onStop() { + doCopySnapshot(); + RegionGenerator.shutdownExecutorService(); + RegionGenerator.awaitExecutorServiceTermination(logger); + + scheduler.getTaskManager().heartbeat(FlowScheduler.PULSE_EVERY << 2); + scheduler.getTaskManager().stop(); + + long delay = 2000; + while (!scheduler.getTaskManager().waitForAsyncTasks(delay)) { + logger.info("Unable to shutdown due to async tasks still running"); + if (delay < 8000) { + delay <<= 1; + } + } + } + + @Override + public void onTick(long delta) { + // Delta is in nanos, we want millis with rounding + final long realDelta = Math.round(delta * 1e-6d); + + currentStage = WorldTickStage.TICKSTART; + + scheduler.getTaskManager().heartbeat(realDelta); + + world.startTickRun(0, realDelta); + world.getRegions().stream().map((r) -> (FlowRegion) r).forEach((FlowRegion r) -> r.startTickRun(0, realDelta)); + + world.getRegions().stream().map((r) -> (FlowRegion) r).forEach((FlowRegion r) -> r.startTickRun(1, realDelta)); + + doFinalizeTick(); + + doCopySnapshot(); + + if (scheduler.getEngine().getPlatform().isServer()) { + for (Player p : ((FlowServer) scheduler.getEngine()).getOnlinePlayers()) { + ((FlowPlayer) p).copyInput(world); + } + } + + tpsMonitor.update(); + } + + private void doFinalizeTick() { + world.getRegions().stream().map((r) -> (FlowRegion) r).forEach((FlowRegion r) -> r.finalizeRun()); + } + + private void doCopySnapshot() { + world.getRegions().stream().map((r) -> (FlowRegion) r).forEach((FlowRegion r) -> r.preSnapshotRun()); + + world.copySnapshotRun(); + world.getRegions().stream().map((r) -> (FlowRegion) r).forEach((FlowRegion r) -> r.copySnapshotRun()); + } + + public int getTPS() { + return tpsMonitor.getTPS(); + } + + public WorldTickStage getStage() { + return currentStage; + } + + /** + * Checks if the current stages is one of the valid allowed stages. + * + * @param allowedStages the OR of all the allowed stages + */ + public void checkStage(ShortBitMask allowedStages) { + if (!testStage(allowedStages)) { + throw new IllegalWorldTickSequenceException(allowedStages.getMask(), currentStage); + } + } + + /** + * Checks if the current currentStages is one of the valid allowed currentStages, but does not throw an exception. + * + * @param allowedStages the OR of all the allowed currentStages + * @return true if the current currentStage is one of the allowed currentStages + */ + public boolean testStage(ShortBitMask allowedStages) { + return (currentStage.getMask() & allowedStages.getMask()) != 0; + } + + /** + * Checks if the current thread is the owner thread and the current currentStage is one of the restricted currentStages, or that the current currentStage is one of the open currentStages + * + * @param allowedStages the OR of all the open currentStages + * @param restrictedStages the OR of all restricted currentStages + * @param ownerThread the thread that has restricted access + */ + public void checkStage(ShortBitMask allowedStages, ShortBitMask restrictedStages, Thread ownerThread) { + if ((currentStage.getMask() & allowedStages.getMask()) != 0 && ((Thread.currentThread() != ownerThread || (currentStage.getMask() & restrictedStages.getMask()) == 0))) { + throw new IllegalWorldTickSequenceException(allowedStages.getMask(), restrictedStages.getMask(), ownerThread, currentStage); + } + } + + /** + * Checks if the current thread is the owner thread and the current currentStage is one of the restricted currentStages + * + * @param restrictedStages the OR of all restricted currentStages + * @param ownerThread the thread that has restricted access + */ + public void checkStage(ShortBitMask restrictedStages, Thread ownerThread) { + if (((currentStage.getMask() & restrictedStages.getMask()) == 0) || Thread.currentThread() != ownerThread) { + throw new IllegalWorldTickSequenceException(restrictedStages.getMask(), 0, ownerThread, currentStage); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/api/scheduler/TickStage.java b/src/main/java/com/flowpowered/engine/scheduler/WorldTickStage.java similarity index 62% rename from src/main/java/com/flowpowered/api/scheduler/TickStage.java rename to src/main/java/com/flowpowered/engine/scheduler/WorldTickStage.java index 10d3bcb..bbbfa3a 100644 --- a/src/main/java/com/flowpowered/api/scheduler/TickStage.java +++ b/src/main/java/com/flowpowered/engine/scheduler/WorldTickStage.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.flowpowered.api.scheduler; +package com.flowpowered.engine.scheduler; import com.flowpowered.commons.bit.ShortBitMask; import com.flowpowered.commons.bit.ShortBitSet; @@ -29,10 +29,7 @@ /** * Represents the various tick stages.

The exact bit fields used are subject to change */ -public enum TickStage implements ShortBitMask { - /** - * All tasks submitted to the main thread are executed during TICKSTART.

This stage is single threaded - */ +public enum WorldTickStage implements ShortBitMask { TICKSTART(1), /** * This is the first stage of the execution of the tick @@ -73,7 +70,7 @@ public enum TickStage implements ShortBitMask { /** * This is the snapshot copy stage.

All snapshots are updated to the equal to the live value. */ - SNAPSHOT(11); + COPY_SNAPSHOT(11); public final static ShortBitMask ALL_PHYSICS = allOf(PHYSICS, GLOBAL_PHYSICS); public final static ShortBitMask ALL_DYNAMIC = allOf(DYNAMIC_BLOCKS, GLOBAL_DYNAMIC_BLOCKS); @@ -82,7 +79,7 @@ public enum TickStage implements ShortBitMask { private final short mask; private final int order; - private TickStage(int stage) { + private WorldTickStage(int stage) { this.order = stage; this.mask = (short) (1 << (stage - 1)); } @@ -100,10 +97,6 @@ public static int getNumStages() { return values().length; } - public static TickStage getStage() { - return currentStage; - } - public static String getStage(int num) { switch (num) { case 1: @@ -141,13 +134,13 @@ public static String getAllStages(int num) { while (scan != 0) { int checkNum = num & scan; if (checkNum != 0) { - if (first) { - first = false; - } else { - sb.append(", "); - } String stage = getStage(checkNum); - if (stage != null) { + if (stage != null) { + if (first) { + first = false; + } else { + sb.append(", "); + } sb.append(stage); } } @@ -156,63 +149,6 @@ public static String getAllStages(int num) { return sb.toString(); } - private static TickStage currentStage = TICKSTART; - - /** - * Sets the current stage. This is not synchronised, so should only be called during the stable period between stages. - * - * @param stage the stage - */ - public static void setStage(TickStage stage) { - TickStage.currentStage = stage; - } - - /** - * Checks if the current stages is one of the valid allowed stages. - * - * @param allowedStages the OR of all the allowed stages - */ - public static void checkStage(ShortBitMask allowedStages) { - if (!testStage(allowedStages)) { - throw new IllegalTickSequenceException(allowedStages.getMask(), currentStage); - } - } - - /** - * Checks if the current currentStages is one of the valid allowed currentStages, but does not throw an exception. - * - * @param allowedStages the OR of all the allowed currentStages - * @return true if the current currentStage is one of the allowed currentStages - */ - public static boolean testStage(ShortBitMask allowedStages) { - return (currentStage.getMask() & allowedStages.getMask()) != 0; - } - - /** - * Checks if the current thread is the owner thread and the current currentStage is one of the restricted currentStages, or that the current currentStage is one of the open currentStages - * - * @param allowedStages the OR of all the open currentStages - * @param restrictedStages the OR of all restricted currentStages - * @param ownerThread the thread that has restricted access - */ - public static void checkStage(ShortBitMask allowedStages, ShortBitMask restrictedStages, Thread ownerThread) { - if ((currentStage.getMask() & allowedStages.getMask()) != 0 && ((Thread.currentThread() != ownerThread || (currentStage.getMask() & restrictedStages.getMask()) == 0))) { - throw new IllegalTickSequenceException(allowedStages.getMask(), restrictedStages.getMask(), ownerThread, currentStage); - } - } - - /** - * Checks if the current thread is the owner thread and the current currentStage is one of the restricted currentStages - * - * @param restrictedStages the OR of all restricted currentStages - * @param ownerThread the thread that has restricted access - */ - public static void checkStage(ShortBitMask restrictedStages, Thread ownerThread) { - if (((currentStage.getMask() & restrictedStages.getMask()) == 0) || Thread.currentThread() != ownerThread) { - throw new IllegalTickSequenceException(restrictedStages.getMask(), 0, ownerThread, currentStage); - } - } - public static ShortBitMask allOf(ShortBitMask... stages) { short mask = 0; for (ShortBitMask stage : stages) { diff --git a/src/main/java/com/flowpowered/engine/scheduler/render/RenderThread.java b/src/main/java/com/flowpowered/engine/scheduler/render/RenderThread.java index 09446bb..4b59d6d 100644 --- a/src/main/java/com/flowpowered/engine/scheduler/render/RenderThread.java +++ b/src/main/java/com/flowpowered/engine/scheduler/render/RenderThread.java @@ -49,6 +49,7 @@ import com.flowpowered.engine.render.mesher.StandardChunkMesher; import com.flowpowered.engine.render.model.ChunkModel; import com.flowpowered.engine.scheduler.input.InputThread; +import com.flowpowered.engine.util.ClientObserver; import com.flowpowered.math.TrigMath; import com.flowpowered.math.imaginary.Quaternionf; import com.flowpowered.math.vector.Vector3f; @@ -74,6 +75,7 @@ public class RenderThread extends TickingElement { private final Map chunkModels = new HashMap<>(); private final TObjectLongMap chunkLastUpdateNumbers = new TObjectLongHashMap<>(); private final CountDownLatch intializedLatch = new CountDownLatch(1); + private final ClientObserver observe; public RenderThread(FlowClient client) { super("RenderThread", FPS); @@ -82,6 +84,7 @@ public RenderThread(FlowClient client) { this.frustum = new ViewFrustum(); this.input = client.getScheduler().getInputThread(); this.mesher = new ParallelChunkMesher(this, new StandardChunkMesher()); + this.observe = new ClientObserver(client); } @Override @@ -107,6 +110,7 @@ public void onStop() { public void onTick(long dt) { handleInput(); updateCameraAndFrustrum(); + observe.update(); WorldReference ref = client.getTransform().getPosition().getWorld(); FlowWorld world = ref == null ? null : (FlowWorld) ref.get(); updateChunkModels(); diff --git a/src/main/java/com/flowpowered/engine/util/thread/AsyncManager.java b/src/main/java/com/flowpowered/engine/util/thread/AsyncManager.java deleted file mode 100644 index b24995f..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/AsyncManager.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread; - -import com.flowpowered.commons.bit.ShortBitMask; -import com.flowpowered.api.scheduler.TickStage; - -public interface AsyncManager { - - /** - * Checks if the current sequence is - * - * @param stage the current TickStage - * @param sequence the current sequence - * @return true if the AsyncManager should be called, false if not - */ - public boolean checkSequence(TickStage stage, int sequence); - - public ShortBitMask getTickStages(); -} diff --git a/src/main/java/com/flowpowered/engine/util/thread/CompleteAsyncManager.java b/src/main/java/com/flowpowered/engine/util/thread/CompleteAsyncManager.java deleted file mode 100644 index 083010d..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/CompleteAsyncManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread; - -public interface CompleteAsyncManager extends FinalizeManager, PreSnapshotManager, CopySnapshotManager, DynamicUpdateManager, StartTickManager, PhysicsManager, LightingManager { -} diff --git a/src/main/java/com/flowpowered/engine/util/thread/CopySnapshotManager.java b/src/main/java/com/flowpowered/engine/util/thread/CopySnapshotManager.java deleted file mode 100644 index 044eb7c..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/CopySnapshotManager.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread; - -public interface CopySnapshotManager extends AsyncManager { - /** - * This method is called in order to update the snapshot at the end of each tick - */ - void copySnapshotRun(int sequence); -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/DynamicUpdateManager.java b/src/main/java/com/flowpowered/engine/util/thread/DynamicUpdateManager.java deleted file mode 100644 index dce6d77..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/DynamicUpdateManager.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread; - -public interface DynamicUpdateManager extends AsyncManager { - /** - * This method is called to execute dynamic updates for blocks in the Region. It might be called multiple times per tick, the sequence number indicates which lists to check - * - * @param sequence -1 for local, 0 - 26 for which sequence - */ - void runDynamicUpdates(long threshold, int sequence); - - /** - * This method is called to determine the earliest available dynamic update time - * - * @return the earliest pending dynamic block update - */ - public long getFirstDynamicUpdateTime(); -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/FinalizeManager.java b/src/main/java/com/flowpowered/engine/util/thread/FinalizeManager.java deleted file mode 100644 index 55e6480..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/FinalizeManager.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread; - - -public interface FinalizeManager extends AsyncManager { - /** - * This method is called directly before preSnapshot is called - */ - void finalizeRun(); -} diff --git a/src/main/java/com/flowpowered/engine/util/thread/LightingManager.java b/src/main/java/com/flowpowered/engine/util/thread/LightingManager.java deleted file mode 100644 index 98a0c81..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/LightingManager.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread; - -public interface LightingManager extends AsyncManager { - /** - * This method is called to update lighting. It might be called multiple times per tick - * - * @param sequence -1 for local, 0 - 26 for which sequence - */ - void runLighting(int sequence); -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/LoggingThreadPoolExecutor.java b/src/main/java/com/flowpowered/engine/util/thread/LoggingThreadPoolExecutor.java index 4a74515..07c7be9 100644 --- a/src/main/java/com/flowpowered/engine/util/thread/LoggingThreadPoolExecutor.java +++ b/src/main/java/com/flowpowered/engine/util/thread/LoggingThreadPoolExecutor.java @@ -43,6 +43,11 @@ public static LoggingThreadPoolExecutor newFixedThreadExecutorWithMarkedName(int new MarkedNamedThreadFactory(name, true), logger); } + public static LoggingThreadPoolExecutor newFixedThreadExecutorWithMarkedName(ThreadGroup group, int nThreads, String name, Logger logger) { + return new LoggingThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), + new MarkedNamedThreadFactory(group, name, true), logger); + } + private Logger logger; public LoggingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, Logger logger) { diff --git a/src/main/java/com/flowpowered/engine/util/thread/PhysicsManager.java b/src/main/java/com/flowpowered/engine/util/thread/PhysicsManager.java deleted file mode 100644 index 6f8fc5c..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/PhysicsManager.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread; - -public interface PhysicsManager extends AsyncManager { - /** - * This method is called to execute physics for blocks local to the Region. It might be called multiple times per tick - * - * @param sequence -1 for local, 0 - 26 for which sequence - */ - void runPhysics(int sequence); -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/PreSnapshotManager.java b/src/main/java/com/flowpowered/engine/util/thread/PreSnapshotManager.java deleted file mode 100644 index bf3c171..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/PreSnapshotManager.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread; - - -public interface PreSnapshotManager extends AsyncManager { - /** - * This method is called directly before copySnapshotRun and is a MONITOR ONLY stage and no updates should be performed.

It occurs after the finalize stage and before the copy snapshot - * stage. - */ - void preSnapshotRun(); -} diff --git a/src/main/java/com/flowpowered/engine/util/thread/StartTickManager.java b/src/main/java/com/flowpowered/engine/util/thread/StartTickManager.java deleted file mode 100644 index 430bd0b..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/StartTickManager.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread; - -public interface StartTickManager extends AsyncManager { - /** - * This method is called in order to start a new tick - * - * @param delta the time since the last tick - */ - void startTickRun(int stage, long delta); -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/CopySnapshotTask.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/CopySnapshotTask.java deleted file mode 100644 index a41d9de..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/CopySnapshotTask.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.CopySnapshotManager; - -public class CopySnapshotTask extends LocalManagerRunnableFactory { - @Override - public ManagerRunnable getTask(final AsyncManager manager, final int sequence) { - return new ManagerRunnable(manager) { - @Override - public void runTask() { - ((CopySnapshotManager) manager).copySnapshotRun(sequence); - } - }; - } - - @Override - public int getMaxSequence() { - return 0; - } - - @Override - public TickStage getTickStage() { - return TickStage.SNAPSHOT; - } -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/FinalizeTask.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/FinalizeTask.java deleted file mode 100644 index 33605aa..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/FinalizeTask.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.FinalizeManager; - -public class FinalizeTask extends LocalManagerRunnableFactory { - @Override - public ManagerRunnable getTask(final AsyncManager manager, final int sequence) { - return new ManagerRunnable(manager) { - @Override - public void runTask() { - ((FinalizeManager) manager).finalizeRun(); - } - }; - } - - @Override - public TickStage getTickStage() { - return TickStage.FINALIZE; - } -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/GlobalDynamicUpdatesTask.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/GlobalDynamicUpdatesTask.java deleted file mode 100644 index 11653f2..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/GlobalDynamicUpdatesTask.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.DynamicUpdateManager; - -public class GlobalDynamicUpdatesTask extends SequencedManagerRunnableFactory { - private long threshold = 0; - - @Override - public ManagerRunnable getTask(final AsyncManager manager, final int sequence) { - return new ManagerRunnable(manager) { - @Override - public void runTask() { - ((DynamicUpdateManager) manager).runDynamicUpdates(threshold, sequence); - } - }; - } - - public void setThreshold(long threshold) { - this.threshold = threshold; - } - - @Override - public int getMinSequence() { - return 0; - } - - @Override - public TickStage getTickStage() { - return TickStage.GLOBAL_DYNAMIC_BLOCKS; - } - -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/GlobalPhysicsTask.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/GlobalPhysicsTask.java deleted file mode 100644 index 23a33a2..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/GlobalPhysicsTask.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.PhysicsManager; - -public class GlobalPhysicsTask extends SequencedManagerRunnableFactory { - @Override - public ManagerRunnable getTask(final AsyncManager manager, final int sequence) { - return new ManagerRunnable(manager) { - @Override - public void runTask() { - ((PhysicsManager) manager).runPhysics(sequence); - } - }; - } - - @Override - public int getMinSequence() { - return 0; - } - - @Override - public TickStage getTickStage() { - return TickStage.GLOBAL_PHYSICS; - } -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/LightingTask.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/LightingTask.java deleted file mode 100644 index b35ea81..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/LightingTask.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.LightingManager; - -public class LightingTask extends SequencedManagerRunnableFactory { - @Override - public ManagerRunnable getTask(final AsyncManager manager, final int sequence) { - return new ManagerRunnable(manager) { - @Override - public void runTask() { - ((LightingManager) manager).runLighting(sequence); - } - }; - } - - @Override - public int getMinSequence() { - return 0; - } - - @Override - public TickStage getTickStage() { - return TickStage.LIGHTING; - } -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalDynamicUpdatesTask.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalDynamicUpdatesTask.java deleted file mode 100644 index 78c2f7e..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalDynamicUpdatesTask.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.DynamicUpdateManager; - -public class LocalDynamicUpdatesTask extends LocalManagerRunnableFactory { - private long threshold = 0; - - @Override - public ManagerRunnable getTask(final AsyncManager manager, final int sequence) { - return new ManagerRunnable(manager) { - @Override - public void runTask() { - ((DynamicUpdateManager) manager).runDynamicUpdates(threshold, sequence); - } - }; - } - - public void setThreshold(long threshold) { - this.threshold = threshold; - } - - @Override - public TickStage getTickStage() { - return TickStage.DYNAMIC_BLOCKS; - } -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalManagerRunnableFactory.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalManagerRunnableFactory.java deleted file mode 100644 index 7bef691..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalManagerRunnableFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -public abstract class LocalManagerRunnableFactory implements ManagerRunnableFactory { - @Override - public int getMaxSequence() { - return -1; - } - - @Override - public int getMinSequence() { - return -1; - } -} diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalPhysicsTask.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalPhysicsTask.java deleted file mode 100644 index ca1b8f6..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/LocalPhysicsTask.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.PhysicsManager; - -public class LocalPhysicsTask extends LocalManagerRunnableFactory { - @Override - public ManagerRunnable getTask(final AsyncManager manager, final int sequence) { - return new ManagerRunnable(manager) { - @Override - public void runTask() { - ((PhysicsManager) manager).runPhysics(sequence); - } - }; - } - - @Override - public TickStage getTickStage() { - return TickStage.PHYSICS; - } -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/ManagerRunnable.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/ManagerRunnable.java deleted file mode 100644 index c1dd67c..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/ManagerRunnable.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import java.util.Objects; -import java.util.concurrent.Callable; -import com.flowpowered.engine.util.thread.AsyncManager; - -public abstract class ManagerRunnable implements Callable { - private final AsyncManager manager; - - public ManagerRunnable(AsyncManager manager) { - this.manager = manager; - } - - @Override - public final Void call() { - runTask(); - return null; - } - - protected abstract void runTask(); - - @Override - public int hashCode() { - int hash = 5; - hash = 89 * hash + Objects.hashCode(this.manager); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final ManagerRunnable other = (ManagerRunnable) obj; - if (!Objects.equals(this.manager, other.manager)) - return false; - return true; - } -} diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/ManagerRunnableFactory.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/ManagerRunnableFactory.java deleted file mode 100644 index 9b25a2e..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/ManagerRunnableFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; - -public interface ManagerRunnableFactory { - public ManagerRunnable getTask(AsyncManager manager, int sequence); - - public int getMaxSequence(); - - public int getMinSequence(); - - public TickStage getTickStage(); -} diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/PreSnapshotTask.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/PreSnapshotTask.java deleted file mode 100644 index 6f848db..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/PreSnapshotTask.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.PreSnapshotManager; - -public class PreSnapshotTask extends LocalManagerRunnableFactory { - @Override - public ManagerRunnable getTask(final AsyncManager manager, final int sequence) { - return new ManagerRunnable(manager) { - @Override - public void runTask() { - ((PreSnapshotManager) manager).preSnapshotRun(); - } - }; - } - - @Override - public TickStage getTickStage() { - return TickStage.PRESNAPSHOT; - } -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/SequencedManagerRunnableFactory.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/SequencedManagerRunnableFactory.java deleted file mode 100644 index 7a7b6c0..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/SequencedManagerRunnableFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -public abstract class SequencedManagerRunnableFactory implements ManagerRunnableFactory { - @Override - public int getMaxSequence() { - return 26; - } - - @Override - public int getMinSequence() { - return -1; - } -} diff --git a/src/main/java/com/flowpowered/engine/util/thread/coretasks/StartTickTask.java b/src/main/java/com/flowpowered/engine/util/thread/coretasks/StartTickTask.java deleted file mode 100644 index b329400..0000000 --- a/src/main/java/com/flowpowered/engine/util/thread/coretasks/StartTickTask.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.engine.util.thread.coretasks; - -import java.util.concurrent.atomic.AtomicLong; - -import com.flowpowered.api.scheduler.TickStage; -import com.flowpowered.engine.util.thread.AsyncManager; -import com.flowpowered.engine.util.thread.StartTickManager; - -public class StartTickTask extends LocalManagerRunnableFactory { - private final int stage; - private final AtomicLong delta; - - public StartTickTask(int stage, AtomicLong delta) { - this.stage = stage; - this.delta = delta; - } - - @Override - public ManagerRunnable getTask(final AsyncManager manager, final int sequence) { - return new ManagerRunnable(manager) { - @Override - public void runTask() { - ((StartTickManager) manager).startTickRun(stage, delta.get()); - } - }; - } - - @Override - public TickStage getTickStage() { - return TickStage.TICKSTART; - } -} \ No newline at end of file diff --git a/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableHashMap.java b/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableHashMap.java index b6efeeb..5a025d0 100644 --- a/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableHashMap.java +++ b/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableHashMap.java @@ -32,7 +32,6 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; -import com.flowpowered.api.scheduler.TickStage; import com.flowpowered.api.util.thread.annotation.DelayedWrite; import com.flowpowered.api.util.thread.annotation.LiveRead; import com.flowpowered.api.util.thread.annotation.SnapshotRead; @@ -149,7 +148,6 @@ public Map getLive() { * @return the list of elements that have been updated */ public List getDirtyKeyList() { - TickStage.checkStage(TickStage.PRESNAPSHOT); return Collections.unmodifiableList(new ArrayList<>(dirtyKeys)); } @@ -160,7 +158,6 @@ public List getDirtyKeyList() { * @return the list of elements that have been updated */ public List getDirtyValueList() { - TickStage.checkStage(TickStage.PRESNAPSHOT); return Collections.unmodifiableList(new ArrayList<>(dirtyValues)); } diff --git a/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableHashSet.java b/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableHashSet.java index e0a15ea..e8248ae 100644 --- a/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableHashSet.java +++ b/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableHashSet.java @@ -31,7 +31,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; -import com.flowpowered.api.scheduler.TickStage; import com.flowpowered.api.util.thread.annotation.DelayedWrite; import com.flowpowered.api.util.thread.annotation.LiveRead; import com.flowpowered.api.util.thread.annotation.SnapshotRead; @@ -115,7 +114,6 @@ public Set getLive() { * @return the list of elements that have been updated */ public List getDirtyList() { - TickStage.checkStage(TickStage.PRESNAPSHOT); return Collections.unmodifiableList(new ArrayList<>(dirty)); } diff --git a/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableLinkedHashMap.java b/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableLinkedHashMap.java index 7090bd5..8fed1ef 100644 --- a/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableLinkedHashMap.java +++ b/src/main/java/com/flowpowered/engine/util/thread/snapshotable/SnapshotableLinkedHashMap.java @@ -34,7 +34,6 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; -import com.flowpowered.api.scheduler.TickStage; import com.flowpowered.api.util.thread.annotation.DelayedWrite; import com.flowpowered.api.util.thread.annotation.LiveRead; import com.flowpowered.api.util.thread.annotation.SnapshotRead; @@ -172,7 +171,6 @@ public Collection getValuesLive() { * @return the list of elements that have been updated */ public List getDirtyList() { - TickStage.checkStage(TickStage.PRESNAPSHOT); if (!dirtyListGenerated) { for (K o : dirty) { if (dirtyListTemp.add(o)) {