commit 629ad21824b143f63c20067fa7e4796f87312513
parent e0dd2a786b68cd6ab0a0f33c4e0124775567580f
Author: amrfti <andrew@kloet.net>
Date: Tue, 8 Jul 2025 11:08:38 -0400
fix segfault for real
Diffstat:
9 files changed, 174 insertions(+), 137 deletions(-)
diff --git a/src/Aquarium.cpp b/src/Aquarium.cpp
@@ -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;
+
+ newEntities.clear();
+ entitiesToRemove.clear();
- // Update and check for removal/replacement
- for (auto it = entities.begin(); it != entities.end();) {
- auto &entity = *it;
+ // 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
diff --git a/src/Castle.cpp b/src/Castle.cpp
@@ -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) {}
diff --git a/src/SeaMonster.cpp b/src/SeaMonster.cpp
@@ -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;
diff --git a/src/Ship.cpp b/src/Ship.cpp
@@ -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;
diff --git a/src/Whale.cpp b/src/Whale.cpp
@@ -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;
diff --git a/src/assets/CastleAssets.h b/src/assets/CastleAssets.h
@@ -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;
+}
diff --git a/src/assets/SeaMonsterAssets.h b/src/assets/SeaMonsterAssets.h
@@ -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;
+}
diff --git a/src/assets/ShipAssets.h b/src/assets/ShipAssets.h
@@ -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;
+}
diff --git a/src/assets/WhaleAssets.h b/src/assets/WhaleAssets.h
@@ -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"(,????/ (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"( )",
+ R"( )",
+ R"( ; ; )",
+ R"( .-----. )",
+ R"( .' `. )",
+ R"(,????/ (o) \)",
+ R"(\`._/ ,__)"
+ }
},
{
- 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"( 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;
+}