瀏覽代碼

fixed some memory leaks

Kolja Strohm 22 小時之前
父節點
當前提交
b1851e25cd

+ 1 - 1
FactoryCraft/BasicBlocks.cpp

@@ -85,7 +85,7 @@ void BasicBlock::getLightEmisionColor(unsigned char* result) const
 TickSourceType BasicBlock::isTickSource() const
 {
     return components.getEntryCount() > 0 ? TickSourceType::EACH_TICK
-                                             : TickSourceType::NONE;
+                                          : TickSourceType::NONE;
 }
 
 void BasicBlock::onApiCall(char messageType,

+ 3 - 0
FactoryCraft/ChatCommandExecutor.cpp

@@ -6,6 +6,7 @@
 #include "GrantCommand.h"
 #include "ModeCommand.h"
 #include "SaveCommand.h"
+#include "ExitCommand.h"
 
 ChatCommandExecutor::ChatCommandExecutor()
     : ReferenceCounter()
@@ -19,6 +20,8 @@ ChatCommandExecutor::ChatCommandExecutor()
     {
         Game::INSTANCE->consoleInput->addPossibleCommand(
             dynamic_cast<Framework::ConsoleCommand*>(command->getThis()));
+        // exit command only available via console and not via chat
+        Game::INSTANCE->consoleInput->addPossibleCommand(new ExitCommand());
     }
 }
 

+ 0 - 9
FactoryCraft/Chunk.cpp

@@ -773,15 +773,6 @@ const Block* Chunk::zBlockConstWC(int x, int y, int z) const
     return Game::INSTANCE->zBlockType(b.getB())->zDefault();
 }
 
