Bläddra i källkod

improve world generation speed to about 20 chunks per second

Kolja Strohm 3 månader sedan
förälder
incheckning
4c42c19e3b

+ 18 - 0
FactoryCraft.sln

@@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Windows Version", "Windows
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NoiseTest", "NoiseTest\NoiseTest.vcxproj", "{096A454C-3835-4A4E-89FE-34EDCCD80467}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assembly", "assembly\assembly.vcxproj", "{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|ARM = Debug|ARM
@@ -75,6 +77,22 @@ Global
 		{096A454C-3835-4A4E-89FE-34EDCCD80467}.Release|x64.Build.0 = Release|x64
 		{096A454C-3835-4A4E-89FE-34EDCCD80467}.Release|x86.ActiveCfg = Release|Win32
 		{096A454C-3835-4A4E-89FE-34EDCCD80467}.Release|x86.Build.0 = Release|Win32
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Debug|ARM.ActiveCfg = Debug|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Debug|ARM.Build.0 = Debug|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Debug|ARM64.ActiveCfg = Debug|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Debug|ARM64.Build.0 = Debug|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Debug|x64.ActiveCfg = Debug|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Debug|x64.Build.0 = Debug|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Debug|x86.ActiveCfg = Debug|Win32
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Debug|x86.Build.0 = Debug|Win32
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Release|ARM.ActiveCfg = Release|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Release|ARM.Build.0 = Release|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Release|ARM64.ActiveCfg = Release|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Release|ARM64.Build.0 = Release|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Release|x64.ActiveCfg = Release|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Release|x64.Build.0 = Release|x64
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Release|x86.ActiveCfg = Release|Win32
+		{1C0B0808-0D8E-49A6-87C2-1D03CA6B937D}.Release|x86.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 13 - 20
FactoryCraft/BiomGenerator.cpp

@@ -30,18 +30,15 @@ void BiomGenerator::initialize(JExpressionMemory* zMemory)
     {
         collection->initialize(zMemory);
     }
+    condition->compile(zMemory);
 }
 
