Skip to content

Commit 813a148

Browse files
fixed water and changed to multithreaded lighting and block updates
1 parent 69bef4c commit 813a148

File tree

6 files changed

+42
-24
lines changed

6 files changed

+42
-24
lines changed

include/block/builtin/air.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ class Air final : public BlockDescriptor
4848
{
4949
return true;
5050
}
51+
virtual bool isReplaceableByFluid() const override
52+
{
53+
return true;
54+
}
5155
virtual bool isGroundBlock() const override
5256
{
5357
return false;

include/block/builtin/furnace.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class Furnace final : public FullBlock
9393
{
9494
fuelStack = temp.item.descriptor->getItemAfterBurnInFurnace();
9595
}
96-
getDebugLog() << L"consumeFuel" << postnl;
96+
//getDebugLog() << L"consumeFuel" << postnl;
9797
return true;
9898
}
9999
bool canProgressSmeltIgnoringFuel()
@@ -129,7 +129,7 @@ class Furnace final : public FullBlock
129129
inputStack.remove(inputStack.item);
130130
if(!inputStack.good())
131131
currentElapsedSmeltTime = 0;
132-
getDebugLog() << L"smeltItem" << postnl;
132+
//getDebugLog() << L"smeltItem" << postnl;
133133
}
134134
};
135135
struct FurnaceBlockData final : BlockData
@@ -211,7 +211,7 @@ class Furnace final : public FullBlock
211211
data->currentElapsedSmeltTime = 0;
212212
return;
213213
}
214-
getDebugLog() << L"currentElapsedSmeltTime = " << data->currentElapsedSmeltTime << L", burnTimeLeft = " << data->burnTimeLeft << postnl;
214+
//getDebugLog() << L"currentElapsedSmeltTime = " << data->currentElapsedSmeltTime << L", burnTimeLeft = " << data->burnTimeLeft << postnl;
215215
if(!hasFuel)
216216
{
217217
data->currentElapsedSmeltTime -= 2 * deltaTime;

include/ui/gameui.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class GameUi : public Ui
8383
if(GameVersion::DEBUG)
8484
gameInput->paused.set(true);
8585
PositionF startingPosition = PositionF(0.5f, World::SeaLevel + 8.5f, 0.5f, Dimension::Overworld);
86-
viewPoint = std::make_shared<ViewPoint>(world, startingPosition, GameVersion::DEBUG ? 48 : 64);
86+
viewPoint = std::make_shared<ViewPoint>(world, startingPosition, GameVersion::DEBUG ? 32 : 48);
8787
player = std::make_shared<Player>(L"default-player-name", gameInput, this);
8888
playerEntity = world.addEntity(Entities::builtin::PlayerEntity::descriptor(), startingPosition, VectorF(0), lock_manager, std::static_pointer_cast<void>(player));
8989
}

include/util/block_chunk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <condition_variable>
4444
#include "util/linked_map.h"
4545
#include <vector>
46+
#include <chrono>
4647

4748
namespace programmerjake
4849
{
@@ -236,6 +237,8 @@ struct BlockChunkChunkVariables final
236237
std::mutex blockUpdateListLock;
237238
BlockUpdate *blockUpdateListHead = nullptr;
238239
BlockUpdate *blockUpdateListTail = nullptr;
240+
std::chrono::steady_clock::time_point lastBlockUpdateTime;
241+
bool lastBlockUpdateTimeValid = false;
239242
std::recursive_mutex entityListLock;
240243
WrappedEntity::ChunkListType entityList;
241244
std::atomic_bool generated, generateStarted;

include/world/world.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,8 @@ class World final
483483
const WorldGenerator *worldGenerator;
484484
SeedType worldGeneratorSeed;
485485
WorldLightingProperties lighting;
486-
std::thread lightingThread;
487-
std::thread blockUpdateThread;
486+
std::list<std::thread> lightingThreads;
487+
std::list<std::thread> blockUpdateThreads;
488488
std::thread particleGeneratingThread;
489489
std::list<std::thread> chunkGeneratingThreads;
490490
std::atomic_bool destructing, lightingStable;
@@ -496,7 +496,7 @@ class World final
496496
void chunkGeneratingThreadFn();
497497
void particleGeneratingThreadFn();
498498
static BlockUpdate *removeAllBlockUpdatesInChunk(BlockUpdateKind kind, BlockIterator bi, WorldLockManager &lock_manager);
499-
static BlockUpdate *removeAllReadyBlockUpdatesInChunk(float deltaTime, BlockIterator bi, WorldLockManager &lock_manager);
499+
static BlockUpdate *removeAllReadyBlockUpdatesInChunk(BlockIterator bi, WorldLockManager &lock_manager);
500500
static Lighting getBlockLighting(BlockIterator bi, WorldLockManager &lock_manager, bool isTopFace);
501501
float getChunkGeneratePriority(BlockIterator bi, WorldLockManager &lock_manager); /// low values mean high priority, NAN means don't generate
502502
RayCasting::Collision castRayCheckForEntitiesInSubchunk(BlockIterator sbi, RayCasting::Ray ray, WorldLockManager &lock_manager, float maxSearchDistance, const Entity *ignoreEntity);

src/world/world.cpp

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "item/builtin/ores.h"
4848
#include "item/builtin/cobblestone.h"
4949
#include "item/builtin/furnace.h"
50+
#include "item/builtin/bucket.h"
5051

5152
using namespace std;
5253

@@ -392,6 +393,7 @@ class MyWorldGenerator final : public RandomWorldGenerator
392393
ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::CoalOre::descriptor())), PositionF(0, 80, 0, Dimension::Overworld));
393394
ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::GoldOre::descriptor())), PositionF(0, 80, 0, Dimension::Overworld));
394395
ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::Furnace::descriptor())), PositionF(0, 80, 0, Dimension::Overworld));
396+
ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::WaterBucket::descriptor())), PositionF(0, 80, 0, Dimension::Overworld));
395397
}
396398
}
397399
#endif
@@ -466,12 +468,18 @@ BlockUpdate *World::removeAllBlockUpdatesInChunk(BlockUpdateKind kind, BlockIter
466468
return retval;
467469
}
468470