-const Block* Chunk::zBlockConst(int z, int index) const
-{
-    if (blocks[z] && blocks[z][index])
-        return blocks[z][index];
-    else
-        return Game::INSTANCE->zBlockType(blockIds[z] ? blockIds[z][index] : 0)
-            ->zDefault();
-}
-
 void Chunk::instantiateBlock(Framework::Vec3<int> location)
 {
     auto b = zBlockAt(location);

+ 0 - 1
FactoryCraft/Chunk.h

@@ -42,7 +42,6 @@ private:
     void sendToClient(Framework::StreamWriter* zWriter, bool* instanceMap);
     void sendLightToClient(Framework::StreamWriter* zWriter, bool* instanceMap);
     void broadcastLightData(int z, int index, bool foreground);
-    const Block* zBlockConst(int z, int index) const;
     bool isVisible(int z, int index) const;
 
 public:

+ 21 - 0
FactoryCraft/ExitCommand.cpp

@@ -0,0 +1,21 @@
+#include "ExitCommand.h"
+
+#include "Game.h"
+#include "Server.h"
+
+ExitCommand::ExitCommand()
+    : ConsoleCommand("exit")
+{}
+
+void ExitCommand::addAutocompletePossibilities(
+    const Framework::RCArray<Framework::Text>& args,
+    bool appendToLast,
+    Framework::RCArray<Framework::Text>& possibilities) const
+{}
+
+bool ExitCommand::execute(Framework::RCArray<Framework::Text>& args) const
+{
+    Game::consoleInput->close();
+    FactoryCraftServer::INSTANCE->close();
+    return true;
+}

+ 20 - 0
FactoryCraft/ExitCommand.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#include <Console.h>
+
+class ExitCommand : public Framework::ConsoleCommand
+{
+public:
+    ExitCommand();
+    void addAutocompletePossibilities(
+        const Framework::RCArray<Framework::Text>& args,
+        bool appendToLast,
+        Framework::RCArray<Framework::Text>& possibilities) const override;
+    /**
+     * executes the command
+     *
+     * \param args the arguments that the user has passed to the command
+     * \return true if the command was executed successfully
+     */
+    bool execute(Framework::RCArray<Framework::Text>& args) const override;
+};

+ 2 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -117,6 +117,7 @@
     <ClInclude Include="DropConfig.h" />
     <ClInclude Include="DropUsedItemCondition.h" />
     <ClInclude Include="EntityGenerator.h" />
+    <ClInclude Include="ExitCommand.h" />
     <ClInclude Include="FactorizeNoise.h" />
     <ClInclude Include="FireBasedProcessingBlockComponent.h" />
     <ClInclude Include="FlattenNoise.h" />
@@ -273,6 +274,7 @@
     <ClCompile Include="Entity.cpp" />
     <ClCompile Include="EntityGenerator.cpp" />
     <ClCompile Include="EntityType.cpp" />
+    <ClCompile Include="ExitCommand.cpp" />
     <ClCompile Include="FactorizeNoise.cpp" />
     <ClCompile Include="FastNoiseWrapper.cpp" />
     <ClCompile Include="FireBasedProcessingBlockComponent.cpp" />

+ 21 - 2
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -133,6 +133,9 @@
     <Filter Include="world\generator\distribution">
       <UniqueIdentifier>{df18d1ea-0c12-41b8-8a3d-f8aef3d637e0}</UniqueIdentifier>
     </Filter>
+    <Filter Include="world\orientation">
+      <UniqueIdentifier>{345be19e-b790-4036-bc34-c70e71d0d843}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Chunk.h">
@@ -519,13 +522,21 @@
     <ClInclude Include="UIMLBuilder.h">
       <Filter>UI\Builder</Filter>
     </ClInclude>
-    <ClInclude Include="Orientation.h" />
     <ClInclude Include="SpecificItemDrop.h">
       <Filter>drops\implementations</Filter>
     </ClInclude>
     <ClInclude Include="FloatDistribution.h">
       <Filter>world\generator\distribution</Filter>
     </ClInclude>
+    <ClInclude Include="ExitCommand.h">
+      <Filter>chat\commands</Filter>
+    </ClInclude>
+    <ClInclude Include="ModeCommand.h">
+      <Filter>chat\commands</Filter>
+    </ClInclude>
+    <ClInclude Include="Orientation.h">
+      <Filter>world\orientation</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
@@ -900,9 +911,17 @@
     <ClCompile Include="PlantConfig.cpp">
       <Filter>world\generator\biom\plants</Filter>
     </ClCompile>
-    <ClCompile Include="Orientation.cpp" />
     <ClCompile Include="FloatDistribution.cpp">
       <Filter>world\generator\distribution</Filter>
     </ClCompile>
+    <ClCompile Include="ExitCommand.cpp">
+      <Filter>chat\commands</Filter>
+    </ClCompile>
+    <ClCompile Include="ModeCommand.cpp">
+      <Filter>chat\commands</Filter>
+    </ClCompile>
+    <ClCompile Include="Orientation.cpp">
+      <Filter>world\orientation</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 11 - 1
FactoryCraft/FireBasedProcessingBlockComponent.cpp

@@ -17,7 +17,17 @@ FireBasedProcessingBlockComponent::FireBasedProcessingBlockComponent()
       burning(0)
 {}
 
-FireBasedProcessingBlockComponent::~FireBasedProcessingBlockComponent() {}
+FireBasedProcessingBlockComponent::~FireBasedProcessingBlockComponent()
+{
+    if (fireStartingItemFilter)
+    {
+        fireStartingItemFilter->release();
+    }
+    if (fuelItemFilter)
+    {
+        fuelItemFilter->release();
+    }
+}
 
 bool FireBasedProcessingBlockComponent::findRecipie()
 {

+ 2 - 0
FactoryCraft/Game.cpp

@@ -110,6 +110,8 @@ Game::~Game()
         if (multiblockStructureTypes[i]) multiblockStructureTypes[i]->release();
     }
     delete[] multiblockStructureTypes;
+    questManager->release();
+    ticker->release();
 }
 
 void Game::initialize()

+ 10 - 0
FactoryCraft/ItemSlot.cpp

