Sfoglia il codice sorgente

actually tick the blocks that needs to be ticked

Kolja Strohm 1 anno fa
parent
commit
396b447d77

+ 6 - 0
FactoryCraft/Block.cpp

@@ -109,6 +109,12 @@ void Block::tick(TickQueue* zQueue)
             ticksLeftCounter = 0;
         }
     }
+    else
+    {
+        onTickCalled = 1;
+        bool blocked = 0;
+        bool result = onTick(zQueue, 1, blocked);
+    }
 }
 
 void Block::postTick()

+ 5 - 3
FactoryCraft/Block.h

@@ -10,6 +10,7 @@
 #include "Item.h"
 #include "NetworkMessage.h"
 #include "ReferenceCounter.h"
+#include "Tickable.h"
 
 #define CONST_BLOCK(maybeBlock, type)                                     \
     (maybeBlock ? maybeBlock                                              \
@@ -23,7 +24,8 @@ class MultiblockStructure;
 
 class TickQueue;
 
-class Block : public Inventory
+class Block : public Inventory,
+              public Tickable
 {
 private:
     int ticksLeftCounter;
@@ -78,8 +80,8 @@ public:
         bool hasInventory);
     virtual ~Block();
 
-    void tick(TickQueue* zQueue);
-    void postTick();
+    void tick(TickQueue* zQueue) override;
+    void postTick() override;
     void setDimensionId(int id);
     void addToStructure(MultiblockStructure* structure);
     virtual void onLoaded();

+ 5 - 0
FactoryCraft/BlockType.cpp

@@ -200,4 +200,9 @@ BlockType* BlockType::initializeDefault()
 {
     defaultBlock = createBlockAt({0, 0, 0}, 0);
     return this;
+}
+
+const char* BlockType::getName() const
+{
+    return name;
 }

+ 1 - 0
FactoryCraft/BlockType.h

@@ -86,6 +86,7 @@ public:
     int getInitialMaxHP() const;
     bool isLightSource() const;
     BlockType* initializeDefault();
+    const char* getName() const;
 };
 
 const Block* getDefaultBlock(Framework::Either<Block*, int> b);

+ 24 - 0
FactoryCraft/Chunk.cpp

@@ -47,6 +47,14 @@ Chunk::~Chunk()
     delete[] lightData;
 }
 
+void Chunk::tick(TickQueue* zQueue)
+{
+    for (Block* source : tickSources)
+        zQueue->addToQueue(source);
+}
+
+void Chunk::postTick() {}
+
 void Chunk::addLightSource(int index)
 {
     for (int i : lightSources)
@@ -366,6 +374,18 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
         = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
     assert(index < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT && index >= 0);
     Block* old = blocks[index];
+    if (old && old->isTickSource())
+    { // remove from tick sorces
+        for (Framework::Iterator<Block*> obj = tickSources.begin(); obj;
+             obj++)
+        {
+            if (obj.val() == old)
+            {
+                obj.remove();
+                break;
+            }
+        }
+    }
     bool change = 0;
     bool wasLightSource
         = old ? old->zBlockType()->isLightSource()
@@ -394,6 +414,10 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
         if (block) block->setNeighbour(d, neighbor);
     }
     if (old) old->release();
+    if (block && block->isTickSource())
+    { // add to tick sources
+        tickSources.add(block);
+    }
     if (change)
     {
         if (isLightSource != wasLightSource)

+ 6 - 1
FactoryCraft/Chunk.h

@@ -8,8 +8,9 @@
 
 #include "Block.h"
 #include "DoLaterHandler.h"
+#include "Tickable.h"
 
-class Chunk : public virtual Framework::ReferenceCounter
+class Chunk : public virtual Framework::ReferenceCounter, public Tickable
 {
 private:
     int dimensionId;
@@ -23,6 +24,7 @@ private:
     Framework::Critical cs;
     Framework::Array<int> observers;
     Framework::Array<int> lightSources;
+    Framework::Array<Block*> tickSources;
     unsigned char* lightData;
     bool currentlyLoading;
 
@@ -37,6 +39,9 @@ public:
         Framework::StreamReader* zReader);
     ~Chunk();
 
+    void tick(TickQueue* zQueue) override;
+    void postTick() override;
+	
     void notifyObservers(NetworkMessage* msg);
     void addObserver(Entity* zEntity, DoLaterHandler& laterHandler);
     void removeObserver(Entity* zEntity);

+ 2 - 0
FactoryCraft/Dimension.cpp

@@ -354,6 +354,7 @@ void Dimension::setChunk(Chunk* chunk, Punkt center)
     Chunk* old = chunks->get(addr, 8);
     if (old)
     {
+        Game::INSTANCE->zTickOrganizer()->removeTickSource(old);
         old->prepareRemove();
         for (int i = 0; i < chunkList.getEintragAnzahl(); i++)
         {
@@ -430,6 +431,7 @@ void Dimension::setChunk(Chunk* chunk, Punkt center)
             index++;
         }
         cs.unlock();
+        Game::INSTANCE->zTickOrganizer()->addTickSource(chunk);
     }
     chunkCs.unlock();
     if (old)

+ 1 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -149,6 +149,7 @@
     <ClInclude Include="ShapedNoise.h" />
     <ClInclude Include="StaticRegistry.h" />
     <ClInclude Include="StoneTool.h" />
+    <ClInclude Include="Tickable.h" />
     <ClInclude Include="TickOrganizer.h" />
     <ClInclude Include="TickQueue.h" />
     <ClInclude Include="TickWorker.h" />

+ 3 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -255,6 +255,9 @@
     <ClInclude Include="ShapedNoise.h">
       <Filter>world\generator\noise</Filter>
     </ClInclude>
+    <ClInclude Include="Tickable.h">
+      <Filter>world\ticking</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">

+ 5 - 0
FactoryCraft/Game.cpp

@@ -884,4 +884,9 @@ void Game::doLater(std::function<void()> action)
     actionsCs.lock();
     actions.add(action);
     actionsCs.unlock();
+}
+
+TickOrganizer* Game::zTickOrganizer() const
+{
+    return ticker;
 }