-Framework::Either<Block*, int> BiomGenerator::generateBlock(int x,
-    int y,
-    int z,
-    int dimensionId,
-    JExpressionMemory* zMemory,
-    Chunk* partialGeneratedChunk)
+Framework::Either<Block*, int> BiomGenerator::generateBlock(
+    int x, int y, int z, int dimensionId, Chunk* partialGeneratedChunk)
 {
     for (GeneratorRule* rule : rules)
     {
-        if (rule->checkCondition(x, y, z, zMemory))
+        if (rule->checkCondition(x, y, z))
         {
             auto result = rule->generateBlock(x, y, z, dimensionId);
             if ((result.isA() && result.getA())
@@ -54,18 +51,17 @@ Framework::Either<Block*, int> BiomGenerator::generateBlock(int x,
     return BlockTypeEnum::AIR;
 }
 
-bool BiomGenerator::isApplicable(JExpressionMemory* zMemory)
+bool BiomGenerator::isApplicable()
 {
-    return condition->getValue(zMemory);
+    return condition->getValue();
 }
 
 void BiomGenerator::generateStructures(int x,
     int y,
     int z,
     int dimensionId,
-    JExpressionMemory* zMemory,
-    Framework::Vec3<int> minPos,
-    Framework::Vec3<int> maxPos,
+    Framework::Vec3<int>& minPos,
+    Framework::Vec3<int>& maxPos,
     Framework::RCArray<GeneratedStructure>* zResult)
 {
     int minSearchX = minPos.x - maxStructureOffset.x;
@@ -80,17 +76,16 @@ void BiomGenerator::generateStructures(int x,
         for (StructureTemplateCollection* collection : templates)
         {
             collection->generateStructures(
-                x, y, z, dimensionId, zMemory, minPos, maxPos, zResult);
+                x, y, z, dimensionId, minPos, maxPos, zResult);
         }
     }
 }
 
-void BiomGenerator::generateEntities(
-    int x, int y, int z, int dimensionId, JExpressionMemory* zMemory)
+void BiomGenerator::generateEntities(int x, int y, int z, int dimensionId)
 {
     for (EntityGenerator* entityGen : entityGenerators)
     {
-        if (entityGen->isGenerated(x, y, z, dimensionId, zMemory))
+        if (entityGen->isGenerated(x, y, z, dimensionId))
         {
             Entity* entity = entityGen->generate(
                 Framework::Vec3<float>((float)x, (float)y, (float)z),
@@ -242,8 +237,7 @@ Framework::JSON::JSONObject* BiomGeneratorFactory::toJsonObject(
     Framework::JSON::JSONArray* collections = new Framework::JSON::JSONArray();
     for (StructureTemplateCollection* collection : zObject->getTemplates())
     {
-        collections->addValue(
-            Game::INSTANCE->zTypeRegistry()
+        collections->addValue(Game::INSTANCE->zTypeRegistry()
                 ->toJson<StructureTemplateCollection>(collection));
     }
     result->addValue("structurCollections", collections);
@@ -272,8 +266,7 @@ JSONObjectValidationBuilder* BiomGeneratorFactory::addToValidator(
         ->withRequiredAttribute("condition",
             Game::INSTANCE->zTypeRegistry()->getValidator<JBoolExpression>())
         ->withRequiredArray("structurCollections")
-        ->addAcceptedTypeInArray(
-            Game::INSTANCE->zTypeRegistry()
+        ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
                 ->getValidator<StructureTemplateCollection>())
         ->finishArray()
         ->withRequiredArray("blocks")

+ 6 - 12
FactoryCraft/BiomGenerator.h

@@ -32,23 +32,17 @@ public:
     ~BiomGenerator();
 
     void initialize(JExpressionMemory* zMemory);
-    Framework::Either<Block*, int> generateBlock(int x,
-        int y,
-        int z,
-        int dimensionId,
-        JExpressionMemory* zMemory,
-        Chunk* partialGeneratedChunk);
-    bool isApplicable(JExpressionMemory* zMemory);
+    Framework::Either<Block*, int> generateBlock(
+        int x, int y, int z, int dimensionId, Chunk* partialGeneratedChunk);
+    bool isApplicable();
     void generateStructures(int x,
         int y,
         int z,
         int dimensionId,
-        JExpressionMemory* zMemory,
-        Framework::Vec3<int> minPos,
-        Framework::Vec3<int> maxPos,
+        Framework::Vec3<int>& minPos,
+        Framework::Vec3<int>& maxPos,
         Framework::RCArray<GeneratedStructure>* zResult);
-    void generateEntities(
-        int x, int y, int z, int dimensionId, JExpressionMemory* zMemory);
+    void generateEntities(int x, int y, int z, int dimensionId);
 
     const Framework::RCArray<StructureTemplateCollection>& getTemplates() const;
     Framework::Vec3<int> getMinStructureOffset() const;

+ 1 - 1
FactoryCraft/Chunk.cpp

@@ -317,7 +317,7 @@ Framework::Either<Block*, int> Chunk::zBlockNeighbor(
         else
             return (int)blockIds[index];
     }
-    if (added && location.z >= 0 && location.z < WORLD_HEIGHT)
+    if (location.z >= 0 && location.z < WORLD_HEIGHT)
         return Game::INSTANCE->zBlockAt(
             {location.x + this->location.x - CHUNK_SIZE / 2,
                 location.y + this->location.y - CHUNK_SIZE / 2,

+ 47 - 46
FactoryCraft/DimensionGenerator.cpp

@@ -31,11 +31,13 @@ void WorldHeightLayer::initialize(JExpressionMemory* zMemory)
     if (noise) noise->release();
     noise = JNoise::parseNoise(noiseConfig, zMemory);
     zMemory->setNoise(name, dynamic_cast<Noise*>(noise->getThis()));
+    valueP = zMemory->getFloatVariableP(name);
+    value->compile(zMemory);
 }
 
-void WorldHeightLayer::calculateValue(JExpressionMemory* zMemory)
+void WorldHeightLayer::calculateValue()
 {
-    zMemory->setFloatVariable(name, value->getValue(zMemory));
+    *valueP = value->getValue();
 }
 
 void WorldHeightLayer::setNoiseConfig(Framework::JSON::JSONObject* noiseConfig)
@@ -129,7 +131,7 @@ void DimensionGenerator::calculateHeightLayers()
 {
     for (WorldHeightLayer* layer : heightLayers)
     {
-        layer->calculateValue(jExpressionMemory);
+        layer->calculateValue();
     }
 }
 
@@ -140,13 +142,18 @@ Dimension* DimensionGenerator::createDimension()
 
 void DimensionGenerator::initialize(int worldSeed)
 {
-    jExpressionMemory->setFloatVariable("worldSeed", (float)worldSeed);
-    jExpressionMemory->setFloatVariable(
-        "dimensionSeed", seedExpression->getValue(jExpressionMemory));
+    this->worldSeed = jExpressionMemory->getFloatVariableP("worldSeed");
+    *this->worldSeed = (float)worldSeed;
+    this->dimensionSeed = jExpressionMemory->getFloatVariableP("dimensionSeed");
+    seedExpression->compile(jExpressionMemory);
+    *this->dimensionSeed = seedExpression->getValue();
     for (WorldHeightLayer* layer : heightLayers)
     {
         layer->initialize(jExpressionMemory);
     }
+    xPos = jExpressionMemory->getFloatVariableP("x");
+    yPos = jExpressionMemory->getFloatVariableP("y");
+    zPos = jExpressionMemory->getFloatVariableP("z");
 }
 
 int DimensionGenerator::getDimensionId() const
@@ -191,10 +198,6 @@ void DimensionGenerator::setSeed(JFloatExpression* seed)
     seedExpression = seed;
 }
 
-const Framework::Text DimensionGenerator::X = "x";
-const Framework::Text DimensionGenerator::Y = "y";
-const Framework::Text DimensionGenerator::Z = "z";
-
 JFloatExpression* DimensionGenerator::zSeed() const
 {
     return seedExpression;
@@ -231,7 +234,7 @@ BiomGenerator* BiomedCavedDimensionGenerator::zBiomGenerator()
 {
     for (BiomGenerator* generator : biomGenerators)
     {
-        if (generator->isApplicable(zMemory())) return generator;
+        if (generator->isApplicable()) return generator;
     }
     return 0;
 }
@@ -252,21 +255,15 @@ BiomedCavedDimensionGenerator::getGeneratedStructoresForArea(
     {
         for (int y = minSearchY; y <= maxSearchY; y++)
         {
-            zMemory()->setFloatVariable(X, (float)x);
-            zMemory()->setFloatVariable(Y, (float)y);
+            *xPos = (float)x;
+            *yPos = (float)y;
             calculateHeightLayers();
             BiomGenerator* gen = zBiomGenerator();
             for (int z = minSearchZ; z <= maxSearchZ; z++)
             {
-                zMemory()->setFloatVariable(Z, (float)z);
-                gen->generateStructures(x,
-                    y,
-                    z,
-                    getDimensionId(),
-                    zMemory(),
-                    minPos,
-                    maxPos,
-                    result);
+                *zPos = (float)z;
+                gen->generateStructures(
+                    x, y, z, getDimensionId(), minPos, maxPos, result);
             }
         }
     }
@@ -276,6 +273,7 @@ BiomedCavedDimensionGenerator::getGeneratedStructoresForArea(
 Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
 {
     zMemory()->lock();
+#ifdef CHUNK_GENERATION_DEBUG_LOG
     Framework::Logging::debug()
         << "generating chunk " << centerX << ", " << centerY;
     double structureTime = 0;
@@ -285,6 +283,7 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
     Framework::ZeitMesser zmGlobal;
     zm.messungStart();
     zmGlobal.messungStart();
+#endif
     Framework::RCArray<GeneratedStructure>* structures
         = getGeneratedStructoresForArea(
             Framework::Vec3<int>(
@@ -292,13 +291,17 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
             Framework::Vec3<int>(centerX + CHUNK_SIZE / 2,
                 centerY + CHUNK_SIZE / 2,
                 WORLD_HEIGHT - 1));
+#ifdef CHUNK_GENERATION_DEBUG_LOG
     zm.messungEnde();
     structureTime += zm.getSekunden();
     zm.messungStart();
+#endif
     CaveChunkGenerator* caveGen
         = caveGenerator->getGeneratorForChunk(centerX, centerY);
+#ifdef CHUNK_GENERATION_DEBUG_LOG
     zm.messungEnde();
     caveTime += zm.getSekunden();
+#endif
     Chunk* chunk
         = new Chunk(Framework::Punkt(centerX, centerY), getDimensionId());
     zMemory()->setCurrentChunk(dynamic_cast<Chunk*>(chunk->getThis()));
@@ -306,8 +309,8 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
     {
         for (int y = -CHUNK_SIZE / 2; y < CHUNK_SIZE / 2; y++)
         {
-            zMemory()->setFloatVariable(X, (float)x + (float)centerX);
-            zMemory()->setFloatVariable(Y, (float)y + (float)centerY);
+            *xPos = (float)x + (float)centerX;
+            *yPos = (float)y + (float)centerY;
             // calculate height layers
             calculateHeightLayers();
             // calculate biom
@@ -315,7 +318,7 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
             // generate blocks
             for (int z = 0; z < WORLD_HEIGHT; z++)
             {
-                zMemory()->setFloatVariable(Z, (float)z);
+                *zPos = (float)z;
                 Framework::Either<Block*, int> generated = BlockTypeEnum::AIR;
                 bool structureAffected = 0;
                 // check if the block is inside of a structure
@@ -339,15 +342,18 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
                     if (!inCave)
                     {
                         // generate biom block
+#ifdef CHUNK_GENERATION_DEBUG_LOG
                         zm.messungStart();
+#endif
                         generated = biom->generateBlock(x + centerX,
                             y + centerY,
                             z,
                             getDimensionId(),
-                            zMemory(),
                             chunk);
+#ifdef CHUNK_GENERATION_DEBUG_LOG
                         zm.messungEnde();
                         blockGenTime += zm.getSekunden();
+#endif
                     }
                 }
                 if (generated.isA())
@@ -365,11 +371,13 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
     }
     caveGen->release();
     structures->release();
+#ifdef CHUNK_GENERATION_DEBUG_LOG
     zmGlobal.messungEnde();
     Framework::Logging::trace() << "structureGenerationTime: " << structureTime;
     Framework::Logging::trace() << "caveGenerationTime: " << caveTime;
     Framework::Logging::trace() << "blockGenTime: " << blockGenTime;
     Framework::Logging::debug() << "totalTime: " << zmGlobal.getSekunden();
+#endif
     zMemory()->unlock();
     return chunk;
 }
@@ -379,8 +387,8 @@ void BiomedCavedDimensionGenerator::generateEntities(Chunk* zChunk)
     zMemory()->lock();
     zMemory()->setCurrentChunk(dynamic_cast<Chunk*>(zChunk->getThis()));
 
-    zMemory()->setFloatVariable(X, (float)zChunk->getCenter().x);
-    zMemory()->setFloatVariable(Y, (float)zChunk->getCenter().y);
+    *xPos = (float)zChunk->getCenter().x;
+    *yPos = (float)zChunk->getCenter().y;
 
     calculateHeightLayers();
     BiomGenerator* biom = zBiomGenerator();
@@ -394,16 +402,13 @@ void BiomedCavedDimensionGenerator::generateEntities(Chunk* zChunk)
                         x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z))
                     == BlockTypeEnum::AIR)
                 {
-                    zMemory()->setFloatVariable(
-                        X, (float)x + (float)zChunk->getCenter().x);
-                    zMemory()->setFloatVariable(
-                        Y, (float)y + (float)zChunk->getCenter().y);
-                    zMemory()->setFloatVariable(Z, (float)z);
+                    *xPos = (float)x + (float)zChunk->getCenter().x;
+                    *yPos = (float)y + (float)zChunk->getCenter().y;
+                    *zPos = (float)z;
                     biom->generateEntities(x + zChunk->getCenter().x,
                         y + zChunk->getCenter().y,
                         z,
-                        getDimensionId(),
-                        zMemory());
+                        getDimensionId());
                 }
             }
         }
@@ -428,13 +433,13 @@ Framework::Either<Block*, int> BiomedCavedDimensionGenerator::generateBlock(
     Framework::RCArray<GeneratedStructure>* structures
         = getGeneratedStructoresForArea(location, location);
 
-    zMemory()->setFloatVariable(X, (float)location.x);
-    zMemory()->setFloatVariable(Y, (float)location.y);
+    *xPos = (float)location.x;
+    *yPos = (float)location.y;
 
     calculateHeightLayers();
     BiomGenerator* biom = zBiomGenerator();
 
-    zMemory()->setFloatVariable(Z, (float)location.z);
+    *zPos = (float)location.z;
 
     for (auto structure : *structures)
     {
@@ -460,12 +465,8 @@ Framework::Either<Block*, int> BiomedCavedDimensionGenerator::generateBlock(
     }
     caveGen->release();
 
-    auto generated = biom->generateBlock(location.x,
-        location.y,
-        location.z,
-        getDimensionId(),
-        zMemory(),
-        zChunk);
+    auto generated = biom->generateBlock(
+        location.x, location.y, location.z, getDimensionId(), zChunk);
     zMemory()->unlock();
     return generated;
 }
@@ -475,8 +476,8 @@ bool BiomedCavedDimensionGenerator::spawnStructure(
     std::function<bool(GeneratorTemplate* tmpl)> filter)
 {
     zMemory()->lock();
-    zMemory()->setFloatVariable(X, (float)location.x);
-    zMemory()->setFloatVariable(Y, (float)location.y);
+    *xPos = (float)location.x;
+    *yPos = (float)location.y;
 
     BiomGenerator* biom = zBiomGenerator();
     zMemory()->unlock();

+ 7 - 5
FactoryCraft/DimensionGenerator.h

@@ -10,6 +10,8 @@
 #include "JNoise.h"
 #include "JsonExpression.h"
 
+// #define CHUNK_GENERATION_DEBUG_LOG to log generation times of chunks
+
 class DimensionGenerator;
 
 class WorldHeightLayer : public virtual Framework::ReferenceCounter
@@ -19,6 +21,7 @@ private:
     Noise* noise;
     Framework::Text name;
     JFloatExpression* value;
+    float* valueP;
 
 public:
     WorldHeightLayer();
@@ -26,7 +29,7 @@ public:
 
     void initialize(JExpressionMemory* zMemory);
 
-    void calculateValue(JExpressionMemory* zMemory);
+    void calculateValue();
 
     void setNoiseConfig(Framework::JSON::JSONObject* noiseConfig);
     Framework::JSON::JSONObject* zNoiseConfig() const;
@@ -56,8 +59,11 @@ private:
     Framework::RCArray<WorldHeightLayer> heightLayers;
     Framework::Text name;
     int dimensionId;
+    float* worldSeed;
+    float* dimensionSeed;
 
 protected:
+    float *xPos, *yPos, *zPos;
     DimensionGenerator();
     ~DimensionGenerator();
 
@@ -84,10 +90,6 @@ public:
     int getId() const;
     void setSeed(JFloatExpression* seed);
     JFloatExpression* zSeed() const;
-
-    static const Framework::Text X;
-    static const Framework::Text Y;
-    static const Framework::Text Z;
 };
 
 template<typename S> class DimensionGeneratorFactory

+ 3 - 3
FactoryCraft/EntityGenerator.cpp

@@ -37,14 +37,14 @@ void EntityGenerator::initialize(JExpressionMemory* zMemory)
         if (noise) noise->release();
         noise = JNoise::parseNoise(noiseConfig, zMemory);
     }
+    condition->compile(zMemory);
 }
 
-bool EntityGenerator::isGenerated(
-    int x, int y, int z, int dimensionId, JExpressionMemory* zMemory)
+bool EntityGenerator::isGenerated(int x, int y, int z, int dimensionId)
 {
     return (!noise
                || noise->getNoise((double)x, (double)y, (double)z) <= threshold)
-        && condition->getValue(zMemory);
+        && condition->getValue();
 }
 
 Entity* EntityGenerator::generate(Framework::Vec3<float> pos, int dimesnionId)

+ 1 - 2
FactoryCraft/EntityGenerator.h

@@ -25,8 +25,7 @@ public:
     EntityGenerator();
     ~EntityGenerator();
     void initialize(JExpressionMemory* zMemory);
-    bool isGenerated(
-        int x, int y, int z, int dimensionId, JExpressionMemory* zMemory);
+    bool isGenerated(int x, int y, int z, int dimensionId);
     Entity* generate(Framework::Vec3<float> pos, int dimesnionId);
 
     friend EntityGeneratorFactory;

+ 2 - 3
FactoryCraft/FlattenNoise.cpp

@@ -19,7 +19,6 @@ int FlattenNoise::getSeed() const
 
 double FlattenNoise::getNoise(double x, double y, double z)
 {
-    return MAX(
-        MIN((base->getNoise(x, y, z) - 0.5) * factor + 0.5 + minValue, 1.0),
-        0.0);
+    double value = (base->getNoise(x, y, z) - 0.5) * factor + 0.5 + minValue;
+    return MAX(MIN(value, 1.0), 0.0);
 }

+ 18 - 7
FactoryCraft/GeneratorRule.cpp

@@ -9,7 +9,9 @@ GeneratorRule::GeneratorRule()
       threshold(0.f),
       condition(0),
       bottomLayer(""),
-      topLayer("")
+      topLayer(""),
+      topLayerF(0),
+      botomLayerF(0)
 {}
 
 GeneratorRule::~GeneratorRule()
@@ -26,18 +28,27 @@ void GeneratorRule::initialize(JExpressionMemory* zMemory)
         if (noise) noise->release();
         noise = JNoise::parseNoise(noiseConfig, zMemory);
     }
+    if (topLayer.getLength())
+    {
+        topLayerF = zMemory->getFloatVariableP(topLayer);
+    }
+    if (bottomLayer.getLength())
+    {
+        botomLayerF = zMemory->getFloatVariableP(bottomLayer);
+    }
+    if (condition)
+    {
+        condition->compile(zMemory);
+    }
 }
 
-bool GeneratorRule::checkCondition(
-    int x, int y, int z, JExpressionMemory* zMemory)
+bool GeneratorRule::checkCondition(int x, int y, int z)
 {
-    if ((topLayer.getLength() && z > zMemory->getFloatVariable(topLayer))
-        || (bottomLayer.getLength()
-            && z < zMemory->getFloatVariable(bottomLayer)))
+    if ((topLayerF && z > *topLayerF) || (botomLayerF && z < *botomLayerF))
     {
         return false;
     }
-    return (!condition || condition->getValue(zMemory))
+    return (!condition || condition->getValue())
         && (!noise
             || noise->getNoise((double)x, (double)y, (double)z) <= threshold);
 }

+ 3 - 1
FactoryCraft/GeneratorRule.h

@@ -17,6 +17,8 @@ private:
     JBoolExpression* condition;
     Framework::Text bottomLayer;
     Framework::Text topLayer;
+    float* topLayerF;
+    float* botomLayerF;
 
 protected:
     virtual Framework::Either<Block*, int> createBlock(
@@ -29,7 +31,7 @@ public:
 
     void initialize(JExpressionMemory* zMemory);
 
-    bool checkCondition(int x, int y, int z, JExpressionMemory* zMemory);
+    bool checkCondition(int x, int y, int z);
     Framework::Either<Block*, int> generateBlock(
         int x, int y, int z, int dimensionId);
     void setNoiseConfig(Framework::JSON::JSONObject* noiseConfig);

+ 40 - 42
FactoryCraft/JNoise.cpp

@@ -19,7 +19,9 @@ Noise* JNoise::parseNoise(JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
         JFloatExpression* seedExpression
             = Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
                 zConfig->asObject()->zValue("seed"));
-        float seed = seedExpression->getValue(zMemory);
+        seedExpression->compile(zMemory);
+        float seed = seedExpression->getValue();
+        seedExpression->release();
         return new RandNoise((int)(round(seed)));
     }
     else if (type.istGleich("factorize"))
@@ -63,7 +65,9 @@ Noise* JNoise::parseNoise(JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
         JFloatExpression* seedExpression
             = Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
                 zConfig->asObject()->zValue("seed"));
-        float seed = seedExpression->getValue(zMemory);
+        seedExpression->compile(zMemory);
+        float seed = seedExpression->getValue();
+        seedExpression->release();
         FastNoiseLite* noise = new FastNoiseLite((int)(round(seed)));
         if (type.istGleich("Cellular"))
             noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_Cellular);
@@ -104,9 +108,9 @@ Noise* JNoise::parseNoise(JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
         if (zConfig->asObject()->hasValue("frequency"))
         {
             noise->SetFrequency((float)zConfig->asObject()
-                                    ->zValue("frequency")
-                                    ->asNumber()
-                                    ->getNumber());
+                    ->zValue("frequency")
+                    ->asNumber()
+                    ->getNumber());
         }
         if (zConfig->asObject()->hasValue("fractalType"))
         {
@@ -148,23 +152,23 @@ Noise* JNoise::parseNoise(JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
         if (zConfig->asObject()->hasValue("fractalOctaves"))
         {
             noise->SetFractalOctaves((int)round(zConfig->asObject()
-                                                    ->zValue("fractalOctaves")
-                                                    ->asNumber()
-                                                    ->getNumber()));
+                    ->zValue("fractalOctaves")
+                    ->asNumber()
+                    ->getNumber()));
         }
         if (zConfig->asObject()->hasValue("fractalLacunarity"))
         {
             noise->SetFractalLacunarity((float)zConfig->asObject()
-                                            ->zValue("fractalLacunarity")
-                                            ->asNumber()
-                                            ->getNumber());
+                    ->zValue("fractalLacunarity")
+                    ->asNumber()
+                    ->getNumber());
         }
         if (zConfig->asObject()->hasValue("fractalGain"))
         {
             noise->SetFractalGain((float)zConfig->asObject()
-                                      ->zValue("fractalGain")
-                                      ->asNumber()
-                                      ->getNumber());
+                    ->zValue("fractalGain")
+                    ->asNumber()
+                    ->getNumber());
         }
         if (zConfig->asObject()->hasValue("cellularDistanceFunction"))
         {
@@ -242,9 +246,9 @@ Noise* JNoise::parseNoise(JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
         if (zConfig->asObject()->hasValue("cellularJitter"))
         {
             noise->SetCellularJitter((float)zConfig->asObject()
-                                         ->zValue("cellularJitter")
-                                         ->asNumber()
-                                         ->getNumber());
+                    ->zValue("cellularJitter")
+                    ->asNumber()
+                    ->getNumber());
         }
         if (zConfig->asObject()->hasValue("domainWarpType"))
         {
@@ -271,18 +275,18 @@ Noise* JNoise::parseNoise(JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
         if (zConfig->asObject()->hasValue("domainWarpAmp"))
         {
             noise->SetDomainWarpAmp((float)zConfig->asObject()
-                                        ->zValue("domainWarpAmp")
-                                        ->asNumber()
-                                        ->getNumber());
+                    ->zValue("domainWarpAmp")
+                    ->asNumber()
+                    ->getNumber());
         }
         FastNoiseWrapper* result
             = new FastNoiseWrapper(noise, (int)(round(seed)));
         if (zConfig->asObject()->hasValue("multiplier"))
         {
             result->setMultiplier((float)zConfig->asObject()
-                                      ->zValue("multiplier")
-                                      ->asNumber()
-                                      ->getNumber());
+                    ->zValue("multiplier")
+                    ->asNumber()
+                    ->getNumber());
         }
         return result;
     }
@@ -329,15 +333,14 @@ Validator::DataValidator* JNoise::getValidator(bool optional)
     return Validator::DataValidator::buildForOneOf()
         ->typeSpecifiedByAttribute("type")
         ->addAcceptedType(validator1->setReferenceId("jn_random")
-                              ->withRequiredString("type")
-                              ->withExactMatch("random")
-                              ->finishString()
-                              ->withRequiredAttribute("seed",
-                                  Game::INSTANCE->zTypeRegistry()
-                                      ->getValidator<JFloatExpression>())
-                              ->finishObject())
-        ->addAcceptedType(
-            validator2->setReferenceId("jn_factorize")
+                ->withRequiredString("type")
+                ->withExactMatch("random")
+                ->finishString()
+                ->withRequiredAttribute("seed",
+                    Game::INSTANCE->zTypeRegistry()
+                        ->getValidator<JFloatExpression>())
+                ->finishObject())
+        ->addAcceptedType(validator2->setReferenceId("jn_factorize")
                 ->withRequiredString("type")
                 ->withExactMatch("factorize")
                 ->finishString()
@@ -350,8 +353,7 @@ Validator::DataValidator* JNoise::getValidator(bool optional)
                 ->withRequiredAttribute("noiseB",
                     dynamic_cast<Validator::DataValidator*>(refs->getThis()))
                 ->finishObject())
-        ->addAcceptedType(
-            validator3->setReferenceId("jn_multiply")
+        ->addAcceptedType(validator3->setReferenceId("jn_multiply")
                 ->withRequiredString("type")
                 ->withExactMatch("multiply")
                 ->finishString()
@@ -360,16 +362,14 @@ Validator::DataValidator* JNoise::getValidator(bool optional)
                 ->withRequiredAttribute("multiplier",
                     dynamic_cast<Validator::DataValidator*>(refs->getThis()))
                 ->finishObject())
-        ->addAcceptedType(
-            validator4->setReferenceId("jn_negate")
+        ->addAcceptedType(validator4->setReferenceId("jn_negate")
                 ->withRequiredString("type")
                 ->withExactMatch("negate")
                 ->finishString()
                 ->withRequiredAttribute("noise",
                     dynamic_cast<Validator::DataValidator*>(refs->getThis()))
                 ->finishObject())
-        ->addAcceptedType(
-            validator5->setReferenceId("jn_flatten")
+        ->addAcceptedType(validator5->setReferenceId("jn_flatten")
                 ->withRequiredString("type")
                 ->withExactMatch("flatten")
                 ->finishString()
@@ -382,8 +382,7 @@ Validator::DataValidator* JNoise::getValidator(bool optional)
                 ->withDefault(0.0)
                 ->finishNumber()
                 ->finishObject())
-        ->addAcceptedType(
-            validator6->setReferenceId("jn_scale")
+        ->addAcceptedType(validator6->setReferenceId("jn_scale")
                 ->withRequiredString("type")
                 ->withExactMatch("scale")
                 ->finishString()
@@ -392,8 +391,7 @@ Validator::DataValidator* JNoise::getValidator(bool optional)
                 ->withRequiredNumber("factor")
                 ->finishNumber()
                 ->finishObject())
-        ->addAcceptedType(
-            validator7->setReferenceId("jn_fastNoiseLite")
+        ->addAcceptedType(validator7->setReferenceId("jn_fastNoiseLite")
                 ->withRequiredString("type")
                 ->whichIsOneOf({"Cellular",
                     "ValueCubic",

+ 11 - 242
FactoryCraft/JsonExpression.cpp

@@ -24,15 +24,6 @@ void JExpressionMemory::unlock()
     cs.unlock();
 }
 
-float JExpressionMemory::getNoise(
-    Framework::Text name, float x, float y, float z) const
-{
-    Noise* currentNoise = noises.z(name, name.getLength());
-    if (currentNoise)
-        return (float)currentNoise->getNoise((double)x, (double)y, (double)z);
-    return 0.f;
-}
-
 Noise* JExpressionMemory::zNoiseP(Framework::Text name)
 {
     return noises.z(name, name.getLength());
@@ -49,11 +40,6 @@ void JExpressionMemory::setCurrentChunk(Chunk* chunk)
     currentChunk = chunk;
 }
 
-float JExpressionMemory::getFloatVariable(const Framework::Text& name) const
-{
-    return floatVariables.get(name, name.getLength());
-}
-
 float* JExpressionMemory::getFloatVariableP(const Framework::Text& name)
 {
     if (!floatVariables.contains(name, name.getLength()))
@@ -63,17 +49,6 @@ float* JExpressionMemory::getFloatVariableP(const Framework::Text& name)
     return floatVariables.getP(name, name.getLength());
 }
 
-void JExpressionMemory::setFloatVariable(
-    const Framework::Text& name, float value)
-{
-    floatVariables.set(name, name.getLength(), value);
-}
-
-bool JExpressionMemory::getBoolVariable(const Framework::Text& name) const
-{
-    return boolVariables.get(name, name.getLength());
-}
-
 bool* JExpressionMemory::getBoolVariableP(const Framework::Text& name)
 {
     if (!boolVariables.contains(name, name.getLength()))
@@ -83,16 +58,6 @@ bool* JExpressionMemory::getBoolVariableP(const Framework::Text& name)
     return boolVariables.getP(name, name.getLength());
 }
 
-void JExpressionMemory::setBoolVariable(const Framework::Text& name, bool value)
-{
-    return boolVariables.set(name, name.getLength(), value);
-}
-
-Chunk* JExpressionMemory::zCurrentChunk()
-{
-    return currentChunk;
-}
-
 Chunk** JExpressionMemory::zzCurrentChunk()
 {
     return &currentChunk;
@@ -103,17 +68,9 @@ JFloatExpression::JFloatExpression()
       compiled(0)
 {}
 
-float JFloatExpression::getValue(JExpressionMemory* zMemory)
+float JFloatExpression::getValue()
 {
-    FloatFunc func = compile(zMemory);
-    float result = func();
-    /* float old = getValueOld(zMemory);
-    if (result != old)
-    {
-        float x = func();
-        Framework::Logging::debug() << "fehler" << x << " != " << old;
-    }*/
-    return result;
+    return compiled();
 }
 
 FloatFunc JFloatExpression::compile(JExpressionMemory* zMemory)
@@ -135,15 +92,9 @@ JBoolExpression::JBoolExpression()
       compiled(0)
 {}
 
-bool JBoolExpression::getValue(JExpressionMemory* zMemory)
+bool JBoolExpression::getValue()
 {
-    bool result = compile(zMemory)();
-    /* bool old = getValueOld(zMemory);
-    if (result != old)
-    {
-        Framework::Logging::debug() << "fehler";
-    }*/
-    return result;
+    return compiled();
 }
 
 BoolFunc JBoolExpression::compile(JExpressionMemory* zMemory)
@@ -165,11 +116,6 @@ JVariableFloatExpression::JVariableFloatExpression()
     : JFloatExpression()
 {}
 
-float JVariableFloatExpression::getValueOld(JExpressionMemory* zMemory)
-{
-    return zMemory->getFloatVariable(name);
-}
-
 Framework::Assembly::AssemblyBlock& JVariableFloatExpression::buildAssembly(
     JExpressionMemory* zMemory)
 {
@@ -224,11 +170,6 @@ JVariableBoolExpression::JVariableBoolExpression()
     : JBoolExpression()
 {}
 
-bool JVariableBoolExpression::getValueOld(JExpressionMemory* zMemory)
-{
-    return zMemory->getBoolVariable(name);
-}
-
 Framework::Assembly::AssemblyBlock& JVariableBoolExpression::buildAssembly(
     JExpressionMemory* zMemory)
 {
@@ -284,11 +225,6 @@ JConstantFloatExpression::JConstantFloatExpression()
       value(0)
 {}
 
-float JConstantFloatExpression::getValueOld(JExpressionMemory* zMemory)
-{
-    return value;
-}
-
 Framework::Assembly::AssemblyBlock& JConstantFloatExpression::buildAssembly(
     JExpressionMemory* zMemory)
 {
@@ -342,11 +278,6 @@ JConstantBoolExpression::JConstantBoolExpression()
     : JBoolExpression()
 {}
 
-bool JConstantBoolExpression::getValueOld(JExpressionMemory* zMemory)
-{
-    return value;
-}
-
 Framework::Assembly::AssemblyBlock& JConstantBoolExpression::buildAssembly(
     JExpressionMemory* zMemory)
 {
@@ -410,14 +341,6 @@ JNoiseFloatExpression::~JNoiseFloatExpression()
     if (z) z->release();
 }
 
-float JNoiseFloatExpression::getValueOld(JExpressionMemory* zMemory)
-{
-    return zMemory->getNoise(name,
-        x->getValueOld(zMemory),
-        y->getValueOld(zMemory),
-        z->getValueOld(zMemory));
-}
-
 Framework::Assembly::AssemblyBlock& JNoiseFloatExpression::buildAssembly(
     JExpressionMemory* zMemory)
 {
@@ -595,29 +518,9 @@ const char* JNoiseFloatExpressionFactory::getTypeToken() const
 }
 
 JOperatorFloatExpression::JOperatorFloatExpression()
-    : JFloatExpression(),
-      accumulator([](float a, float b) { return 0.f; })
+    : JFloatExpression()
 {}
 
-float JOperatorFloatExpression::getValueOld(JExpressionMemory* zMemory)
-{
-    bool first = 1;
-    float val = 0.f;
-    for (JFloatExpression* expression : values)
-    {
-        if (first)
-        {
-            first = 0;
-            val = expression->getValueOld(zMemory);
-        }
-        else
-        {
-            val = accumulator(val, expression->getValueOld(zMemory));
-        }
-    }
-    return val;
-}
-
 Framework::Assembly::AssemblyBlock& JOperatorFloatExpression::buildAssembly(
     JExpressionMemory* zMemory)
 {
@@ -690,11 +593,9 @@ Framework::Assembly::AssemblyBlock& JOperatorFloatExpression::buildAssembly(
     return codeBlock;
 }
 
-void JOperatorFloatExpression::setOperator(
-    Framework::Text op, std::function<float(float a, float b)> accumulator)
+void JOperatorFloatExpression::setOperator(Framework::Text op)
 {
     this->op = op;
-    this->accumulator = accumulator;
 }
 
 Framework::Text JOperatorFloatExpression::getOperator()
@@ -721,23 +622,7 @@ JOperatorFloatExpression* JOperatorFloatExpressionFactory::fromJson(
     Framework::JSON::JSONObject* zJson) const
 {
     JOperatorFloatExpression* result = new JOperatorFloatExpression();
-    Framework::Text op = zJson->zValue("operator")->asString()->getString();
-    if (op.istGleich("+"))
-    {
-        result->setOperator("+", [](float a, float b) { return a + b; });
-    }
-    else if (op.istGleich("-"))
-    {
-        result->setOperator("-", [](float a, float b) { return a - b; });
-    }
-    else if (op.istGleich("*"))
-    {
-        result->setOperator("*", [](float a, float b) { return a * b; });
-    }
-    else if (op.istGleich("/"))
-    {
-        result->setOperator("/", [](float a, float b) { return a / b; });
-    }
+    result->setOperator(zJson->zValue("operator")->asString()->getString());
     for (Framework::JSON::JSONValue* value :
         *zJson->zValue("values")->asArray())
     {
@@ -785,25 +670,6 @@ JBoolOperatorBoolExpression::JBoolOperatorBoolExpression()
     : JBoolExpression()
 {}
 
-bool JBoolOperatorBoolExpression::getValueOld(JExpressionMemory* zMemory)
-{
-    bool first = 1;
-    bool val = 0;
-    for (JBoolExpression* expression : values)
-    {
-        if (first)
-        {
-            first = 0;
-            val = expression->getValueOld(zMemory);
-        }
-        else
-        {
-            val = accumulator(val, expression->getValueOld(zMemory));
-        }
-    }
-    return val;
-}
-
 Framework::Assembly::AssemblyBlock& JBoolOperatorBoolExpression::buildAssembly(
     JExpressionMemory* zMemory)
 {
@@ -855,11 +721,9 @@ Framework::Assembly::AssemblyBlock& JBoolOperatorBoolExpression::buildAssembly(
     return codeBlock;
 }
 
-void JBoolOperatorBoolExpression::setOperator(
-    Framework::Text op, std::function<float(float a, float b)> accumulator)
+void JBoolOperatorBoolExpression::setOperator(Framework::Text op)
 {
     this->op = op;
-    this->accumulator = accumulator;
 }
 
 Framework::Text JBoolOperatorBoolExpression::getOperator()
@@ -892,15 +756,7 @@ JBoolOperatorBoolExpression* JBoolOperatorBoolExpressionFactory::fromJson(
         result->addValue(
             Game::INSTANCE->zTypeRegistry()->fromJson<JBoolExpression>(value));
     }
-    Framework::Text op = zJson->zValue("operator")->asString()->getString();
-    if (op.istGleich("&&"))
-    {
-        result->setOperator("&&", [](bool a, bool b) { return a && b; });
-    }
-    else if (op.istGleich("||"))
-    {
-        result->setOperator("||", [](bool a, bool b) { return a || b; });
-    }
+    result->setOperator(zJson->zValue("operator")->asString()->getString());
     return result;
 }
 
@@ -942,22 +798,6 @@ JFloatOperatorBoolExpression::JFloatOperatorBoolExpression()
     : JBoolExpression()
 {}
 
-bool JFloatOperatorBoolExpression::getValueOld(JExpressionMemory* zMemory)
-{
-    bool first = 1;
-    bool val = 1;
-    float last = 0.f;
-    for (JFloatExpression* expression : values)
-    {
-        float current = expression->getValueOld(zMemory);
-        if (!first) val &= accumulator(last, current);
-        first = 0;
-        last = current;
-        if (!val) break;
-    }
-    return val;
-}
-
 Framework::Assembly::AssemblyBlock& JFloatOperatorBoolExpression::buildAssembly(
     JExpressionMemory* zMemory)
 {
@@ -1088,11 +928,9 @@ Framework::Assembly::AssemblyBlock& JFloatOperatorBoolExpression::buildAssembly(
     return codeBlock;
 }
 
-void JFloatOperatorBoolExpression::setOperator(
-    Framework::Text op, std::function<bool(float a, float b)> accumulator)
+void JFloatOperatorBoolExpression::setOperator(Framework::Text op)
 {
     this->op = op;
-    this->accumulator = accumulator;
 }
 
 Framework::Text JFloatOperatorBoolExpression::getOperator()
@@ -1119,61 +957,7 @@ JFloatOperatorBoolExpression* JFloatOperatorBoolExpressionFactory::fromJson(
     Framework::JSON::JSONObject* zJson) const
 {
     JFloatOperatorBoolExpression* result = new JFloatOperatorBoolExpression();
-    Framework::Text op = zJson->zValue("operator")->asString()->getString();
-    if (op.istGleich(">"))
-    {
-        result->setOperator(">", [](float a, float b) { return a > b; });
-    }
-    else if (op.istGleich("<"))
-    {
-        result->setOperator("<", [](float a, float b) { return a < b; });
-    }
-    else if (op.istGleich(">="))
-    {
-        result->setOperator(">=", [](float a, float b) { return a >= b; });
-    }
-    else if (op.istGleich("<="))
-    {
-        result->setOperator("<=", [](float a, float b) { return a <= b; });
-    }
-    else if (op.istGleich("=="))
-    {
-        result->setOperator("==", [](float a, float b) { return a == b; });
-    }
-    else if (op.istGleich("!="))
-    {
-        result->setOperator("!=", [](float a, float b) { return a != b; });
-    }
-    else if (op.istGleich(">i"))
-    {
-        result->setOperator(
-            ">i", [](float a, float b) { return (int)a > (int)b; });
-    }
-    else if (op.istGleich("<i"))
-    {
-        result->setOperator(
-            "<i", [](float a, float b) { return (int)a < (int)b; });
-    }
-    else if (op.istGleich(">=i"))
-    {
-        result->setOperator(
-            ">=i", [](float a, float b) { return (int)a >= (int)b; });
-    }
-    else if (op.istGleich("<=i"))
-    {
-        result->setOperator(
-            "<=i", [](float a, float b) { return (int)a <= (int)b; });
-    }
-    else if (op.istGleich("==i"))
-    {
-        result->setOperator(
-            "==i", [](float a, float b) { return (int)a == (int)b; });
-    }
-    else if (op.istGleich("!=i"))
-    {
-        result->setOperator(
-            "!=i", [](float a, float b) { return (int)a != (int)b; });
-    }
+    result->setOperator(zJson->zValue("operator")->asString()->getString());
     for (Framework::JSON::JSONValue* value :
         *zJson->zValue("values")->asArray())
     {
@@ -1251,21 +1035,6 @@ bool JBlockTypeBoolExpression::isValidPosition(
         && Game::getChunkCenter(x, y) == currentChunk->getCenter();
 }
 
-bool JBlockTypeBoolExpression::getValueOld(JExpressionMemory* zMemory)
-{
-    int x = (int)(round(this->x->getValueOld(zMemory)));
-    int y = (int)(round(this->y->getValueOld(zMemory)));
-    int z = (int)(round(this->z->getValueOld(zMemory)));
-    if (z < 0 || z >= WORLD_HEIGHT || !zMemory->zCurrentChunk()
-        || Game::getChunkCenter(x, y) != zMemory->zCurrentChunk()->getCenter())
-    {
-        return 0;
-    }
-    return zMemory->zCurrentChunk()->getBlockTypeAt(
-               Dimension::chunkCoordinates({x, y, z}))
-        == typeId;
-}
-
 Framework::Assembly::AssemblyBlock& JBlockTypeBoolExpression::buildAssembly(
     JExpressionMemory* zMemory)
 {

+ 5 - 28
FactoryCraft/JsonExpression.h

@@ -31,18 +31,12 @@ public:
     void lock();
     void unlock();
 
-    float getNoise(Framework::Text name, float x, float y, float z) const;
     Noise* zNoiseP(Framework::Text name);
     void setNoise(Framework::Text name, Noise* noise);
     void setCurrentChunk(Chunk* chunk);
 
-    float getFloatVariable(const Framework::Text& name) const;
     float* getFloatVariableP(const Framework::Text& name);
-    void setFloatVariable(const Framework::Text& name, float value);
-    bool getBoolVariable(const Framework::Text& name) const;
     bool* getBoolVariableP(const Framework::Text& name);
-    void setBoolVariable(const Framework::Text& name, bool value);
-    Chunk* zCurrentChunk();
     Chunk** zzCurrentChunk();
 };
 
@@ -62,8 +56,7 @@ public:
     virtual Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory)
         = 0;
-    virtual float getValueOld(JExpressionMemory* zMemory) = 0;
-    float getValue(JExpressionMemory* zMemory);
+    float getValue();
     FloatFunc compile(JExpressionMemory* zMemory);
 };
 
@@ -83,8 +76,7 @@ public:
     virtual Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory)
         = 0;
-    virtual bool getValueOld(JExpressionMemory* zMemory) = 0;
-    bool getValue(JExpressionMemory* zMemory);
+    bool getValue();
     BoolFunc compile(JExpressionMemory* zMemory);
 };
 
@@ -95,7 +87,6 @@ private:
 
 public:
     JVariableFloatExpression();
-    float getValueOld(JExpressionMemory* zMemory) override;
     Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory) override;
 
@@ -124,7 +115,6 @@ private:
 
 public:
     JVariableBoolExpression();
-    bool getValueOld(JExpressionMemory* zMemory) override;
     Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory) override;
 
@@ -153,7 +143,6 @@ private:
 
 public:
     JConstantFloatExpression();
-    float getValueOld(JExpressionMemory* zMemory) override;
     Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory) override;
 
@@ -182,7 +171,6 @@ private:
 
 public:
     JConstantBoolExpression();
-    bool getValueOld(JExpressionMemory* zMemory) override;
     Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory) override;
 
@@ -215,7 +203,6 @@ private:
 public:
     JNoiseFloatExpression();
     ~JNoiseFloatExpression();
-    float getValueOld(JExpressionMemory* zMemory) override;
     Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory) override;
 
@@ -247,17 +234,14 @@ class JOperatorFloatExpression : public JFloatExpression
 {
 private:
     Framework::Text op;
-    std::function<float(float a, float b)> accumulator;
     Framework::RCArray<JFloatExpression> values;
 
 public:
     JOperatorFloatExpression();
-    float getValueOld(JExpressionMemory* zMemory) override;
     Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory) override;
 
-    void setOperator(
-        Framework::Text op, std::function<float(float a, float b)> accumulator);
+    void setOperator(Framework::Text op);
     Framework::Text getOperator();
     void addValue(JFloatExpression* value);
     const Framework::RCArray<JFloatExpression>& getValues() const;
@@ -281,17 +265,14 @@ class JBoolOperatorBoolExpression : public JBoolExpression
 {
 private:
     Framework::Text op;
-    std::function<bool(bool a, bool b)> accumulator;
     Framework::RCArray<JBoolExpression> values;
 
 public:
     JBoolOperatorBoolExpression();
-    bool getValueOld(JExpressionMemory* zMemory) override;
     Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory) override;
 
-    void setOperator(
-        Framework::Text op, std::function<float(float a, float b)> accumulator);
+    void setOperator(Framework::Text op);
     Framework::Text getOperator();
     void addValue(JBoolExpression* value);
     const Framework::RCArray<JBoolExpression>& getValues() const;
@@ -315,17 +296,14 @@ class JFloatOperatorBoolExpression : public JBoolExpression
 {
 private:
     Framework::Text op;
-    std::function<bool(float a, float b)> accumulator;
     Framework::RCArray<JFloatExpression> values;
 
 public:
     JFloatOperatorBoolExpression();
-    bool getValueOld(JExpressionMemory* zMemory) override;
     Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory) override;
 
-    void setOperator(
-        Framework::Text op, std::function<bool(float a, float b)> accumulator);
+    void setOperator(Framework::Text op);
     Framework::Text getOperator();
     void addValue(JFloatExpression* value);
     const Framework::RCArray<JFloatExpression>& getValues() const;
@@ -361,7 +339,6 @@ private:
     bool isValidPosition(int x, int y, Chunk* currentChunk);
 
 public:
-    bool getValueOld(JExpressionMemory* zMemory) override;
     Framework::Assembly::AssemblyBlock& buildAssembly(
         JExpressionMemory* zMemory) override;
 

+ 2 - 1
FactoryCraft/ScaleNoise.cpp

@@ -13,5 +13,6 @@ int ScaleNoise::getSeed() const
 
 double ScaleNoise::getNoise(double x, double y, double z)
 {
-    return MIN(MAX(base->getNoise(x, y, z) * factor, 0.0), 1.0);
+    double value = base->getNoise(x, y, z) * factor;
+    return MIN(MAX(value, 0.0), 1.0);
 }

+ 8 - 4
FactoryCraft/ShapedNoise.cpp

@@ -19,13 +19,17 @@ double ShapedNoise::getNoise(double x, double y, double z)
 {
     double max = 0;
     double noise = delegateNoise->getNoise(x, y, z);
-    max = MAX(max, abs(noise - delegateNoise->getNoise(x + neighborOffset, y, z)));
-    max = MAX(max, abs(noise - delegateNoise->getNoise(x, y + neighborOffset, z)));
-    max = MAX(max, abs(noise - delegateNoise->getNoise(x, y, z + neighborOffset)));
+    double value
+        = abs(noise - delegateNoise->getNoise(x + neighborOffset, y, z));
+    max = MAX(max, value);
+    value = abs(noise - delegateNoise->getNoise(x, y + neighborOffset, z));
+    max = MAX(max, value);
+    value = abs(noise - delegateNoise->getNoise(x, y, z + neighborOffset));
+    max = MAX(max, value);
     return max;
 }
 
 int ShapedNoise::getSeed() const
 {
-	return delegateNoise->getSeed();
+    return delegateNoise->getSeed();
 }

+ 4 - 4
FactoryCraft/StructureCollection.cpp

@@ -28,15 +28,15 @@ void StructureTemplateCollection::initialize(JExpressionMemory* zMemory)
     if (structureNoise) structureNoise->release();
     activeNoise = JNoise::parseNoise(activeNoiseConfig, zMemory);
     structureNoise = JNoise::parseNoise(structureNoiseConfig, zMemory);
+    condition->compile(zMemory);
 }
 
 void StructureTemplateCollection::generateStructures(int x,
     int y,
     int z,
     int dimensionId,
-    JExpressionMemory* zMemory,
-    Framework::Vec3<int> minPos,
-    Framework::Vec3<int> maxPos,
+    Framework::Vec3<int>& minPos,
+    Framework::Vec3<int>& maxPos,
     Framework::RCArray<GeneratedStructure>* zResult)
 {
     int minSearchX = minPos.x - maxAffected.x;
@@ -50,7 +50,7 @@ void StructureTemplateCollection::generateStructures(int x,
     {
         if (activeNoise->getNoise((double)x, (double)y, (double)z) < threshold)
         {
-            if (condition->getValue(zMemory))
+            if (condition->getValue())
             {
                 double rValue
                     = structureNoise->getNoise((double)x, (double)y, (double)z);

+ 2 - 3
FactoryCraft/StructureCollection.h

@@ -27,9 +27,8 @@ public:
         int y,
         int z,
         int dimensionId,
-        JExpressionMemory* zMemory,
-        Framework::Vec3<int> minPos,
-        Framework::Vec3<int> maxPos,
+        Framework::Vec3<int>& minPos,
+        Framework::Vec3<int>& maxPos,
         Framework::RCArray<GeneratedStructure>* zResult);
 
     void setThreshold(double threshold);

+ 13 - 3
FactoryCraft/WorldGenerator.cpp

@@ -92,6 +92,8 @@ DimensionGenerator* WorldGenerator::zGenerator(int dimensionId)
 
 void WorldGenerator::thread()
 {
+    double completeTime = 0.0;
+    int generatedChunks = 0;
     while (!exit)
     {
         cs.lock();
@@ -106,6 +108,9 @@ void WorldGenerator::thread()
         cs.unlock();
         if (!hasNext)
         {
+            chunksPerSecond = 0.0;
+            completeTime = 0;
+            generatedChunks = 0;
             Sleep(1000);
             continue;
         }
@@ -121,8 +126,6 @@ void WorldGenerator::thread()
         Punkt end = Game::INSTANCE->getChunkCenter(next.endX, next.endY);
         int xDir = start.x > end.x ? -1 : 1;
         int yDir = start.y > end.y ? -1 : 1;
-        double completeTime = 0.0;
-        int generatedChunks = 0;
         for (int x = start.x; xDir < 0 ? x >= end.x : x <= end.x;
             x += CHUNK_SIZE * xDir)
         {
@@ -135,38 +138,45 @@ void WorldGenerator::thread()
                     zm.messungStart();
                     Chunk* generatedChunk
                         = zGenerator(next.dimensionId)->generateChunk(x, y);
+#ifdef CHUNK_GENERATION_DEBUG_LOG
                     zm.messungEnde();
                     Framework::Logging::trace()
                         << "block generation time: " << zm.getSekunden();
                     completeTime += zm.getSekunden();
                     zm.messungStart();
+#endif
                     generatedChunk->initializeLightning();
+#ifdef CHUNK_GENERATION_DEBUG_LOG
                     zm.messungEnde();
                     Framework::Logging::trace()
                         << "light calculation: " << zm.getSekunden();
                     completeTime += zm.getSekunden();
                     zm.messungStart();
+#endif
                     generatedChunk->removeUnusedBlocks();
+#ifdef CHUNK_GENERATION_DEBUG_LOG
                     zm.messungEnde();
                     Framework::Logging::trace()
                         << "unused block removal: " << zm.getSekunden();
                     completeTime += zm.getSekunden();
                     zm.messungStart();
+#endif
                     generatedChunk->getThis();
                     dim->setChunk(generatedChunk, Punkt(x, y));
                     zGenerator(next.dimensionId)
                         ->generateEntities(generatedChunk);
                     generatedChunk->release();
                     zm.messungEnde();
+#ifdef CHUNK_GENERATION_DEBUG_LOG
                     Framework::Logging::trace()
                         << "adding chunk to map: " << zm.getSekunden();
+#endif
                     completeTime += zm.getSekunden();
                     generatedChunks++;
                     chunksPerSecond = generatedChunks / completeTime;
                 }
             }
         }
-        chunksPerSecond = 0.0;
     }
     Framework::Logging::info() << "World Generator thread exited";
 }

+ 0 - 11
FactoryCraft/WormCaveGenerator.cpp

@@ -204,10 +204,6 @@ NoiseWorm3D* WormCaveGenerator::zWormOfChunk(int x, int y)
             return worm;
         }
     }
-    for (Framework::Punkt p : noWormChunks)
-    {
-        if (p.x == x && p.y == y) return 0;
-    }
     float cNoise
         = (float)wormStartNoise->getNoise((double)x, (double)y, (double)0);
     if (cNoise < cavePosibillity)
@@ -248,13 +244,6 @@ NoiseWorm3D* WormCaveGenerator::zWormOfChunk(int x, int y)
         cache.add(worm);
         return worm;
     }
-    else
-    {
-        if (noWormChunks.getEintragAnzahl()
-            > (maxDistant * 2) / CHUNK_SIZE * (maxDistant * 2) / CHUNK_SIZE * 3)
-            noWormChunks.remove(0);
-        noWormChunks.add(Framework::Punkt(x, y));
-    }
     return 0;
 }
 

+ 0 - 1
FactoryCraft/WormCaveGenerator.h

@@ -52,7 +52,6 @@ private:
     float cavePosibillity;
     Noise* wormStartNoise;
     Framework::RCArray<NoiseWorm3D> cache;
-    Framework::Array<Framework::Punkt> noWormChunks;
 
     NoiseWorm3D* zWormOfChunk(int x, int y);
 

+ 165 - 0
assembly/assembly.vcxproj

@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>17.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{1c0b0808-0d8e-49a6-87c2-1d03ca6b937d}</ProjectGuid>
+    <RootNamespace>assembly</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <CustomBuildAfterTargets>
+    </CustomBuildAfterTargets>
+    <IncludePath>..\..\..\..\..\Allgemein\Framework;..\FactoryCraft;..\..\..\..\..\Allgemein\Network\Network;..\..\..\..\..\Allgemein\Network;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\..\..\Allgemein\Framework\x64\release;..\..\..\..\..\Allgemein\Network\x64\release;$(LibraryPath)</LibraryPath>
+    <ExternalIncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</ExternalIncludePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <IncludePath>..\..\..\..\..\Allgemein\Framework;..\FactoryCraft;..\..\..\..\..\Allgemein\Network\Network;..\..\..\..\..\Allgemein\Network;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\..\..\Allgemein\Framework\x64\debug;..\..\..\..\..\Allgemein\Network\x64\debug;$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>Framework.lib;Network.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>Framework.lib;Network.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="start.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <CustomBuild Include="test.asm">
+      <FileType>Document</FileType>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm -f win64 -o test.obj test.asm</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">test.obj</Outputs>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
+  </ImportGroup>
+</Project>

+ 27 - 0
assembly/assembly.vcxproj.filters

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Headerdateien">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Ressourcendateien">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="start.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <CustomBuild Include="test.asm">
+      <Filter>Quelldateien</Filter>
+    </CustomBuild>
+  </ItemGroup>
+</Project>

+ 307 - 0
assembly/start.cpp

@@ -0,0 +1,307 @@
+#include <Assembly.h>
+#include <functional>
+#include <iostream>
+#include <malloc.h>
+#include <windows.h>
+#include <Zeit.h>
+
+using namespace Framework;
+using namespace Assembly;
+
+typedef int (*valF)(void*);
+typedef int (*compF)();
+
+template<typename T> class Val
+{
+protected:
+    AssemblyBlock block;
+    T* self;
+
+public:
+    Val(T* self)
+        : self(self)
+    {}
+
+    inline int getValueInline()
+    {
+        return self->getValue2();
+    }
+
+    virtual int getValue() = 0;
+    virtual valF compileFP() = 0;
+    virtual std::function<int()> compileStdF() = 0;
+
+    compF compileToAssembly()
+    {
+        internalCompileAssembly();
+        block.optimize();
+        return block.compileToFunction<compF>();
+    }
+
+    virtual AssemblyBlock& internalCompileAssembly() = 0;
+
+    inline AssemblyBlock& getBlock()
+    {
+        return block;
+    }
+};
+
+class RandVal : public Val<RandVal>
+{
+public:
+    RandVal()
+        : Val(this)
+    {}
+
+    int getValue() override
+    {
+        return rand();
+    }
+
+    int getValue2()
+    {
+        return rand();
+    }
+
+    valF compileFP() override
+    {
+        return [](void* v) { return rand(); };
+    }
+
+    std::function<int()> compileStdF() override
+    {
+        return []() { return rand(); };
+    }
+
+    AssemblyBlock& internalCompileAssembly() override
+    {
+        block.addCall(rand);
+        return block;
+    }
+};
+
+class ConstVal : public Val<ConstVal>
+{
+private:
+    int value;
+
+public:
+    ConstVal(int value)
+        : Val(this),
+          value(value)
+    {}
+
+    int getValue() override
+    {
+        return value;
+    }
+
+    inline int getValue2()
+    {
+        return value;
+    }
+
+    valF compileFP() override
+    {
+        return [](void* v) { return ((ConstVal*)v)->value; };
+    }
+
+    std::function<int()> compileStdF() override
+    {
+        const int& value = this->value;
+        return [value]() { return value; };
+    }
+
+    AssemblyBlock& internalCompileAssembly() override
+    {
+        block.addLoadValue(&value, RAX);
+        return block;
+    }
+};
+
+template<typename T1, typename T2> class AdditionVal
+    : public Val<AdditionVal<T1, T2>>
+{
+private:
+    Val<T1>* a;
+    Val<T2>* b;
+    valF af;
+    valF bf;
+    std::function<int()> saf;
+    std::function<int()> sbf;
+
+public:
+    AdditionVal(Val<T1>* a, Val<T2>* b)
+        : Val<AdditionVal<T1, T2>>(this),
+          a(a),
+          b(b),
+          af(a->compileFP()),
+          bf(b->compileFP()),
+          saf(a->compileStdF()),
+          sbf(b->compileStdF())
+    {}
+
+    int getValue() override
+    {
+        return a->getValue() + b->getValue();
+    }
+
+    inline int getValue2()
+    {
+        return a->getValueInline() + b->getValueInline();
+    }
+
+    valF compileFP() override
+    {
+        return [](void* v) {
+            AdditionVal* av = (AdditionVal*)v;
+            return av->af(av->a) + av->bf(av->b);
+        };
+    }
+
+    std::function<int()> compileStdF() override
+    {
+        const std::function<int()>& aFunc = saf;
+        const std::function<int()>& bFunc = sbf;
+        return [aFunc, bFunc]() { return aFunc() + bFunc(); };
+    }
+
+    AssemblyBlock& internalCompileAssembly() override
+    {
+        GPRegister result = RAX;
+        GPRegister result2 = RAX;
+        FPRegister resultFP;
+        this->getBlock().addBlock(
+            &a->internalCompileAssembly(), {}, {}, &result, &resultFP);
+        this->getBlock().addBlock(
+            &b->internalCompileAssembly(), {result}, {}, &result2, &resultFP);
+        this->getBlock().addInstruction(new Instruction(ADD,
+            {new GPRegisterArgument(result, LOWER32),
+                new GPRegisterArgument(result2, LOWER32)}));
+        if (result != RAX)
+        {
+            this->getBlock().addMoveValue(result, RAX, LOWER32);
+        }
+        return this->getBlock();
+    }
+};
+
+extern "C"
+{
+    extern int getVal(void*);
+}
+
+template<typename T> __declspec(noinline) int get(T* t)
+{
+    return t->getValueInline();
+}
+
+int main()
+{
+    RandVal* r = new RandVal();
+    auto test
+        = new AdditionVal<AdditionVal<AdditionVal<RandVal, ConstVal>, ConstVal>,
+            AdditionVal<ConstVal, ConstVal>>(
+            new AdditionVal<AdditionVal<RandVal, ConstVal>, ConstVal>(
+                new AdditionVal<RandVal, ConstVal>(r, new ConstVal(2)),
+                new ConstVal(3)),
+            new AdditionVal<ConstVal, ConstVal>(
+                new ConstVal(4), new ConstVal(5)));
+    ZeitMesser zeitMesser;
+    srand(0);
+    zeitMesser.messungStart();
+    __int64 res = 0;
+    for (int i = 0; i < 100000000; i++)
+    {
+        res += get(test);
+    }
+    zeitMesser.messungEnde();
+    std::cout << "inlined Time: " << zeitMesser.getSekunden() << "s"
+              << " result: " << res << std::endl;
+    srand(0);
+    zeitMesser.messungStart();
+    res = 0;
+    for (int i = 0; i < 100000000; i++)
+    {
+        res += test->getValue();
+    }
+    zeitMesser.messungEnde();
+    std::cout << "getValue() Time: " << zeitMesser.getSekunden() << "s"
+              << " result: " << res << std::endl;
+    res = 0;
+    srand(0);
+    auto val = test->compileFP();
+    zeitMesser.messungStart();
+    for (int i = 0; i < 100000000; i++)
+    {
+        res += val(test);
+    }
+    zeitMesser.messungEnde();
+    std::cout << "compile() Time: " << zeitMesser.getSekunden() << "s"
+              << " result: " << res << std::endl;
+    res = 0;
+    auto stdf = test->compileStdF();
+    srand(0);
+    zeitMesser.messungStart();
+    for (int i = 0; i < 100000000; i++)
+    {
+        res += stdf();
+    }
+    zeitMesser.messungEnde();
+    std::cout << "compileStdF() Time: " << zeitMesser.getSekunden() << "s"
+              << " result: " << res << std::endl;
+    res = 0;
+    auto assembly = test->compileToAssembly();
+    srand(0);
+    zeitMesser.messungStart();
+    for (int i = 0; i < 100000000; i++)
+    {
+        res += assembly();
+    }
+    zeitMesser.messungEnde();
+    std::cout << "compileToAssembly() Time: " << zeitMesser.getSekunden() << "s"
+              << " result: " << res << std::endl;
+    res = 0;
+    int i2 = 2;
+    int i3 = 3;
+    int i4 = 4;
+    int i5 = 5;
+    AssemblyBlock fastest;
+    fastest.addMoveValue(RCX, 2);
+    fastest.addMoveValue(RDX, 3);
+    fastest.addMoveValue(R8, 4);
+    fastest.addMoveValue(R9, 5);
+    fastest.addCall(rand);
+    fastest.addInstruction(new Instruction(ADD,
+        {new GPRegisterArgument(RAX, LOWER32),
+            new GPRegisterArgument(RCX, LOWER32)}));
+    fastest.addInstruction(new Instruction(ADD,
+        {new GPRegisterArgument(RAX, LOWER32),
+            new GPRegisterArgument(RDX, LOWER32)}));
+    fastest.addInstruction(new Instruction(ADD,
+        {new GPRegisterArgument(RAX, LOWER32),
+            new GPRegisterArgument(R8, LOWER32)}));
+    fastest.addInstruction(new Instruction(ADD,
+        {new GPRegisterArgument(RAX, LOWER32),
+            new GPRegisterArgument(R9, LOWER32)}));
+    auto f = fastest.compileToFunction<compF>();
+    zeitMesser.messungStart();
+    srand(0);
+    for (int i = 0; i < 100000000; i++)
+    {
+        res += assembly();
+    }
+    zeitMesser.messungEnde();
+    srand(0);
+    std::cout << "fastest Time: " << zeitMesser.getSekunden() << "s"
+              << " result: " << res << std::endl;
+    res = 0;
+    zeitMesser.messungStart();
+    for (int i = 0; i < 100000000; i++)
+    {
+        res += getVal(rand);
+    }
+    zeitMesser.messungEnde();
+    std::cout << "fastest Time: " << zeitMesser.getSekunden() << "s"
+              << " result: " << res << std::endl;
+}

+ 18 - 0
assembly/test.asm

@@ -0,0 +1,18 @@
+bits 64
+default rel
+
+segment .text
+global getVal
+
+getVal:
+	call        rcx
+	mov         rcx,2h  
+	add         eax,ecx
+	mov         rcx,3h  
+	add         eax,ecx
+	mov         rdx,4h  
+	mov         edx,edx
+	mov         rcx,5h  
+	add         edx,ecx
+	add         eax,edx  
+	ret