@@ -21,6 +21,16 @@ ItemSlot::ItemSlot(Framework::Text name,
       id(0)
 {}
 
+ItemSlot::ItemSlot(ItemSlot& slot)
+    : ItemSlot(slot.getName(),
+          slot.maxSize,
+          slot.getPullPriority(),
+          slot.getPushPriority(),
+          slot.allowedPullSides,
+          slot.allowedPushSides,
+          slot.allowHigherStackSize)
+{}
+
 ItemSlot::~ItemSlot()
 {
     if (items) items->release();

+ 1 - 0
FactoryCraft/ItemSlot.h

@@ -41,6 +41,7 @@ public:
         Directions allowedPullSides,
         Directions allowedPushSides,
         bool allowHigherStackSize);
+    ItemSlot(ItemSlot& slot);
     ~ItemSlot();
 
     ItemStack* takeItemsOut(int count, Direction dir);

+ 3 - 1
FactoryCraft/JNoise.cpp

@@ -330,7 +330,7 @@ Validator::DataValidator* JNoise::getValidator(bool optional)
               ->addAcceptedType(Validator::DataValidator::buildForReference(
                   "jn_fastNoiseLite"))
               ->finishOneOf();
-    return Validator::DataValidator::buildForOneOf()
+    auto result = Validator::DataValidator::buildForOneOf()
         ->typeSpecifiedByAttribute("type")
         ->addAcceptedType(validator1->setReferenceId("jn_random")
                 ->withRequiredString("type")
@@ -448,4 +448,6 @@ Validator::DataValidator* JNoise::getValidator(bool optional)
                 ->finishNumber()
                 ->finishObject())
         ->finishOneOf();
+    refs->release();
+    return result;
 }

+ 4 - 1
FactoryCraft/Quest.cpp

@@ -541,7 +541,10 @@ Framework::JSON::JSONObject* QuestType::toJsonObject(Quest* zObject) const
     if (requiredQuestIdsArray->getLength())
     {
         requiredQuestGroupArray->addValue(requiredQuestIdsArray);
-        requiredQuestIdsArray = new Framework::JSON::JSONArray();
+    }
+    else
+    {
+        requiredQuestIdsArray->release();
     }
     result->addValue("requiredQuestIds", requiredQuestGroupArray);
     Framework::JSON::JSONArray* requirementsArray

+ 0 - 2
FactoryCraft/QuestReward.cpp

@@ -216,8 +216,6 @@ Framework::JSON::JSONObject* QuestRewardGiveItemsType::toJsonObject(
 {
     Framework::JSON::JSONObject* zResult
         = QuestRewardFactoryBase::toJsonObject(zObject);
-    zResult->addValue(
-        "rewardId", new Framework::JSON::JSONString(zObject->getRewardId()));
     Framework::JSON::JSONArray* itemsJson = new Framework::JSON::JSONArray();
     for (ItemStackInfo* item : zObject->items)
     {

+ 2 - 0
FactoryCraft/RecipieLoader.cpp

@@ -50,6 +50,7 @@ void RecipieLoader::loadRecipies(const char* path)
                         count++;
                     }
                 }
+                valid->release();
             }
             Framework::Logging::info()
                 << count << " recipie groups were loaded.";
@@ -100,6 +101,7 @@ void RecipieLoader::loadRecipies(const char* path)
                         count++;
                     }
                 }
+                valid->release();
             }
             Framework::Logging::info() << count << " recipies were loaded.";
         });

+ 5 - 0
FactoryCraft/ScaleNoise.cpp

@@ -6,6 +6,11 @@ ScaleNoise::ScaleNoise(Noise* base, double factor)
       factor(factor)
 {}
 
+ScaleNoise::~ScaleNoise()
+{
+    base->release();
+}
+
 int ScaleNoise::getSeed() const
 {
     return base->getSeed();

+ 1 - 0
FactoryCraft/ScaleNoise.h

@@ -10,6 +10,7 @@ private:
 
 public:
     ScaleNoise(Noise* base, double factor);
+    ~ScaleNoise();
     int getSeed() const override;
     double getNoise(double x, double y, double z) override;
 };

+ 2 - 1
FactoryCraft/Server.cpp

@@ -10,12 +10,13 @@
 #include "Game.h"
 #include "PlayerRegister.h"
 
