Made chunk saving asynchronous, added auto saving and asynchronous
saving, seperated chunks into their own files, made chunks unload to a file instead of to memory, fixed a lighting based performance bug.
This commit is contained in:
parent
c5e36b6f79
commit
76fce435b1
|
|
@ -34,6 +34,7 @@ import projectzombie.settings.Settings;
|
|||
import projectzombie.time.GameTimer;
|
||||
import projectzombie.time.NoSleep;
|
||||
import projectzombie.worker.WorkerChunks;
|
||||
import projectzombie.worker.WorkerFile;
|
||||
import projectzombie.worker.WorkerLighting;
|
||||
import projectzombie.world.World;
|
||||
import projectzombie.world.chunk.ChunkEventHandler;
|
||||
|
|
@ -48,9 +49,11 @@ public class Main
|
|||
public static AudioEngine audio;
|
||||
public static Random rand = new Random();
|
||||
public static Menu menu;
|
||||
public static WorkerFile workerFile;
|
||||
public static WorkerLighting workerLighting;
|
||||
public static WorkerChunks workerChunks;
|
||||
public static WorkerChunks[] workerChunks;
|
||||
public static boolean game_paused = false;
|
||||
public static boolean running = true;
|
||||
public static int tickrate = 10;
|
||||
|
||||
public static void main(String[] args) throws IOException
|
||||
|
|
@ -59,12 +62,19 @@ public class Main
|
|||
{
|
||||
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
|
||||
workerChunks = new WorkerChunks();
|
||||
workerLighting = new WorkerLighting();
|
||||
workerFile = new WorkerFile();
|
||||
workerFile.start();
|
||||
|
||||
workerChunks.start();
|
||||
workerLighting = new WorkerLighting();
|
||||
workerLighting.start();
|
||||
|
||||
workerChunks = new WorkerChunks[4];
|
||||
|
||||
for(int i=0;i<workerChunks.length;i++) {
|
||||
workerChunks[i] = new WorkerChunks();
|
||||
workerChunks[i].start();
|
||||
}
|
||||
|
||||
MathHelpers.init();
|
||||
Settings.init();
|
||||
Environment.init(args);
|
||||
|
|
@ -116,9 +126,8 @@ public class Main
|
|||
|
||||
finally
|
||||
{
|
||||
// Kill the worker thread
|
||||
workerLighting.kill();
|
||||
workerChunks.kill();
|
||||
// Kill the worker threads
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package projectzombie.display;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
|
@ -34,9 +35,9 @@ public class DisplayLighting
|
|||
private static int lighting_last_x = 0;
|
||||
private static int lighting_last_y = 0;
|
||||
private static boolean lighting_dirty = false;
|
||||
private static boolean lighting_new = false;
|
||||
public static int lightmap;
|
||||
|
||||
private static AtomicBoolean lighting_new = new AtomicBoolean(false);
|
||||
private static AtomicReference<Lighting> lighting = new AtomicReference<DisplayLighting.Lighting>();
|
||||
|
||||
public static void setDirty() {
|
||||
|
|
@ -49,7 +50,7 @@ public class DisplayLighting
|
|||
|
||||
private static void setLighting(Lighting lighting) {
|
||||
DisplayLighting.lighting.set(lighting);
|
||||
lighting_new = true;
|
||||
lighting_new.set(true);
|
||||
}
|
||||
|
||||
public DisplayLighting() {
|
||||
|
|
@ -230,23 +231,31 @@ public class DisplayLighting
|
|||
Lighting lighting = getLighting();
|
||||
Layer layer = Main.world.getLayer();
|
||||
|
||||
if(lighting_new.getAndSet(false))
|
||||
{
|
||||
for(int i=0;i<lighting.p.length/3;i++)
|
||||
{
|
||||
int i3 = i*3;
|
||||
int x = i % lighting.w;
|
||||
int y = i / lighting.w;
|
||||
|
||||
Vec2i tpos = new Vec2i(x + lighting.x * 16, y + lighting.y * 16);
|
||||
|
||||
// Store light level data from the image
|
||||
layer.setLightLevel(lighting.p[i3+1], tpos);
|
||||
|
||||
// Store temperature and humidity data
|
||||
lighting.p[i3+1] = (float)layer.getTemperature(new Vec2i(x + lighting.x * 16, y + lighting.y * 16));
|
||||
lighting.p[i3+2] = (float)layer.getHumidity(new Vec2i(x + lighting.x * 16, y + lighting.y * 16));
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the pixels
|
||||
float[] pixels = new float[lighting.p.length];
|
||||
for(int i=0;i<pixels.length;i++) {
|
||||
pixels[i] = lighting.p[i];
|
||||
}
|
||||
|
||||
for(int x2=0;x2<lighting.w;x2++) {
|
||||
for(int y2=0;y2<lighting.h;y2++)
|
||||
{
|
||||
int i = (x2 + y2 * lighting.w) * 3;
|
||||
|
||||
// Send temperature and humidity data to the image
|
||||
pixels[i+1] = (float)layer.getTemperature(new Vec2i(x2 + lighting.x * 16, y2 + lighting.y * 16));
|
||||
pixels[i+2] = (float)layer.getHumidity(new Vec2i(x2 + lighting.x * 16, y2 + lighting.y * 16));
|
||||
}
|
||||
}
|
||||
|
||||
Vec2d ppos = Main.player.getPos().xz();
|
||||
|
||||
calculateEntityLighting(layer, lighting, Main.player, pixels);
|
||||
|
|
@ -266,22 +275,6 @@ public class DisplayLighting
|
|||
}
|
||||
}
|
||||
|
||||
if(lighting_new)
|
||||
{
|
||||
for(int i=0;i<lighting.p.length/3;i++)
|
||||
{
|
||||
int x = i % lighting.w;
|
||||
int y = i / lighting.w;
|
||||
|
||||
Vec2i tpos = new Vec2i(x + lighting.x * 16, y + lighting.y * 16);
|
||||
|
||||
// Store light level data from the image
|
||||
layer.setLightLevel(lighting.p[i*3+1], tpos);
|
||||
}
|
||||
|
||||
lighting_new = false;
|
||||
}
|
||||
|
||||
ByteBuffer pixels_b = BufferUtils.createByteBuffer(pixels.length);
|
||||
|
||||
for(int i=0;i<pixels.length;i++) {
|
||||
|
|
@ -316,6 +309,8 @@ public class DisplayLighting
|
|||
(float)(lighting.y * 16 - Camera.camera.y - 0.5));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void clearLighting()
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ public class EntityPlayer extends Entity implements
|
|||
}
|
||||
|
||||
inventory.addItem(new ItemStack(Items.TORCH, 1));
|
||||
inventory.addItem(new ItemStack(Items.LANTERN, 1));
|
||||
}
|
||||
|
||||
public int getAmmo() {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ public class MainloopEventHandler implements IMainloopEvent, IMainloopTask
|
|||
{
|
||||
public static final MainloopEventHandler MAINLOOP_EVENT_HANDLER = new MainloopEventHandler();
|
||||
|
||||
private long autosave_interval = 0;
|
||||
private long max_mspf = 1;
|
||||
public long mspf = max_mspf;
|
||||
|
||||
|
|
@ -45,7 +46,7 @@ public class MainloopEventHandler implements IMainloopEvent, IMainloopTask
|
|||
|
||||
@Override
|
||||
public boolean MainLoopDelay(long millis) {
|
||||
return millis > 1;
|
||||
return millis > 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -58,6 +59,15 @@ public class MainloopEventHandler implements IMainloopEvent, IMainloopTask
|
|||
{
|
||||
// Stop the mainloop if the window should close
|
||||
if(Main.window.shouldClose()) Main.mainloop.stop();
|
||||
|
||||
// Autosave every minute
|
||||
autosave_interval += 1;
|
||||
if(autosave_interval > 6000)
|
||||
{
|
||||
autosave_interval -= 6000;
|
||||
|
||||
Main.world.save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,6 @@ public class MenuGamePause extends Menu
|
|||
public void saveAndQuit()
|
||||
{
|
||||
Main.world.save();
|
||||
Main.menu = new MenuMain();
|
||||
Main.menu = new MenuSavingWorld();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
package projectzombie.menu;
|
||||
|
||||
import gl_engine.matrix.Matrix4;
|
||||
import gl_engine.vec.Vec3d;
|
||||
import projectzombie.Main;
|
||||
import projectzombie.init.Models;
|
||||
import projectzombie.input.types.InputGUI;
|
||||
import projectzombie.menu.gui.GUI;
|
||||
import projectzombie.menu.gui.GUIAlignment;
|
||||
import projectzombie.menu.gui.GUILabel;
|
||||
import projectzombie.util.gl.GlHelpers;
|
||||
import projectzombie.worker.WorkerChunks;
|
||||
import projectzombie.world.chunk.ChunkEventHandler;
|
||||
|
||||
public class MenuSavingWorld extends Menu
|
||||
{
|
||||
private GUI gui;
|
||||
|
||||
public MenuSavingWorld()
|
||||
{
|
||||
doGameloop = true;
|
||||
doGameRender = true;
|
||||
keepMouse = false;
|
||||
showIngameGUI = false;
|
||||
|
||||
GUILabel label = new GUILabel();
|
||||
label.setText("Saving world...");
|
||||
label.setAlign(GUIAlignment.CENTRE);
|
||||
|
||||
gui = new GUI();
|
||||
input = new InputGUI(gui);
|
||||
|
||||
gui.add(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
double a = GlHelpers.getAspectRatio();
|
||||
|
||||
for(int x = 0; x < 16; x ++) {
|
||||
for(int y = 0; y < 16; y ++)
|
||||
{
|
||||
Models.UI_STONE_BG.setModel(Matrix4.multiply(
|
||||
Matrix4.scale(new Vec3d(1.25 * a, 1.25 * a, 1)),
|
||||
Matrix4.translate(new Vec3d(-10 * a + 1.25 * a * x, -10 * a + 1.25 * a * y, 0))));
|
||||
Models.UI_STONE_BG.render();
|
||||
}
|
||||
}
|
||||
|
||||
gui.render();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
super.update();
|
||||
|
||||
if(WorkerChunks.isDone()) {
|
||||
Main.menu = new MenuMain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,13 @@
|
|||
package projectzombie.menu;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.FileVisitor;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
import bdf.file.BdfFileManager;
|
||||
import bdf.types.BdfArray;
|
||||
|
|
@ -22,7 +29,6 @@ public class MenuWorldDelete extends Menu
|
|||
{
|
||||
|
||||
private MenuSaves parent;
|
||||
private String name;
|
||||
private String path;
|
||||
|
||||
private GUI gui;
|
||||
|
|
@ -30,7 +36,6 @@ public class MenuWorldDelete extends Menu
|
|||
public MenuWorldDelete(MenuSaves parent, String name, String path)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
|
||||
keepMouse = false;
|
||||
|
|
@ -85,8 +90,37 @@ public class MenuWorldDelete extends Menu
|
|||
BdfNamedList nl = bdf.getNamedList();
|
||||
BdfArray array = nl.get("saves").getArray();
|
||||
|
||||
File save_file = new File("./saves/" + path + ".bdf");
|
||||
save_file.delete();
|
||||
try
|
||||
{
|
||||
Files.walkFileTree(Paths.get("./saves/" + path), new FileVisitor<Path>()
|
||||
{
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for(int i=0;i<array.size();i++) {
|
||||
BdfNamedList world_nl = array.get(i).getNamedList();
|
||||
|
|
|
|||
|
|
@ -7,19 +7,7 @@ import projectzombie.world.chunk.Chunk;
|
|||
import projectzombie.world.layer.Layer;
|
||||
import projectzombie.world.layer.layergen.LayerGen;
|
||||
|
||||
class WorkerChunkTask
|
||||
abstract class WorkerChunkTask
|
||||
{
|
||||
Chunk chunk;
|
||||
LayerGen layergen;
|
||||
Layer layer;
|
||||
Random rand;
|
||||
Vec2i pos;
|
||||
|
||||
public WorkerChunkTask(LayerGen layergen, Layer layer, Chunk chunk, Random rand, Vec2i pos) {
|
||||
this.chunk = chunk;
|
||||
this.layergen = layergen;
|
||||
this.layer = layer;
|
||||
this.rand = rand;
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package projectzombie.worker;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import gl_engine.vec.Vec2i;
|
||||
import projectzombie.world.chunk.Chunk;
|
||||
import projectzombie.world.layer.Layer;
|
||||
import projectzombie.world.layer.layergen.LayerGen;
|
||||
|
||||
class WorkerChunkTaskGenerate extends WorkerChunkTask
|
||||
{
|
||||
Chunk chunk;
|
||||
LayerGen layergen;
|
||||
Layer layer;
|
||||
Random rand;
|
||||
|
||||
public WorkerChunkTaskGenerate(LayerGen layergen, Layer layer, Chunk chunk, Random rand, Vec2i pos) {
|
||||
this.chunk = chunk;
|
||||
this.layergen = layergen;
|
||||
this.layer = layer;
|
||||
this.rand = rand;
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package projectzombie.worker;
|
||||
|
||||
import gl_engine.vec.Vec2i;
|
||||
import projectzombie.world.layer.Layer;
|
||||
|
||||
public class WorkerChunkTaskLoad extends WorkerChunkTask
|
||||
{
|
||||
String path;
|
||||
Layer layer;
|
||||
|
||||
public WorkerChunkTaskLoad(String path, Layer layer, Vec2i pos) {
|
||||
this.path = path;
|
||||
this.layer = layer;
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package projectzombie.worker;
|
||||
|
||||
import gl_engine.vec.Vec2i;
|
||||
import projectzombie.world.chunk.Chunk;
|
||||
|
||||
public class WorkerChunkTaskSave extends WorkerChunkTask
|
||||
{
|
||||
Chunk chunk;
|
||||
String path;
|
||||
int id;
|
||||
|
||||
public WorkerChunkTaskSave(String path, Vec2i pos, Chunk chunk, int id) {
|
||||
this.path = path;
|
||||
this.pos = pos;
|
||||
this.chunk = chunk;
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,31 +5,45 @@ import java.util.Vector;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import bdf.file.BdfFileManager;
|
||||
import gl_engine.vec.Vec2i;
|
||||
import projectzombie.Main;
|
||||
import projectzombie.world.chunk.Chunk;
|
||||
import projectzombie.world.layer.Layer;
|
||||
import projectzombie.world.layer.layergen.LayerGen;
|
||||
|
||||
public class WorkerChunks extends Thread
|
||||
{
|
||||
private boolean running = false;
|
||||
private Vector<WorkerChunkTask> chunks_in = new Vector<WorkerChunkTask>();
|
||||
private AtomicReference<Vector<Chunk>> chunks_out = new AtomicReference<Vector<Chunk>>();
|
||||
private static Vector<WorkerChunkTask> chunks_in = new Vector<WorkerChunkTask>();
|
||||
private static AtomicReference<Vector<Chunk>> chunks_out = new AtomicReference<Vector<Chunk>>();
|
||||
|
||||
public void generateChunk(LayerGen layergen, Layer layer, Chunk chunk, Random rand, Vec2i pos) {
|
||||
chunks_in.add(new WorkerChunkTask(layergen, layer, chunk, rand, pos));
|
||||
public static void generateChunk(LayerGen layergen, Layer layer, Chunk chunk, Random rand, Vec2i pos) {
|
||||
chunks_in.add(new WorkerChunkTaskGenerate(layergen, layer, chunk, rand, pos.copy()));
|
||||
}
|
||||
|
||||
public Vector<Chunk> getChunks() {
|
||||
public static void loadChunk(String path, Layer layer, Vec2i pos) {
|
||||
chunks_in.add(new WorkerChunkTaskLoad(path, layer, pos.copy()));
|
||||
}
|
||||
|
||||
public static void saveChunk(String path, Vec2i pos, Chunk chunk, int id) {
|
||||
chunks_in.add(new WorkerChunkTaskSave(path, pos.copy(), chunk, id));
|
||||
}
|
||||
|
||||
public static Vector<Chunk> getChunks() {
|
||||
return chunks_out.getAndSet(new Vector<Chunk>());
|
||||
}
|
||||
|
||||
public boolean hasChunk(Vec2i cpos)
|
||||
public static boolean hasChunk(Vec2i cpos)
|
||||
{
|
||||
boolean has[] = {false};
|
||||
|
||||
chunks_in.forEach(c -> {
|
||||
if(c.pos.equal(cpos)) {
|
||||
chunks_in.forEach(c ->
|
||||
{
|
||||
if(
|
||||
(c instanceof WorkerChunkTaskGenerate ||
|
||||
c instanceof WorkerChunkTaskLoad) &&
|
||||
c.pos.equal(cpos))
|
||||
{
|
||||
has[0] = true;
|
||||
}
|
||||
});
|
||||
|
|
@ -41,31 +55,80 @@ public class WorkerChunks extends Thread
|
|||
chunks_out.set(new Vector<Chunk>());
|
||||
}
|
||||
|
||||
private synchronized WorkerChunkTask getNextIfAvailable()
|
||||
{
|
||||
if(chunks_in.size() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return chunks_in.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
running = true;
|
||||
|
||||
try
|
||||
{
|
||||
while(running)
|
||||
while(Main.running)
|
||||
{
|
||||
if(chunks_in.size() == 0) {
|
||||
Thread.sleep(1);
|
||||
WorkerChunkTask ct = getNextIfAvailable();
|
||||
|
||||
if(ct == null) {
|
||||
Thread.sleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
WorkerChunkTask ct = chunks_in.remove(0);
|
||||
// Generate a new chunk
|
||||
if(ct instanceof WorkerChunkTaskGenerate)
|
||||
{
|
||||
WorkerChunkTaskGenerate ct_g = (WorkerChunkTaskGenerate)ct;
|
||||
|
||||
Chunk chunk = ct.chunk;
|
||||
LayerGen layergen = ct.layergen;
|
||||
Layer layer = ct.layer;
|
||||
Random rand = ct.rand;
|
||||
Vec2i pos = ct.pos;
|
||||
ct_g.layergen.generateChunk(ct_g.chunk, ct_g.layer, ct_g.rand, ct_g.pos);
|
||||
|
||||
layergen.generateChunk(chunk, layer, rand, pos);
|
||||
chunks_out.get().add(ct_g.chunk);
|
||||
}
|
||||
|
||||
chunks_out.get().add(chunk);
|
||||
// Load an existing chunk
|
||||
if(ct instanceof WorkerChunkTaskLoad)
|
||||
{
|
||||
WorkerChunkTaskLoad ct_l = (WorkerChunkTaskLoad)ct;
|
||||
|
||||
if(ct_l.path == null) {
|
||||
System.out.println("ChunkLoad: Path is NULL");
|
||||
continue;
|
||||
}
|
||||
|
||||
String path = (
|
||||
"./saves/" + ct_l.path + "/c_" + ct_l.layer.id +
|
||||
"_" + ct_l.pos.x + "_" + ct_l.pos.y + ".bdf");
|
||||
|
||||
BdfFileManager reader = new BdfFileManager(path, true);
|
||||
|
||||
Chunk chunk = new Chunk(ct_l.layer, ct_l.pos, reader.getObject());
|
||||
|
||||
chunks_out.get().add(chunk);
|
||||
}
|
||||
|
||||
// Save a chunk
|
||||
if(ct instanceof WorkerChunkTaskSave)
|
||||
{
|
||||
WorkerChunkTaskSave ct_s = (WorkerChunkTaskSave)ct;
|
||||
|
||||
if(ct_s.path == null) {
|
||||
System.out.println("ChunkSave: Path is NULL");
|
||||
continue;
|
||||
}
|
||||
|
||||
String path = (
|
||||
"./saves/" + ct_s.path + "/c_" + ct_s.id +
|
||||
"_" + ct_s.pos.x + "_" + ct_s.pos.y + ".bdf");
|
||||
|
||||
BdfFileManager reader = new BdfFileManager(path, true);
|
||||
|
||||
ct_s.chunk.BdfClassSave(reader.getObject());
|
||||
|
||||
reader.saveDatabase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +137,7 @@ public class WorkerChunks extends Thread
|
|||
}
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
running = false;
|
||||
public static boolean isDone() {
|
||||
return chunks_in.size() == 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
package projectzombie.worker;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Vector;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import bdf.types.BdfReader;
|
||||
import projectzombie.Main;
|
||||
|
||||
public class WorkerFile extends Thread
|
||||
{
|
||||
private static Vector<WorkerFileTask> tasks = new Vector<WorkerFileTask>();
|
||||
|
||||
public static void addTask(String path, BdfReader reader) {
|
||||
tasks.add(new WorkerFileTask(path, reader));
|
||||
}
|
||||
|
||||
private synchronized WorkerFileTask getNextIfAvailable()
|
||||
{
|
||||
if(tasks.size() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return tasks.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
while(Main.running)
|
||||
{
|
||||
WorkerFileTask task = getNextIfAvailable();
|
||||
|
||||
if(task == null) {
|
||||
Thread.sleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
OutputStream out = new FileOutputStream(task.path);
|
||||
out = new GZIPOutputStream(out);
|
||||
|
||||
task.reader.serialize().writeToStream(out);
|
||||
|
||||
out.close();
|
||||
}
|
||||
|
||||
catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch(InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package projectzombie.worker;
|
||||
|
||||
import bdf.types.BdfReader;
|
||||
|
||||
class WorkerFileTask
|
||||
{
|
||||
String path;
|
||||
BdfReader reader;
|
||||
|
||||
public WorkerFileTask(String path, BdfReader reader) {
|
||||
this.reader = reader;
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package projectzombie.worker;
|
|||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import projectzombie.Main;
|
||||
import projectzombie.display.DisplayLighting;
|
||||
import projectzombie.task.Task;
|
||||
|
||||
|
|
@ -15,7 +16,6 @@ public class WorkerLighting extends Thread
|
|||
int y;
|
||||
}
|
||||
|
||||
private boolean running;
|
||||
private AtomicReference<LightingTask> task = new AtomicReference<WorkerLighting.LightingTask>();
|
||||
|
||||
public void processLighting(float[] lights, int width, int height, int x, int y)
|
||||
|
|
@ -71,16 +71,13 @@ public class WorkerLighting extends Thread
|
|||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
super.run();
|
||||
|
||||
running = true;
|
||||
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
while(running)
|
||||
while(Main.running)
|
||||
{
|
||||
LightingTask task = this.task.get();
|
||||
LightingTask task = this.task.getAndSet(null);
|
||||
|
||||
if(task != null)
|
||||
{
|
||||
|
|
@ -101,7 +98,7 @@ public class WorkerLighting extends Thread
|
|||
}
|
||||
|
||||
else {
|
||||
Thread.sleep(1);
|
||||
Thread.sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -110,8 +107,4 @@ public class WorkerLighting extends Thread
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import bdf.file.BdfFileManager;
|
|||
import bdf.types.BdfArray;
|
||||
import bdf.types.BdfNamedList;
|
||||
import bdf.types.BdfObject;
|
||||
import bdf.types.BdfReader;
|
||||
import gl_engine.matrix.Matrix4;
|
||||
import gl_engine.vec.Vec3d;
|
||||
import projectzombie.Main;
|
||||
|
|
@ -25,6 +26,7 @@ import projectzombie.init.Layers;
|
|||
import projectzombie.menu.MenuLoadingWorld;
|
||||
import projectzombie.model.Model;
|
||||
import projectzombie.time.GameTimer;
|
||||
import projectzombie.worker.WorkerFile;
|
||||
import projectzombie.world.chunk.ChunkEventHandler;
|
||||
import projectzombie.world.layer.Layer;
|
||||
|
||||
|
|
@ -38,7 +40,6 @@ public class World implements IBdfClassManager
|
|||
|
||||
private Layer loaded;
|
||||
private ArrayList<Layer> layers = new ArrayList<Layer>();
|
||||
private BdfFileManager file_manager;
|
||||
|
||||
private String path;
|
||||
private int pool_vao, pool_vbo, pool_ibo;
|
||||
|
|
@ -51,22 +52,18 @@ public class World implements IBdfClassManager
|
|||
|
||||
if(path != null)
|
||||
{
|
||||
path = "./saves/" + path + ".bdf";
|
||||
File save_file = new File(path);
|
||||
File save_dir = save_file.getParentFile();
|
||||
path = "./saves/" + path + "/";
|
||||
File save_dir = new File(path);
|
||||
File file_dir = new File(path + "world.bdf");
|
||||
|
||||
if(!save_dir.exists()) {
|
||||
save_dir.mkdirs();
|
||||
}
|
||||
|
||||
if(save_file.exists()) {
|
||||
file_manager = new BdfFileManager(path);
|
||||
if(file_dir.exists()) {
|
||||
BdfFileManager file_manager = new BdfFileManager(path + "world.bdf", true);
|
||||
BdfClassLoad(file_manager.getObject());
|
||||
}
|
||||
|
||||
else {
|
||||
file_manager = new BdfFileManager(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,12 +262,17 @@ public class World implements IBdfClassManager
|
|||
|
||||
public void save()
|
||||
{
|
||||
if(file_manager != null)
|
||||
if(path != null)
|
||||
{
|
||||
BdfObject bdf = file_manager.resetObject();
|
||||
for(Layer layer : layers) {
|
||||
layer.save();
|
||||
}
|
||||
|
||||
BdfReader reader = new BdfReader();
|
||||
BdfObject bdf = reader.getObject();
|
||||
BdfClassSave(bdf);
|
||||
|
||||
file_manager.saveDatabase();
|
||||
WorkerFile.addTask("./saves/" + path + "/world.bdf", reader);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public class Chunk implements IBdfClassManager
|
|||
private byte tiles_temperature[] = new byte[CHUNK_INDEX];
|
||||
private byte tiles_humidity[] = new byte[CHUNK_INDEX];
|
||||
public ArrayList<Entity> entities = new ArrayList<Entity>();
|
||||
private Layer layer;
|
||||
public Layer layer;
|
||||
public Vec2i c_pos;
|
||||
private boolean dirty;
|
||||
private boolean light_dirty;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import mainloop.task.IMainloopTask;
|
|||
import projectzombie.Main;
|
||||
import projectzombie.display.DisplayLighting;
|
||||
import projectzombie.util.math.map.Map2DElement;
|
||||
import projectzombie.worker.WorkerChunks;
|
||||
import projectzombie.world.layer.Layer;
|
||||
|
||||
public class ChunkEventHandler implements IMainloopTask
|
||||
|
|
@ -73,7 +74,7 @@ public class ChunkEventHandler implements IMainloopTask
|
|||
Vec2i c_pos = new Vec2i(cx, cy);
|
||||
|
||||
// Is this chunk not loaded
|
||||
if(!layer.chunkLoaded(c_pos) && !Main.workerChunks.hasChunk(c_pos))
|
||||
if(!layer.chunkLoaded(c_pos) && !WorkerChunks.hasChunk(c_pos))
|
||||
{
|
||||
// Load the chunk
|
||||
layer.loadChunk(c_pos);
|
||||
|
|
|
|||
|
|
@ -21,14 +21,15 @@ import projectzombie.util.math.TileState;
|
|||
import projectzombie.util.math.map.Map2D;
|
||||
import projectzombie.util.math.map.Map2DElement;
|
||||
import projectzombie.util.math.random.NoiseGenerator;
|
||||
import projectzombie.worker.WorkerChunks;
|
||||
import projectzombie.world.chunk.Chunk;
|
||||
import projectzombie.world.layer.layergen.LayerGen;
|
||||
|
||||
public class Layer implements IBdfClassManager
|
||||
{
|
||||
public Map2D<Chunk> chunks;
|
||||
private Map2D<Chunk> dirty_chunks;
|
||||
public NoiseGenerator[] noise_gens;
|
||||
public ArrayList<Vec2i> chunks_saved;
|
||||
public LayerGen layergen;
|
||||
private Random rand;
|
||||
public long lseed;
|
||||
|
|
@ -43,7 +44,7 @@ public class Layer implements IBdfClassManager
|
|||
this.seed = rand.nextLong();
|
||||
this.lseed = this.rand.nextLong();
|
||||
this.chunks = new Map2D<Chunk>(layergen);
|
||||
this.dirty_chunks = new Map2D<Chunk>(layergen);
|
||||
this.chunks_saved = new ArrayList<Vec2i>();
|
||||
|
||||
this.layergen.init(this);
|
||||
}
|
||||
|
|
@ -268,19 +269,34 @@ public class Layer implements IBdfClassManager
|
|||
|
||||
public void loadChunks()
|
||||
{
|
||||
for(Chunk chunk : Main.workerChunks.getChunks())
|
||||
WorkerChunks.getChunks().forEach(chunk ->
|
||||
{
|
||||
if(chunk.layer != this) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vec2i pos = chunk.c_pos;
|
||||
chunks.set(pos, chunk);
|
||||
chunk.clearDirty();
|
||||
});
|
||||
}
|
||||
|
||||
private boolean hasSavedChunk(Vec2i check)
|
||||
{
|
||||
for(Vec2i pos : chunks_saved) {
|
||||
if(pos.equal(check)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void loadChunk(Vec2i pos)
|
||||
{
|
||||
// Has the chunk been saved for later
|
||||
if(dirty_chunks.contains(pos)) {
|
||||
chunks.set(pos, dirty_chunks.get(pos));
|
||||
if(hasSavedChunk(pos)) {
|
||||
WorkerChunks.loadChunk(Main.world.getSavePath(), this, pos);
|
||||
}
|
||||
|
||||
else
|
||||
|
|
@ -290,7 +306,7 @@ public class Layer implements IBdfClassManager
|
|||
|
||||
// Create and generate the chunk
|
||||
Chunk chunk = new Chunk(this, pos, rand);
|
||||
Main.workerChunks.generateChunk(layergen, this, chunk, new Random(cseed), pos);
|
||||
WorkerChunks.generateChunk(layergen, this, chunk, new Random(cseed), pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -298,8 +314,13 @@ public class Layer implements IBdfClassManager
|
|||
{
|
||||
// Store the chunk if its a dirty chunk
|
||||
Chunk chunk = chunks.get(pos);
|
||||
if(chunk.isDirty()) {
|
||||
dirty_chunks.set(pos, chunk);
|
||||
if(chunk.isDirty())
|
||||
{
|
||||
WorkerChunks.saveChunk(Main.world.getSavePath(), pos, chunk, id);
|
||||
|
||||
if(!hasSavedChunk(pos)) {
|
||||
chunks_saved.add(pos);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the chunk
|
||||
|
|
@ -341,21 +362,19 @@ public class Layer implements IBdfClassManager
|
|||
{
|
||||
BdfNamedList nl = bdf.getNamedList();
|
||||
|
||||
this.layergen = LayerGenerators.loadFromID(nl.get("lgen").getInteger());
|
||||
this.dirty_chunks = new Map2D<Chunk>(layergen);
|
||||
BdfArray bdf_chunks = nl.get("chunks").getArray();
|
||||
|
||||
this.layergen = LayerGenerators.loadFromID((int)nl.get("lgen").getAutoInt());
|
||||
this.chunks_saved = new ArrayList<Vec2i>(bdf_chunks.size());
|
||||
this.chunks = new Map2D<Chunk>(layergen);
|
||||
this.seed = nl.get("seed").getLong();
|
||||
this.lseed = nl.get("lseed").getLong();
|
||||
this.id = nl.get("id").getInteger();
|
||||
this.id = (int)nl.get("id").getAutoInt();
|
||||
this.rand = new Random();
|
||||
|
||||
BdfArray bdf_chunks = nl.get("chunks").getArray();
|
||||
|
||||
for(BdfObject bdf_chunk : bdf_chunks) {
|
||||
BdfNamedList chunk_nl = bdf_chunk.getNamedList();
|
||||
Vec2i cpos = new Vec2i(chunk_nl.get("pos"));
|
||||
Chunk chunk = new Chunk(this, cpos, chunk_nl.get("chunk"));
|
||||
dirty_chunks.set(cpos, chunk);
|
||||
Vec2i c = new Vec2i(bdf_chunk);
|
||||
chunks_saved.add(c);
|
||||
}
|
||||
|
||||
layergen.init(this);
|
||||
|
|
@ -368,28 +387,29 @@ public class Layer implements IBdfClassManager
|
|||
|
||||
nl.set("lseed", bdf.newObject().setLong(lseed));
|
||||
nl.set("seed", bdf.newObject().setLong(seed));
|
||||
nl.set("id", bdf.newObject().setInteger(id));
|
||||
nl.set("lgen", bdf.newObject().setInteger(LayerGenerators.getLGID(this.layergen)));
|
||||
nl.set("id", bdf.newObject().setAutoInt(id));
|
||||
nl.set("lgen", bdf.newObject().setAutoInt(LayerGenerators.getLGID(this.layergen)));
|
||||
|
||||
BdfArray bdf_chunks = nl.get("chunks").getArray();
|
||||
BdfArray bdf_chunks = bdf.newArray(chunks_saved.size());
|
||||
nl.set("chunks", bdf.newObject().setArray(bdf_chunks));
|
||||
|
||||
for(Map2DElement<Chunk> chunk : dirty_chunks) {
|
||||
BdfNamedList chunk_nl = bdf.newNamedList();
|
||||
chunk.pos.BdfClassSave(chunk_nl.get("pos"));
|
||||
chunk.o.BdfClassSave(chunk_nl.get("chunk"));
|
||||
bdf_chunks.add(bdf.newObject().setNamedList(chunk_nl));
|
||||
for(int i=0;i<chunks_saved.size();i++) {
|
||||
chunks_saved.get(i).BdfClassSave(bdf_chunks.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
for(Map2DElement<Chunk> chunk : chunks) {
|
||||
if(dirty_chunks.contains(chunk.pos))
|
||||
continue;
|
||||
if(!chunk.o.isDirty())
|
||||
continue;
|
||||
public void save()
|
||||
{
|
||||
for(Map2DElement<Chunk> chunk : chunks)
|
||||
{
|
||||
if(chunk.o.isDirty())
|
||||
{
|
||||
WorkerChunks.saveChunk(Main.world.getSavePath(), chunk.pos, chunk.o, id);
|
||||
|
||||
BdfNamedList chunk_nl = bdf.newNamedList();
|
||||
chunk.pos.BdfClassSave(chunk_nl.get("pos"));
|
||||
chunk.o.BdfClassSave(chunk_nl.get("chunk"));
|
||||
bdf_chunks.add(bdf.newObject().setNamedList(chunk_nl));
|
||||
if(!hasSavedChunk(chunk.pos)) {
|
||||
chunks_saved.add(chunk.pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue