Răsfoiți Sursa

fix a fiew memory access bugs

Kolja Strohm 3 ani în urmă
părinte
comite
a0cdcc16ed

+ 31 - 0
FactoryCraft/Dimension.cpp

@@ -52,6 +52,21 @@ Block* Dimension::zBlock( Vec3<int> location )
     return 0;
 }
 
+Block* Dimension::getBlock( Vec3<int> location )
+{
+    cs.lock();
+    Chunk* c = zChunk( currentGame->getChunkCenter( location.x, location.y ) );
+    if( c )
+    {
+        Block* b = c->zBlockAt( location );
+        b = b ? dynamic_cast<Block*>(b->getThis()) : 0;
+        cs.unlock();
+        return b;
+    }
+    cs.unlock();
+    return 0;
+}
+
 void Dimension::addEntity( Entity* entity )
 {
     entities->add( entity );
@@ -152,6 +167,22 @@ Entity* Dimension::zEntity( int id )
     return 0;
 }
 
+Entity* Dimension::getEntity( int id )
+{
+    cs.lock();
+    for( Entity* e : *entities )
+    {
+        if( e->getId() == id )
+        {
+            Entity* result = dynamic_cast<Entity*>(e->getThis());
+            cs.unlock();
+            return result;
+        }
+    }
+    cs.unlock();
+    return 0;
+}
+
 void Dimension::removeEntity( int id )
 {
     cs.lock();

+ 2 - 0
FactoryCraft/Dimension.h

@@ -25,6 +25,7 @@ public:
     ~Dimension();
 
     Block* zBlock( Framework::Vec3<int> location );
+    Block* getBlock( Framework::Vec3<int> location );
     void addEntity( Entity* entity );
     void setChunk( Chunk* chunk, Framework::Punkt center, World* zWorld );
     int getDimensionId() const;
@@ -34,5 +35,6 @@ public:
     void setBlock( Block* block );
     void removeBlock( Block* zBlock );
     Entity* zEntity( int id );
+    Entity* getEntity( int id );
     void removeEntity( int id );
 };

+ 18 - 0
FactoryCraft/Entity.cpp

@@ -67,6 +67,14 @@ Framework::Either<Block*, Entity*> ActionTarget::zTarget( int dimension ) const
         return currentGame->zBlockAt( blockPos, dimension );
 }
 
+Framework::Either<Block*, Entity*> ActionTarget::getTarget( int dimension ) const
+{
+    if( entityId >= 0 )
+        return currentGame->getEntity( entityId );
+    else
+        return currentGame->getBlockAt( blockPos, dimension );
+}
+
 
 Entity::Entity( const EntityType* zType, bool hasInventory )
     : Model3D(), Inventory( { 0.f, 0.f, 0.f }, hasInventory ), zEntityType( zType ), target( 0 )
@@ -98,4 +106,14 @@ const EntityType* Entity::zType() const
 int Entity::getCurrentDimension() const
 {
     return currentDimensionId;
+}
+
+void Entity::lock()
+{
+    cs.lock();
+}
+
+void Entity::unlock()
+{
+    cs.unlock();
 }

+ 5 - 0
FactoryCraft/Entity.h

@@ -2,6 +2,7 @@
 
 #include <Model3D.h>
 #include <Either.h>
+#include <Critical.h>
 #include "EntityType.h"
 #include "Inventory.h"
 
@@ -26,6 +27,7 @@ public:
     Framework::Vec3<int> getBlockPos() const;
     Direction getBlockSide() const;
     Framework::Either<Block*, Entity*> zTarget( int dimensionId ) const;
+    Framework::Either<Block*, Entity*> getTarget( int dimensionId ) const;
 };
 
 class Entity : public Framework::Model3D, public Inventory
@@ -47,6 +49,7 @@ protected:
     float gravityMultiplier;
     int id;
     ActionTarget* target;
+    Framework::Critical cs;
 
 public:
     Entity( const EntityType* zType, bool hasInventory );
@@ -57,6 +60,8 @@ public:
     int getId() const;
     const EntityType* zType() const;
     int getCurrentDimension() const;
+    void lock();
+    void unlock();
 
     friend EntityType;
 };

+ 4 - 0
FactoryCraft/EntityChangedUpdate.cpp

@@ -22,6 +22,10 @@ void EntityChangedUpdateType::applyUpdate( Framework::StreamReader* zReader )
             currentGame->zDimensionOrCreate( e->getCurrentDimension() )->addEntity( e );
         }
         else
+        {
+            e->lock();
             STATIC_REGISTRY( EntityType ).zElement( type )->updateEntity( e, zReader );
+            e->unlock();
+        }
     }
 }

+ 8 - 0
FactoryCraft/Game.cpp

@@ -77,6 +77,14 @@ void Game::updateInventory( Framework::Array<ItemSlot*>& itemBar, int pos )
         if( slot && slot->zStack() && slot->zStack()->zItem() )
         {
             tr.renderText( 5 + index * 50, 5, slot->zStack()->zItem()->getName(), *invB, 0xFFFFFFFF );
+            int size = slot->zStack()->getSize();
+            const char *units[] = { "", "K", "M", "G", "T", "P"};
+            int index = 0;
+            for(; index < 6 && size > 1024; index++ )
+                size = size / 1024;
+            Text count = size;
+            count += units[ index ];
+            tr.renderText( 45 - tr.getTextBreite( count ), 45 - tr.getTextHeight( count ), count, *invB, 0xFFFFFFFF );
         }
         index++;
     }