+FactoryCraftServer* FactoryCraftServer::INSTANCE = 0;
+
 // Inhalt der LoginServer Klasse aus LoginServer.h
 // Konstruktor
 FactoryCraftServer::FactoryCraftServer(InitFile* zIni)
     : ReferenceCounter()
 {
-    Network::Start(100);
     runningThreads = 0;
     klients = new RCArray<FCKlient>();
     ini = dynamic_cast<InitFile*>(zIni->getThis());

+ 3 - 0
FactoryCraft/Server.h

@@ -18,6 +18,9 @@ class GameClient;
 
 class FactoryCraftServer : virtual public ReferenceCounter
 {
+public:
+    static FactoryCraftServer* INSTANCE;
+
 private:
     SSLServer* sslServer;
     Server* server;

+ 50 - 32
FactoryCraft/Start.cpp

@@ -17,20 +17,26 @@
 #include "Server.h"
 #include "WorldGenerator.h"
 
-FactoryCraftServer* mserver = 0;
+bool exited2 = false;
 
 #ifdef _WINDOWS
 static LONG WINAPI exceptionHandler(struct _EXCEPTION_POINTERS* apExceptionInfo)
 {
-    Sleep(10000);
-    Logging::error() << "Creating dump";
-    createMinidump(apExceptionInfo);
-    if (mserver)
+    if (!exited2)
     {
-        Logging::error()
-            << "The server terminated unexpectedly. Trying to save game "
-               "progress.";
-        mserver->close();
+        Logging::error() << "Creating dump";
+        createMinidump(apExceptionInfo);
+        if (FactoryCraftServer::INSTANCE)
+        {
+            Logging::error()
+                << "The server terminated unexpectedly. Trying to save game "
+                    "progress.";
+            FactoryCraftServer::INSTANCE->close();
+        }
+    }
+    else
+    {
+        std::cout << "Exception after exiting the main function";
     }
     return EXCEPTION_CONTINUE_SEARCH;
 }
@@ -38,25 +44,25 @@ static LONG WINAPI exceptionHandler(struct _EXCEPTION_POINTERS* apExceptionInfo)
 
 static void onError(int i)
 {
-    Sleep(10000);
-    Logging::error() << "Creating dump";
+    if (!exited2)
+    {
+        Logging::error() << "Creating dump";
 #ifdef WIN32
-    createMinidump(0);
+        createMinidump(0);
 #endif
-    if (mserver)
-    {
-        Logging::error()
-            << "The server terminated unexpectedly. Trying to save game "
-               "progress.";
-        mserver->close();
+        if (FactoryCraftServer::INSTANCE)
+        {
+            Logging::error()
+                << "The server terminated unexpectedly. Trying to save game "
+                   "progress.";
+            FactoryCraftServer::INSTANCE->close();
+        }
     }
 }
 
 static void onExit()
 {
-    Sleep(10000);
-    Logging::info() << "Programm exited";
-    onError(0);
+    std::cout << "Programm exited";
 }
 
 bool exited = false;
@@ -103,12 +109,8 @@ public:
     }
 };
 
-int main()
+int factoryCraftMain()
 {
-#ifdef _WINDOWS
-    SetUnhandledExceptionFilter(exceptionHandler);
-#endif
-    Framework::initFramework();
     Game::consoleHandler = new ConsoleHandler();
 
 #ifndef _WINDOWS
@@ -222,7 +224,7 @@ int main()
         }
     }
 
-    mserver = new FactoryCraftServer(dat);
+    FactoryCraftServer::INSTANCE = new FactoryCraftServer(dat);
     std::atexit(onExit);
     signal(SIGTERM, onError);
     signal(SIGSEGV, onError);
@@ -232,10 +234,10 @@ int main()
     signal(SIGINT, onError);
 
     Logging::info() << "The Server is now running.";
-    mserver->run();
+    FactoryCraftServer::INSTANCE->run();
     exited = 1;
