fix segfault for real

This commit is contained in:
2025-07-08 11:08:38 -04:00
parent 9c631d3d9a
commit cda06a5169
9 changed files with 176 additions and 139 deletions

View File

@@ -47,15 +47,18 @@ void Aquarium::ensureEntitiesSorted() {
void Aquarium::redraw() {
clearCurrentFrame();
ensureBigEntityExists();
std::vector<std::unique_ptr<Entity>> newEntities;
bool entities_modified = false;
// Use static vectors to avoid per-frame allocations
static std::vector<std::unique_ptr<Entity>> newEntities;
static std::vector<size_t> entitiesToRemove;
// Update and check for removal/replacement
for (auto it = entities.begin(); it != entities.end();) {
auto &entity = *it;
newEntities.clear();
entitiesToRemove.clear();
// Update all entities and collect changes
for (size_t i = 0; i < entities.size(); ++i) {
auto &entity = entities[i];
entity->update();
// Handle fish bubble spawning
@@ -69,30 +72,32 @@ void Aquarium::redraw() {
if (entity->shouldBeRemoved()) {
auto replacement = entity->createReplacement();
if (replacement) {
*it = std::move(replacement);
entities_modified = true;
++it;
entity = std::move(replacement); // Replace in-place
entities_need_sorting = true;
} else {
it = entities.erase(it);
entities_modified = true;
entitiesToRemove.push_back(i); // Mark for removal
}
} else {
++it;
}
}
// Add new entities if any
// Remove entities in reverse order to maintain indices
for (auto it = entitiesToRemove.rbegin(); it != entitiesToRemove.rend();
++it) {
entities.erase(entities.begin() + *it);
entities_need_sorting = true;
}
// Add new entities (only if we have them)
if (!newEntities.empty()) {
// Reserve space to minimize reallocations
entities.reserve(entities.size() + newEntities.size());
for (auto &newEntity : newEntities) {
entities.emplace_back(std::move(newEntity));
}
entities_modified = true;
}
// Only sort if entities were modified
if (entities_modified) {
entities_need_sorting = true;
}
ensureEntitiesSorted();
// Draw all entities

View File

@@ -5,4 +5,4 @@
Castle::Castle()
: Entity(Aquarium::getInstance().getWidth() - 32,
Aquarium::getInstance().getHeight() - 13),
image(castleAsset.image), mask(castleAsset.mask) {}
image(getCastleAsset().image), mask(getCastleAsset().mask) {}

View File

@@ -6,8 +6,9 @@
SeaMonster::SeaMonster() : SeaMonster(getRandomDirection()) {}
SeaMonster::SeaMonster(int asset_index)
: Entity(asset_index == 0), frames(seaMonsterAssets[asset_index].frames),
mask(seaMonsterAssets[asset_index].mask), speed(SEAMONSTER_SPEED) {
: Entity(asset_index == 0),
frames(getSeaMonsterAssets()[asset_index].frames),
mask(getSeaMonsterAssets()[asset_index].mask), speed(SEAMONSTER_SPEED) {
const auto &aquarium = Aquarium::getInstance();
y = WATER_SURFACE_OFFSET;

View File

@@ -6,8 +6,8 @@
Ship::Ship() : Ship(getRandomDirection()) {}
Ship::Ship(int asset_index)
: Entity(asset_index == 0), image(shipAssets[asset_index].image),
mask(shipAssets[asset_index].mask), speed(SHIP_SPEED) {
: Entity(asset_index == 0), image(getShipAssets()[asset_index].image),
mask(getShipAssets()[asset_index].mask), speed(SHIP_SPEED) {
const auto &aquarium = Aquarium::getInstance();
y = 0;

View File

@@ -6,8 +6,8 @@
Whale::Whale() : Whale(getRandomDirection()) {}
Whale::Whale(int asset_index)
: Entity((asset_index == 0)), frames(whaleAssets[asset_index].frames),
mask(whaleAssets[asset_index].mask), speed(WHALE_SPEED) {
: Entity((asset_index == 0)), frames(getWhaleAssets()[asset_index].frames),
mask(getWhaleAssets()[asset_index].mask), speed(WHALE_SPEED) {
const auto &aquarium = Aquarium::getInstance();
y = 0;

View File

@@ -8,7 +8,8 @@ struct CastleAsset {
std::vector<std::string> mask;
};
inline CastleAsset castleAsset = {
inline const CastleAsset& getCastleAsset() {
static const CastleAsset castleAsset = {
{
R"( T~~)",
R"( |)",
@@ -37,4 +38,6 @@ inline CastleAsset castleAsset = {
R"( yy yy)",
R"( y y y y)",
R"( yyyyyyy)"}
};
};
return castleAsset;
}

View File

@@ -8,23 +8,31 @@ struct SeaMonsterAsset {
std::vector<std::string> mask;
};
const SeaMonsterAsset seaMonster = {
{// Frame 1
inline const SeaMonsterAsset& getSeaMonster() {
static const SeaMonsterAsset seaMonster = {
{
R"(?????????_???_?????????????????????_???_???????_a_a???)",
R"(???????_{.`=`.}_??????_???_??????_{.`=`.}_????{/ ''\_?)",
R"(?_????{.' _ '.}????{.`'`.}????{.' _ '.}??{| ._oo))",
R"({ \??{/ .'?'. \}??{/ .-. \}??{/ .'?'. \}?{/ |????)"},
{
R"(??????????????????????_???_????????????????????_a_a???)",
R"(??_??????_???_??????_{.`=`.}_??????_???_??????{/ ''\_?)",
R"(?{ \????{.`'`.}????{.' _ '.}????{.`'`.}????{| ._oo))",
R"(??\ \??{/ .-. \}??{/ .'?'. \}??{/ .-. \}???{/ |????)"}},
{
R"( W W )",
R"()",
R"()",
R"()"}};
{
R"(?????????_???_?????????????????????_???_???????_a_a???)",
R"(???????_{.`=`.}_??????_???_??????_{.`=`.}_????{/ ''\_?)",
R"(?_????{.' _ '.}????{.`'`.}????{.' _ '.}??{| ._oo))",
R"({ \??{/ .'?'. \}??{/ .-. \}??{/ .'?'. \}?{/ |????)"},
{
R"(??????????????????????_???_????????????????????_a_a???)",
R"(??_??????_???_??????_{.`=`.}_??????_???_??????{/ ''\_?)",
R"(?{ \????{.`'`.}????{.' _ '.}????{.`'`.}????{| ._oo))",
R"(??\ \??{/ .-. \}??{/ .'?'. \}??{/ .-. \}???{/ |????)"}},
{
R"( W W )",
R"()",
R"()",
R"()"
}
};
return seaMonster;
}
inline const std::vector<SeaMonsterAsset> seaMonsterAssets =
createBidirectionalFramedAssets(seaMonster);
inline const std::vector<SeaMonsterAsset>& getSeaMonsterAssets() {
static const std::vector<SeaMonsterAsset> seaMonsterAssets =
createBidirectionalFramedAssets(getSeaMonster());
return seaMonsterAssets;
}

View File

@@ -3,13 +3,27 @@
#include "../SpriteUtils.h"
#include <vector>
const AssetPair ship = {
{R"( | | | )", R"( )_) )_) )_) )",
R"( )___))___))___)\ )", R"( )____)____)_____)\\ )",
R"(_____|____|____|____\\\__)", R"(\ /????)"},
{R"( y y y )", R"()", R"( w )",
R"( ww )", R"(yyyyyyyyyyyyyyyyyyyywwwyy)",
R"(y y )"}};
inline const AssetPair &getShip() {
static const AssetPair ship = {
{
R"( | | | )",
R"( )_) )_) )_) )",
R"( )___))___))___)\ )",
R"( )____)____)_____)\\ )",
R"(_____|____|____|____\\\__)",
R"(\ /????)"},
{
R"( y y y )",
R"()",
R"( w )",
R"( ww )",
R"(yyyyyyyyyyyyyyyyyyyywwwyy)",
R"(y y )"}};
return ship;
}
inline const std::vector<AssetPair> shipAssets =
createBidirectionalAssets({ship});
inline const std::vector<AssetPair> &getShipAssets() {
static const std::vector<AssetPair> shipAssets =
createBidirectionalAssets({getShip()});
return shipAssets;
}

View File

@@ -8,91 +8,97 @@ struct WhaleAsset {
std::vector<std::string> mask;
};
const WhaleAsset whale = {
{
inline const WhaleAsset& getWhale() {
static const WhaleAsset whale = {
{
R"( )",
{
R"( )",
R"()",
R"()",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( )",
R"()",
R"( : )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( )",
R"( : )",
R"( : )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( . . )",
R"( -:- )",
R"( : )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( . . )",
R"( .-.-. )",
R"( : )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( . . )",
R"( '.-:-.' )",
R"( ' : ' )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( )",
R"( .- -. )",
R"( ; : ; )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( )",
R"( )",
R"( ; ; )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
}
},
{
R"( C C )",
R"( CCCCCCC )",
R"( C C C )",
R"()",
R"()",
R"()",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( )",
R"()",
R"( : )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( )",
R"( : )",
R"( : )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( . . )",
R"( -:- )",
R"( : )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( . . )",
R"( .-.-. )",
R"( : )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( . . )",
R"( '.-:-.' )",
R"( ' : ' )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( )",
R"( .- -. )",
R"( ; : ; )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
},
{
R"( )",
R"( )",
R"( ; ; )",
R"( .-----. )",
R"( .' `. )",
R"(,????/ (o) \)",
R"(\`._/ ,__)"
R"( W )",
R"()"
}
},
{
R"( C C )",
R"( CCCCCCC )",
R"( C C C )",
R"()",
R"()",
R"( W )",
R"()"
}
};
};
return whale;
}
inline const std::vector<WhaleAsset> whaleAssets =
createBidirectionalFramedAssets(whale);
inline const std::vector<WhaleAsset>& getWhaleAssets() {
static const std::vector<WhaleAsset> whaleAssets =
createBidirectionalFramedAssets(getWhale());
return whaleAssets;
}