+ 2 - 0
FactoryCraft/Inventoty.cpp

@@ -45,6 +45,8 @@ void Inventory::loadInventory( Framework::StreamReader* zReader )
                 Item* item = STATIC_REGISTRY( ItemType ).zElement( id )->loadItem( zReader );
                 slot->setItems( new ItemStack( item, size ) );
             }
+            else
+                slot->setItems( 0 );
         }
     }
 }

+ 2 - 0
FactoryCraft/ItemEntity.cpp

@@ -14,11 +14,13 @@ ItemEntity::ItemEntity()
 
 bool ItemEntity::tick( double time )
 {
+    lock();
     if( !model && slot->zStack() )
     {
         setModelDaten( slot->zStack()->zItem()->zItemType()->getItemModel() );
         textur = slot->zStack()->zItem()->zItemType()->getItemTextur();
     }
+    unlock();
     return Entity::tick( time );
 }
 

+ 2 - 0
FactoryCraft/ItemSlot.cpp

@@ -20,6 +20,8 @@ ItemSlot::~ItemSlot()
 
 void ItemSlot::setItems( ItemStack* items )
 {
+    if( this->items )
+        this->items->release();
     this->items = items;
 }
 

+ 7 - 1
FactoryCraft/Player.cpp

@@ -39,12 +39,13 @@ Player::~Player()
 
 bool Player::tick( double time )
 {
+    cs.lock();
     if( currentGame->getCurrentPlayerId() == id )
     {
         currentGame->zKamera()->setPosition( pos + Vec3<float>( 0.f, 0.f, 1.5f ) );
         if( target )
         {
-            auto t = target->zTarget( currentDimensionId );
+            auto t = target->getTarget( currentDimensionId );
             if( t.isA() && t.getA() )
                 currentGame->setTarget( t.getA() );
             if( t.isB() && t.getB() )
@@ -53,6 +54,10 @@ bool Player::tick( double time )
                 ((Game*)(Menu*)menuRegister->get( "game" ))->updatePosition( pos, 1, t.isA() ? t.getA()->getPos() : t.getB()->getPos() );
             else
                 ((Game*)(Menu*)menuRegister->get( "game" ))->updatePosition( pos, 0, { 0, 0, 0 } );
+            if( t.isA() && t.getA() )
+                t.getA()->release();
+            if( t.isB() && t.getB() )
+                t.getB()->release();
         }
         else
         {
@@ -61,6 +66,7 @@ bool Player::tick( double time )
         }
         ((Game*)(Menu*)menuRegister->get( "game" ))->updateInventory( itemBar, 0 ); // todo: pass selected slot
     }
+    cs.unlock();
     return Entity::tick( time );
 }
 

+ 31 - 3
FactoryCraft/World.cpp

@@ -39,6 +39,8 @@ World::~World()
     zScreenPtr->removeKamera( kam );
     dimensions->release();
     currentPlayer->release();
+    if( currentTarget )
+        currentTarget->release();
 }
 
 void World::update( bool background )
@@ -124,6 +126,14 @@ Block* World::zBlockAt( Framework::Vec3<int> location, int dimension ) const
     return 0;
 }
 
+Block* World::getBlockAt( Framework::Vec3<int> location, int dimension ) const
+{
+    Dimension* dim = zDimension( dimension );
+    if( dim )
+        return dim->getBlock( location );
+    return 0;
+}
+
 Dimension* World::zDimension( int id ) const
 {
     for( auto dim : *dimensions )
@@ -188,6 +198,17 @@ Entity* World::zEntity( int id ) const
     return 0;
 }
 
+Entity* World::getEntity( int id ) const
+{
+    for( Dimension* d : *dimensions )
+    {
+        Entity* e = d->getEntity( id );
+        if( e )
+            return e;
+    }
+    return 0;
+}
+
 void World::removeEntity( int id )
 {
     for( Dimension* d : *dimensions )
@@ -220,9 +241,16 @@ void World::setTarget( Framework::Model3D* zTarget )
     if( zTarget != currentTarget )
     {
         if( currentTarget )
+        {
             currentTarget->setAmbientFactor( currentTarget->getAmbientFactor() - 0.2f );
-        currentTarget = zTarget;
-        if( currentTarget )
-            currentTarget->setAmbientFactor( currentTarget->getAmbientFactor() + 0.2f );
+            currentTarget->release();
+            currentTarget = 0;
+        }
+        if( zTarget )
+        {
+            currentTarget = dynamic_cast<Framework::Model3D*>(zTarget->getThis());
+            if( currentTarget )
+                currentTarget->setAmbientFactor( currentTarget->getAmbientFactor() + 0.2f );
+        }
     }
 }

+ 2 - 0
FactoryCraft/World.h

@@ -32,6 +32,7 @@ public:
     void thread() override;
 
     Block* zBlockAt( Framework::Vec3<int> location, int dimension ) const;
+    Block* getBlockAt( Framework::Vec3<int> location, int dimension ) const;
     Dimension* zDimension( int id ) const;
     Dimension* zDimensionOrCreate( int id );
     void setVisibility( Chunk* zChunk, bool visible );
@@ -39,6 +40,7 @@ public:
     Framework::Bildschirm3D* zScreen() const;
     Framework::Punkt getChunkCenter( int x, int y ) const;
     Entity* zEntity( int id ) const;
+    Entity* getEntity( int id ) const;
     void removeEntity( int id );
     PlayerKam* zKamera() const;
     int getCurrentPlayerId() const;