+ 1 - 0
FactoryCraft/Game.h

@@ -130,6 +130,7 @@ public:
         std::function<bool(Entity*)> filter);
     const RecipieLoader& getRecipies() const;
     void doLater(std::function<void()> action);
+    TickOrganizer* zTickOrganizer() const;
 
     static Game* INSTANCE;
     static void initialize(Framework::Text name, Framework::Text worldsDir);

+ 14 - 9
FactoryCraft/TickOrganizer.cpp

@@ -27,32 +27,37 @@ TickOrganizer::~TickOrganizer()
 
 void TickOrganizer::nextTick()
 {
+    sourceCs.lock();
     queue->startNextTick(&tickSources);
+    sourceCs.unlock();
     bool notWaiting = 0;
     do
     {
         queue->waitForEmpty();
+        notWaiting = 0;
         for (int i = 0; i < workerCount; i++)
             notWaiting |= !workers[i]->isWaiting();
     } while (notWaiting);
     queue->postTick();
 }
 
-void TickOrganizer::addTickSource(Block* zBlock)
+void TickOrganizer::addTickSource(Tickable* zObj)
 {
-    tickSources.add(zBlock);
+    sourceCs.lock();
+    tickSources.add(zObj);
+    sourceCs.unlock();
 }
 
-void TickOrganizer::removeTickSource(Block* zBlock)
+void TickOrganizer::removeTickSource(Tickable* zObj)
 {
-    int index = 0;
-    for (Block* block : tickSources)
+    sourceCs.lock();
+    for (Framework::Iterator<Tickable*> obj = tickSources.begin(); obj; obj++)
     {
-        if (block == zBlock)
+        if (obj.val() == zObj)
         {
-            tickSources.remove(index);
-            return;
+            obj.remove();
+            break;
         }
-        index++;
     }
+    sourceCs.unlock();
 }

+ 5 - 3
FactoryCraft/TickOrganizer.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <Array.h>
+#include <Critical.h>
 
 #include "TickWorker.h"
 
@@ -9,8 +10,9 @@ class TickOrganizer : public virtual Framework::ReferenceCounter
 private:
     int workerCount;
     TickWorker** workers;
-    Framework::Array<Block*> tickSources;
+    Framework::Array<Tickable*> tickSources;
     TickQueue* queue;
+    Framework::Critical sourceCs;
 
 public:
     TickOrganizer();
@@ -18,6 +20,6 @@ public:
 
     void nextTick();
 
-    void addTickSource(Block* zBlock);
-    void removeTickSource(Block* zBlock);
+    void addTickSource(Tickable* zObj);
+    void removeTickSource(Tickable* zObj);
 };

+ 11 - 11
FactoryCraft/TickQueue.cpp

@@ -17,7 +17,7 @@ TickQueue::~TickQueue()
     delete[] queue;
 }
 
-void TickQueue::startNextTick(Framework::Array<Block*>* zSources)
+void TickQueue::startNextTick(Framework::Array<Tickable*>* zSources)
 {
     std::unique_lock<std::mutex> lk(mutex);
     readPosition = 0;
@@ -25,29 +25,29 @@ void TickQueue::startNextTick(Framework::Array<Block*>* zSources)
     int count = zSources->getEintragAnzahl();
     if (count >= maxSize)
     {
-        Block** temp = new Block*[count + 1000];
-        memcpy(queue, temp, sizeof(Block*) * maxSize);
-        memset(temp + sizeof(Block*) * maxSize,
+        Tickable** temp = new Tickable*[count + 1000];
+        memcpy(queue, temp, sizeof(Tickable*) * maxSize);
+        memset(temp + sizeof(Tickable*) * maxSize,
             0,
-            sizeof(Block*) * (count + 1000 - maxSize));
+            sizeof(Tickable*) * (count + 1000 - maxSize));
         maxSize = count + 1000;
         delete[] queue;
         queue = temp;
     }
-    for (Block* block : *zSources)
+    for (Tickable* block : *zSources)
         queue[writePosition++] = block;
     lk.unlock();
     hasBlocks.notify_all();
 }
 