-    mserver->release();
-    mserver = 0;
+    FactoryCraftServer::INSTANCE->release();
+    FactoryCraftServer::INSTANCE = 0;
     if (Game::INSTANCE)
     {
         Game* tmp = Game::INSTANCE;
@@ -247,6 +249,22 @@ int main()
     dat->release();
     Logging::info() << "The server was shut down successfully.";
     Game::consoleHandler->release();
-    Framework::releaseFramework();
     return 0;
-}
+}
+
+int main()
+{
+#ifdef _WINDOWS
+#    ifdef _DEBUG
+    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#    endif
+    SetUnhandledExceptionFilter(exceptionHandler);
+#endif
+    Framework::initFramework();
+    Network::Start(100);
+    int result = factoryCraftMain();
+    exited2 = true;
+    Network::Exit();
+    Framework::releaseFramework();
+    return result;
+}

+ 56 - 24
FactoryCraft/TypeRegistry.h

@@ -32,11 +32,13 @@ template<typename T> class ObjectTypeFactory : public SimpleTypeFactory<T*>
 {
 protected:
     mutable Framework::Validator::DataValidator* validator;
+    mutable bool insideGetValidator;
 
 public:
     ObjectTypeFactory()
         : SimpleTypeFactory<T*>(),
-          validator(0) {};
+          validator(0),
+          insideGetValidator(false) {};
 
     ~ObjectTypeFactory()
     {
@@ -60,17 +62,26 @@ public:
     {
         if (!this->validator)
         {
-            this->validator = addToValidator(
-                Framework::Validator::DataValidator::buildForObject())
-                                  ->finishObject();
+            if (!insideGetValidator)
+            {
+                insideGetValidator = true;
+                this->validator = addToValidator(
+                    Framework::Validator::DataValidator::buildForObject())
+                                      ->finishObject();
+                insideGetValidator = false;
+            }
+            else
+            {
+                throw "recursive endless loop. a json object needs to contain "
+                      "itself";
+            }
         }
         return dynamic_cast<Framework::Validator::DataValidator*>(
             this->validator->getThis());
     };
 
     virtual JSONObjectValidationBuilder* addToValidator(
-        JSONObjectValidationBuilder* builder) const
-        = 0;
+        JSONObjectValidationBuilder* builder) const = 0;
 
 protected:
     virtual T* fromJson(Framework::JSON::JSONObject* zJson) const = 0;
@@ -98,14 +109,32 @@ public:
         {
             Framework::Text referenceId = "_type_";
             referenceId.append() << typeid(T).name() << "_" << getTypeToken();
-            this->validator
-                = this->addToValidator(
-                          Framework::Validator::DataValidator::buildForObject()
-                              ->withRequiredString("type")
-                              ->withExactMatch(getTypeToken())
-                              ->finishString()
-                              ->setReferenceId(referenceId))
-                      ->finishObject();
+            if (!this->insideGetValidator)
+            {
+                this->insideGetValidator = true;
+                auto result = this->addToValidator(
+                                      Framework::Validator::DataValidator::
+                                          buildForObject()
+                                              ->withRequiredString("type")
+                                              ->withExactMatch(getTypeToken())
+                                              ->finishString()
+                                              ->setReferenceId(referenceId))
+                                  ->finishObject();
+                if (this->validator)
+                {
+                    // during a recursive call the validator could have ben
+                    // initialized to a reference validator (else branch below)
+                    this->validator->release();
+                }
+                this->validator = result;
+                this->insideGetValidator = false;
+            }
+            else
+            {
+                this->validator
+                    = Framework::Validator::DataValidator::buildForReference(
+                        referenceId);
+            }
         }
         return dynamic_cast<Framework::Validator::DataValidator*>(
             this->validator->getThis());
@@ -174,7 +203,6 @@ template<typename T> class PolymorphTypeFactory : public ObjectTypeFactory<T>
 private:
     Framework::RCArray<SubTypeFactoryRef<T>> factories;
     Framework::RCArray<Framework::Text> typeNames;
-    static thread_local bool insideGetValidator;
 
 public:
     PolymorphTypeFactory()
@@ -234,9 +262,9 @@ public:
     {
         if (!this->validator)
         {
-            if (!insideGetValidator)
+            if (!this->insideGetValidator)
             {
-                insideGetValidator = true;
+                this->insideGetValidator = true;
                 auto validator
                     = Framework::Validator::DataValidator::buildForOneOf()
                           ->typeSpecifiedByAttribute("type");
@@ -245,8 +273,14 @@ public:
                     validator
                         = validator->addAcceptedType(factory->getValidator());
                 }
+                if (this->validator)
+                {
+                    // during a recursive call the validator could have ben
+                    // initialized to a reference validator (else branch below)
+                    this->validator->release();
+                }
                 this->validator = validator->finishOneOf();
-                insideGetValidator = false;
+                this->insideGetValidator = false;
             }
             else
             {
@@ -258,8 +292,7 @@ public:
                     validator = validator->addAcceptedType(
                         Framework::Validator::DataValidator::buildForReference(
                             ((Framework::Text("_type_") += typeid(T).name())
-                                += "_")
-                            += factory->getTypeToken()));
+                                += "_") += factory->getTypeToken()));
                 }
                 this->validator = validator->finishOneOf();
             }