469-
BlockUpdate *World::removeAllReadyBlockUpdatesInChunk(float deltaTime, BlockIterator bi, WorldLockManager &lock_manager)
471+
BlockUpdate *World::removeAllReadyBlockUpdatesInChunk(BlockIterator bi, WorldLockManager &lock_manager)
470472
{
471473
BlockChunk *chunk = bi.chunk;
472474
lock_manager.clear();
473475
BlockChunkFullLock lockChunk(*chunk);
474476
auto lockIt = std::unique_lock<decltype(chunk->chunkVariables.blockUpdateListLock)>(chunk->chunkVariables.blockUpdateListLock);
477+
float deltaTime = 0;
478+
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
479+
if(chunk->chunkVariables.lastBlockUpdateTimeValid)
480+
deltaTime = std::chrono::duration_cast<std::chrono::duration<double>>(now - chunk->chunkVariables.lastBlockUpdateTime).count();
481+
chunk->chunkVariables.lastBlockUpdateTimeValid = true;
482+
chunk->chunkVariables.lastBlockUpdateTime = now;
475483
BlockUpdate *retval = nullptr;
476484
for(BlockUpdate *node = chunk->chunkVariables.blockUpdateListHead; node != nullptr;)
477485
{
@@ -532,10 +540,13 @@ World::World(SeedType seed, const WorldGenerator *worldGenerator)
532540
}
533541
break;
534542
}
535-
lightingThread = thread([this]()
543+
for(int i = 0; i < 2; i++)
536544
{
537-
lightingThreadFn();
538-
});
545+
lightingThreads.emplace_back([this]()
546+
{
547+
lightingThreadFn();
548+
});
549+
}
539550
for(int dx = 0; dx >= -1; dx--)
540551
{
541552
for(int dz = 0; dz >= -1; dz--)
@@ -547,10 +558,13 @@ World::World(SeedType seed, const WorldGenerator *worldGenerator)
547558
initialChunk->chunkVariables.generated = true;
548559
}
549560
}
550-
blockUpdateThread = thread([this]()
561+
for(int i = 0; i < 3; i++)
551562
{
552-
blockUpdateThreadFn();
553-
});
563+
blockUpdateThreads.emplace_back([this]()
564+
{
565+
blockUpdateThreadFn();
566+
});
567+
}
554568
lock_manager.clear();
555569
getDebugLog() << L"lighting initial world..." << postnl;
556570
for(int i = 0; i < 500 && !isLightingStable(); i++)
@@ -579,10 +593,12 @@ World::~World()
579593
{
580594
assert(viewPoints.empty());
581595
destructing = true;
582-
if(lightingThread.joinable())
583-
lightingThread.join();
584-
if(blockUpdateThread.joinable())
585-
blockUpdateThread.join();
596+
for(auto &t : lightingThreads)
597+
if(t.joinable())
598+
t.join();
599+
for(auto &t : blockUpdateThreads)
600+
if(t.joinable())
601+
t.join();
586602
for(auto &t : chunkGeneratingThreads)
587603
if(t.joinable())
588604
t.join();
@@ -682,13 +698,9 @@ void World::blockUpdateThreadFn()
682698
setThreadPriority(ThreadPriority::Low);
683699
WorldLockManager lock_manager;
684700
BlockChunkMap *chunks = &physicsWorld->chunks;
685-
auto lastUpdateTime = std::chrono::steady_clock::now();
686701
while(!destructing)
687702
{
688703
bool didAnything = false;
689-
auto currentUpdateTime = std::chrono::steady_clock::now();
690-
float deltaTime = std::chrono::duration_cast<std::chrono::duration<float>>(currentUpdateTime - lastUpdateTime).count();
691-
lastUpdateTime = currentUpdateTime;
692704
for(auto chunkIter = chunks->begin(); chunkIter != chunks->end(); chunkIter++)
693705
{
694706
if(destructing)
@@ -697,7 +709,7 @@ void World::blockUpdateThreadFn()
697709
if(chunkIter.is_locked())
698710
chunkIter.unlock();
699711
BlockIterator cbi(chunk, chunks, chunk->basePosition, VectorI(0));
700-
for(BlockUpdate *node = removeAllReadyBlockUpdatesInChunk(deltaTime, cbi, lock_manager); node != nullptr; node = removeAllReadyBlockUpdatesInChunk(0, cbi, lock_manager))
712+
for(BlockUpdate *node = removeAllReadyBlockUpdatesInChunk(cbi, lock_manager); node != nullptr; node = removeAllReadyBlockUpdatesInChunk(cbi, lock_manager))
701713
{
702714
didAnything = true;
703715
while(node != nullptr)
@@ -729,7 +741,6 @@ void World::blockUpdateThreadFn()
729741
}
730742
if(!didAnything)
731743
{
732-
lightingStable = true;
733744
std::this_thread::sleep_for(std::chrono::milliseconds(10));
734745
}
735746
}

0 commit comments

Comments
 (0)