-void TickQueue::addToQueue(Block* zBlock)
+void TickQueue::addToQueue(Tickable* zBlock)
 {
     std::unique_lock<std::mutex> lk(mutex);
     if (writePosition >= maxSize)
     {
-        Block** temp = new Block*[maxSize + 1000];
-        memcpy(queue, temp, sizeof(Block*) * maxSize);
-        memset(temp + sizeof(Block*) * maxSize, 0, sizeof(Block*) * 1000);
+        Tickable** temp = new Tickable*[maxSize + 1000];
+        memcpy(queue, temp, sizeof(Tickable*) * maxSize);
+        memset(temp + sizeof(Tickable*) * maxSize, 0, sizeof(Tickable*) * 1000);
         maxSize += 1000;
         delete[] queue;
         queue = temp;
@@ -57,7 +57,7 @@ void TickQueue::addToQueue(Block* zBlock)
     hasBlocks.notify_one();
 }
 
-Block* TickQueue::zNextBlock(bool& waiting)
+Tickable* TickQueue::zNext(bool& waiting)
 {
     std::unique_lock<std::mutex> lk(mutex);
     if (readPosition == writePosition && exit) return 0;

+ 6 - 4
FactoryCraft/TickQueue.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "Tickable.h"
+
 #include <Array.h>
 #include <condition_variable>
 #include <ReferenceCounter.h>
@@ -12,7 +14,7 @@ private:
     int maxSize;
     int readPosition;
     int writePosition;
-    Block** queue;
+    Tickable** queue;
     std::mutex mutex;
     std::condition_variable hasBlocks;
     std::condition_variable hasNoBlocks;
@@ -22,9 +24,9 @@ public:
     TickQueue();
     ~TickQueue();
 
-    void startNextTick(Framework::Array<Block*>* zSources);
-    void addToQueue(Block* zBlock);
-    Block* zNextBlock(bool& waiting);
+    void startNextTick(Framework::Array<Tickable*>* zSources);
+    void addToQueue(Tickable* zBlock);
+    Tickable* zNext(bool& waiting);
     void requestExit();
     void waitForEmpty();
     void postTick();

+ 4 - 4
FactoryCraft/TickWorker.cpp

@@ -17,11 +17,11 @@ TickWorker::~TickWorker()
 
 void TickWorker::thread()
 {
-    Block* zTickBlock = queue->zNextBlock(waiting);
-    while (zTickBlock)
+    Tickable* zTick = queue->zNext(waiting);
+    while (zTick)
     {
-        zTickBlock->tick(queue);
-        zTickBlock = queue->zNextBlock(waiting);
+        zTick->tick(queue);
+        zTick = queue->zNext(waiting);
     }
 }
 

+ 10 - 0
FactoryCraft/Tickable.h

@@ -0,0 +1,10 @@
+#pragma once
+
+class TickQueue;
+
+class Tickable
+{
+public:
+    virtual void tick(TickQueue* zQueue) = 0;
+    virtual void postTick() = 0;
+};

+ 10 - 0
FactoryCraft/TreeSeblingBlock.cpp

@@ -12,6 +12,8 @@ TreeSeblingBlock::TreeSeblingBlock(int typeId,
     const BlockType* wood,
     const BlockType* leaves)
     : Block(typeId, zTool, pos, 0),
+      seblingTicks(0),
+      seblingTicksMax(10000),
       wood(wood),
       leaves(leaves)
 {
@@ -49,6 +51,14 @@ void TreeSeblingBlock::onPostTick()
     }
 }
 
+Framework::Text TreeSeblingBlock::getTargetUIML()
+{
+    return Text("<targetInfo><text width=\"auto\" height=\"auto\">")
+         + StaticRegistry<BlockType>::INSTANCE.zElement(typeId)->getName()
+         + "\n" + "Growth: " + Text((int)(seblingTicks / seblingTicksMax * 100))
+         + "%</text></targetInfo>";
+}
+
 TreeSeblingBlockType::TreeSeblingBlockType(int typeId,
     int itemTypeId,
     ModelInfo model,

+ 1 - 0
FactoryCraft/TreeSeblingBlock.h

@@ -21,6 +21,7 @@ public:
     virtual bool onTick(
         TickQueue* zQueue, int numTicks, bool& blocked) override;
     virtual void onPostTick() override;
+    virtual Framework::Text getTargetUIML();
 
     friend TreeSeblingBlockType;
 };