@@ -289,9 +322,6 @@ public:
     }
 };
 
-template<typename T>
-thread_local bool PolymorphTypeFactory<T>::insideGetValidator = false;
-
 class TypeFatoryRef : public Framework::ReferenceCounter
 {
 private:
@@ -375,7 +405,8 @@ public:
             throw Framework::Text("Type not registered as Polymorphic type: ")
                 + typeId;
         }
-        polymorphFactory->template addFactory<S>(factory);
+        polymorphFactory->template addFactory<S>(
+            dynamic_cast<SubTypeFactory<T, S>*>(factory->getThis()));
         Framework::Text typeIdS = typeid(S).name();
         parsableTypeNames.add(new Framework::Text(typeIdS));
         registerType(factory);
@@ -477,6 +508,7 @@ public:
         {
             Framework::Logging::error() << invalidPart->getInvalidInfo();
         }
+        validator->release();
         return result;
     }
 

+ 2 - 0
Windows Version/Windows Version.vcxproj

@@ -199,6 +199,7 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClCompile Include="..\FactoryCraft\Entity.cpp" />
     <ClCompile Include="..\FactoryCraft\EntityGenerator.cpp" />
     <ClCompile Include="..\FactoryCraft\EntityType.cpp" />
+    <ClCompile Include="..\FactoryCraft\ExitCommand.cpp" />
     <ClCompile Include="..\FactoryCraft\FactorizeNoise.cpp" />
     <ClCompile Include="..\FactoryCraft\FastNoiseWrapper.cpp" />
     <ClCompile Include="..\FactoryCraft\FireBasedProcessingBlockComponent.cpp" />
@@ -307,6 +308,7 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClInclude Include="..\FactoryCraft\DropConfig.h" />
     <ClInclude Include="..\FactoryCraft\DropUsedItemCondition.h" />
     <ClInclude Include="..\FactoryCraft\EntityGenerator.h" />
+    <ClInclude Include="..\FactoryCraft\ExitCommand.h" />
     <ClInclude Include="..\FactoryCraft\FactorizeNoise.h" />
     <ClInclude Include="..\FactoryCraft\FireBasedProcessingBlockComponent.h" />
     <ClInclude Include="..\FactoryCraft\FlattenNoise.h" />

+ 6 - 0
Windows Version/Windows Version.vcxproj.filters

@@ -519,6 +519,9 @@
     <ClCompile Include="..\FactoryCraft\ModeCommand.cpp">
       <Filter>chat\commands</Filter>
     </ClCompile>
+    <ClCompile Include="..\FactoryCraft\ExitCommand.cpp">
+      <Filter>chat\commands</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\FactoryCraft\Chunk.h">
@@ -917,5 +920,8 @@
     <ClInclude Include="..\FactoryCraft\ModeCommand.h">
       <Filter>chat\commands</Filter>
     </ClInclude>
+    <ClInclude Include="..\FactoryCraft\ExitCommand.h">
+      <Filter>chat\commands</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>

二進制
Windows Version/error_core_memory_dump.dmp