Skip to content

Commit

Permalink
Improve performance of world->find
Browse files Browse the repository at this point in the history
  • Loading branch information
feresr committed May 25, 2020
1 parent 528b466 commit dcf035e
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 64 deletions.
7 changes: 6 additions & 1 deletion include/ecs/ecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ class World {
}

template<typename... Components>
[[deprecated("Replaced by find(std::function<>), which has better performance")]]
std::vector<Entity*> find() {
// todo: Optimize, avoid creating a new vector an returning it by copy
std::vector<Entity*> result;
std::copy_if(
entities.begin(),
Expand All @@ -126,6 +126,11 @@ class World {
return result;
}

template<typename... Components>
void find(const std::function<void(Entity*)>& callback) {
for (auto entity : entities) if (entity->has<Components...>()) callback(entity);
}

template<typename... Components>
std::vector<Entity*> findAny() {
// todo: Optimize, avoid creating a new vector an returning it by copy
Expand Down
2 changes: 1 addition & 1 deletion src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void Game::init(const char* title, int width, int height, bool fullscreen) {
void Game::update() {
currentScene->update();
if (dynamic_cast<IntroScene*>(currentScene)) {
SDL_Delay(500);
SDL_Delay(2500);
delete currentScene;
currentScene = new GameScene(window);
}
Expand Down
2 changes: 1 addition & 1 deletion src/TextureManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ TextureManager::TextureManager(SDL_Renderer* renderer) : renderer{renderer} {

textures.insert_or_assign(ONE_UP_LABEL, new SDL_Rect{184, 271, 16, 7});
textures.insert_or_assign(ONEHUNDRED, new SDL_Rect{153, 287, 11, 8});
textures.insert_or_assign(TWOHUNDRED, new SDL_Rect{153, 279, 11, 8});
textures.insert_or_assign(TWOHUNDRED, new SDL_Rect{153, 279, 12, 8});
textures.insert_or_assign(THOUSAND, new SDL_Rect{153, 287, 15, 8});
textures.insert_or_assign(MARIO_FLAG_1, new SDL_Rect{170, 170, TILE_SIZE, TILE_SIZE});
textures.insert_or_assign(MARIO_FLAG_2, new SDL_Rect{187, 170, TILE_SIZE, TILE_SIZE});
Expand Down
5 changes: 2 additions & 3 deletions src/systems/AnimationSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ void AnimationSystem::onAddedToWorld(World* world) {
}

void AnimationSystem::tick(World* world) {
auto entities = world->find<AnimationComponent, TextureComponent>();
for (auto entity : entities) {
world->find<AnimationComponent, TextureComponent>([&](Entity* entity) {
auto animation = entity->get<AnimationComponent>();
auto texture = entity->get<TextureComponent>();
animation->counter++;
Expand All @@ -20,7 +19,7 @@ void AnimationSystem::tick(World* world) {
entity->remove<AnimationComponent>();
}
}
}
});
}

void AnimationSystem::handleEvent(SDL_Event& event) {
Expand Down
64 changes: 33 additions & 31 deletions src/systems/EnemySystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,37 +52,38 @@ void flipEnemy(Entity* enemy) {

void turtleShellInteractions(World* world, Entity* shell) {
if (shell->hasAny<LeftCollisionComponent, RightCollisionComponent>()) {
for (auto other : world->find<EnemyComponent, KineticComponent>()) {
if (shell == other) continue;
world->find<EnemyComponent, KineticComponent>([&](Entity* other) {
if (shell == other) return;
auto transform = other->get<TransformComponent>();
if (AABBCollision(shell->get<TransformComponent>(), other->get<TransformComponent>())) {
world->create()->assign<FloatingPointsComponent>(Points::ONEHOUNDRED, transform->getCenterX(), transform->y);
world->create()->assign<FloatingPointsComponent>(Points::ONEHOUNDRED, transform->getCenterX(),
transform->y);
world->create()->assign<AddScoreComponent>(100);
flipEnemy(other);
shell->remove<LeftCollisionComponent>();
shell->remove<RightCollisionComponent>();
}
}
});
}

if (shell->has<LeftCollisionComponent>()) {
shell->get<KineticComponent>()->accX = 3.0f;
shell->get<KineticComponent>()->speedX = 3.0f;
}
if (shell->has<RightCollisionComponent>()) {
shell->get<KineticComponent>()->accX = -3.0f;
shell->get<KineticComponent>()->speedX = -3.0f;
}
if (shell->has<LeftCollisionComponent>()) {
shell->get<KineticComponent>()->accX = 3.0f;
shell->get<KineticComponent>()->speedX = 3.0f;
}
if (shell->has<RightCollisionComponent>()) {
shell->get<KineticComponent>()->accX = -3.0f;
shell->get<KineticComponent>()->speedX = -3.0f;
}
}

void EnemySystem::tick(World* world) {
for (auto shell : world->find<EnemyComponent, KineticComponent>()) {
world->find<EnemyComponent, KineticComponent>([&](Entity* shell) {
if (shell->has<EnemyComponent>() && shell->get<EnemyComponent>()->type == Enemy::Type::TURTLE_SHELL) {
turtleShellInteractions(world, shell);
}
}
});

for (auto enemy : world->find<EnemyComponent, TransformComponent, CrushedComponent>()) {
world->find<EnemyComponent, TransformComponent, CrushedComponent>([&](Entity* enemy) {
auto enemyTransform = enemy->get<TransformComponent>();
world->create()->assign<SoundComponent>(Sound::Id::STOMP);
switch (enemy->get<EnemyComponent>()->type) {
Expand All @@ -92,13 +93,15 @@ void EnemySystem::tick(World* world) {
enemy->assign<DestroyDelayedComponent>(50);
enemy->assign<TextureComponent>(TextureId::GOOMBA_CRUSHED);
enemy->assign<TransformComponent>(*enemyTransform);
world->create()->assign<FloatingPointsComponent>(Points::ONEHOUNDRED, enemyTransform->getCenterX(), enemyTransform->y);
world->create()->assign<FloatingPointsComponent>(Points::ONEHOUNDRED, enemyTransform->getCenterX(),
enemyTransform->y);
world->create()->assign<AddScoreComponent>(100);
}
break;
case Enemy::Type::TURTLE:
stepOnTurtle(enemy);
world->create()->assign<FloatingPointsComponent>(Points::TWOHOUNDRED, enemyTransform->getCenterX(), enemyTransform->y);
world->create()->assign<FloatingPointsComponent>(Points::TWOHOUNDRED, enemyTransform->getCenterX(),
enemyTransform->y);
world->create()->assign<AddScoreComponent>(200);
break;
case Enemy::Type::TURTLE_SHELL: {
Expand All @@ -113,20 +116,19 @@ void EnemySystem::tick(World* world) {
}
}
}
}
});

//WALKABLE (bounce walls)
auto entities = world->find<WalkComponent, LeftCollisionComponent>();
for (auto entity : entities) {
world->find<WalkComponent, LeftCollisionComponent>([&](Entity* entity) {
auto walkComponent = entity->get<WalkComponent>();
walkComponent->speed = std::abs(walkComponent->speed);
if (entity->has<TextureComponent>() && entity->has<EnemyComponent>()) {
entity->get<TextureComponent>()->flipH = true;
}
}
});

// Flip Enemy by hitting block beneath
for (auto entity : world->find<BottomCollisionComponent, TransformComponent, KineticComponent, EnemyComponent>()) {
world->find<BottomCollisionComponent, TransformComponent, KineticComponent, EnemyComponent>([&](Entity* entity) {
auto transform = entity->get<TransformComponent>();
auto tileMap = world->findFirst<TileMapComponent>()->get<TileMapComponent>();
auto bottomTile = tileMap->get(
Expand All @@ -135,32 +137,32 @@ void EnemySystem::tick(World* world) {
);
if (bottomTile && bottomTile->has<BreakableComponent>()) {
if (bottomTile->get<BreakableComponent>()->hit) {
world->create()->assign<FloatingPointsComponent>(Points::ONEHOUNDRED, transform->getCenterX(), transform->y);
world->create()->assign<FloatingPointsComponent>(Points::ONEHOUNDRED, transform->getCenterX(),
transform->y);
world->create()->assign<AddScoreComponent>(100);
flipEnemy(entity);
}
}
}
});

for (auto entity : world->find<WalkComponent, RightCollisionComponent>()) {
world->find<WalkComponent, RightCollisionComponent>([&](Entity* entity) {
auto walkComponent = entity->get<WalkComponent>();
walkComponent->speed = -std::abs(walkComponent->speed);
if (entity->has<TextureComponent>() && entity->has<EnemyComponent>()) {
entity->get<TextureComponent>()->flipH = false;
}
}

for (auto entity : world->find<WalkComponent, KineticComponent>()) {
});
world->find<WalkComponent, KineticComponent>([&](Entity* entity) {
entity->get<KineticComponent>()->speedX = entity->get<WalkComponent>()->speed;
}
});

for (auto entity : world->find<EnemyComponent>()) {
world->find<EnemyComponent>([&](Entity* entity) {
entity->remove<BottomCollisionComponent>();
entity->remove<TopCollisionComponent>();
entity->remove<LeftCollisionComponent>();
entity->remove<RightCollisionComponent>();
entity->remove<CrushedComponent>();
}
});
}

void EnemySystem::onRemovedFromWorld(World* world) {
Expand Down
13 changes: 6 additions & 7 deletions src/systems/MapSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ void MapSystem::tick(World* world) {
if (player)camera->x = std::max(camera->x, (int) player->get<TransformComponent>()->getCenterX());
auto tileMap = world->findFirst<TileMapComponent>()->get<TileMapComponent>();


// 2. Iterate over them and remove the ones that are outside the camera.
for (auto entity : world->find<TransformComponent>()) {
world->find<TransformComponent>([&](Entity* entity) {
auto transform = entity->get<TransformComponent>();
if (transform->right() < camera->left() - CAMERA_WORLD_OFFSET
|| transform->left() > camera->right() + CAMERA_WORLD_OFFSET
Expand All @@ -33,13 +32,13 @@ void MapSystem::tick(World* world) {
nullptr
);
}

if (entity->has<PlayerComponent>()) continue;
if (entity->has<TextComponent>()) continue;
if (entity->has<FlagPoleComponent>()) continue;
if (entity->has<PlayerComponent>()) return;
if (entity->has<TextComponent>()) return;
if (entity->has<FlagPoleComponent>()) return;
world->destroy(entity);
}
}
});


// 3. Iterate over the `map` in the constructor and instantiate entities
// Remove them from the map so they don't get instantiated again.
Expand Down
39 changes: 19 additions & 20 deletions src/systems/PhysicsSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,20 @@ Direction checkCollisionX(Entity* solid, TransformComponent* transform, KineticC
}

void PhysicsSystem::tick(World* world) {
std::vector<Entity*> entities;
entities = world->find<GravityComponent, KineticComponent>();
for (auto entity : entities) entity->get<KineticComponent>()->accY += GRAVITY;
world->find<GravityComponent, KineticComponent>([&](Entity* entity) {
entity->get<KineticComponent>()->accY += GRAVITY;
});

// Kinetic-Kinetic collisions
entities = world->find<TransformComponent, KineticComponent, SolidComponent>();
for (auto entity : entities) {
if (entity->has<BlinkingComponent>()) continue;
world->find<TransformComponent, KineticComponent, SolidComponent>([&](Entity* entity) {
if (entity->has<BlinkingComponent>()) return;
auto transform = entity->get<TransformComponent>();
auto kinetic = entity->get<KineticComponent>();
for (auto other : entities) {
if (entity == other) continue;
if (!other->has<SolidComponent>()) continue;
if (other->has<CollectibleComponent>()) continue;
if (other->has<BlinkingComponent>()) continue;
world->find<TransformComponent, KineticComponent, SolidComponent>([&](Entity* other) {
if (entity == other) return;
if (!other->has<SolidComponent>()) return;
if (other->has<CollectibleComponent>()) return;
if (other->has<BlinkingComponent>()) return;
switch (checkCollisionY(other, transform, kinetic)) {
case Direction::TOP:
entity->assign<TopCollisionComponent>();
Expand All @@ -116,15 +115,16 @@ void PhysicsSystem::tick(World* world) {
default:
break;
}
}
}
});
});



// Check Kinetic-Tiles Collisions
auto tileMapEntity = world->findFirst<TileMapComponent>();
if (tileMapEntity) {
auto tileMapComponent = tileMapEntity->get<TileMapComponent>();
auto kineticEntities = world->find<KineticComponent, TransformComponent, SolidComponent>();
for (auto entity : kineticEntities) {
world->find<KineticComponent, TransformComponent, SolidComponent>([&](Entity* entity) {
auto transform = entity->get<TransformComponent>();
auto kinetic = entity->get<KineticComponent>();

Expand Down Expand Up @@ -188,13 +188,12 @@ void PhysicsSystem::tick(World* world) {
break;
}
}
}
});
}

// Apply Forces
entities = world->find<TransformComponent, KineticComponent>();
for (auto entity : entities) {
if (entity->has<FrozenComponent>()) continue;
world->find<TransformComponent, KineticComponent>([&](Entity* entity) {
if (entity->has<FrozenComponent>()) return;
auto transform = entity->get<TransformComponent>();
auto kinematic = entity->get<KineticComponent>();

Expand All @@ -213,5 +212,5 @@ void PhysicsSystem::tick(World* world) {

if (kinematic->speedY < -MAX_SPEED_Y) kinematic->speedY = -MAX_SPEED_Y;
if (kinematic->speedX < -MAX_SPEED_X) kinematic->speedX = -MAX_SPEED_X;
}
});
}

0 comments on commit dcf035e

Please sign in to comment.