return manager_->component_mask(id_);
}
-EntityManager::EntityManager(EventManager &event_manager) : event_manager_(event_manager) {
+EntityManager::EntityManager(EventManager &event_manager)
+ : event_manager_(event_manager) {
}
EntityManager::~EntityManager() {
for (BaseComponentHelper *helper : component_helpers_) {
if (helper) delete helper;
}
+
component_pools_.clear();
component_helpers_.clear();
entity_component_mask_.clear();
#include <new>
#include <cstdlib>
#include <algorithm>
+#include <mutex>
#include <bitset>
#include <cassert>
#include <iostream>
template <typename T> struct identity { typedef T type; };
void each(typename identity<std::function<void(Entity entity, Components&...)>>::type f) {
+ static std::mutex locked;
+ locked.lock();
for (auto it : *this)
f(it, *(it.template component<Components>().get())...);
+ locked.unlock();
}
private:
}
};
-class LockableEntityManager : public entityx::EntityManager {
-private:
- std::atomic_bool locked;
-
-public:
- LockableEntityManager(entityx::EventManager& ev)
- : EntityManager(ev) {
- locked.store(false);
- }
-
- void lock(void) {
- while (locked.load())
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
-
- locked.store(true);
- }
-
- void unlock(void) {
- locked.store(false);
- }
-
- bool try_lock(void) {
- if (locked.load())
- return false;
-
- locked.store(true);
- return true;
- }
-};
-
namespace game {
/**
* Handles all game events.
/**
* Handles entity data.
*/
- extern LockableEntityManager entities;
+ extern entityx::EntityManager entities;
/**
* An instance of the main game engine.
void MovementSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
{
+ std::string arena;
+
(void)ev;
- en.each<Position, Direction>([dt](entityx::Entity entity, Position &position, Direction &direction) {
+ en.each<Position, Direction>([&arena, dt](entityx::Entity entity, Position &position, Direction &direction) {
position.x += direction.x * dt;
position.y += direction.y * dt;
// TODO initialX and range?
if (entity.has_component<Aggro>()) {
auto ppos = game::engine.getSystem<PlayerSystem>()->getPosition();
- if (ppos.x > position.x && ppos.x < position.x + entity.component<Solid>()->width) {
- ui::toggleWhiteFast();
- ui::waitForCover(); // TODO thread safe call to load world?
- //game::engine.getSystem<WorldSystem>()->load(entity.component<Aggro>()->arena);
- ui::toggleWhiteFast();
- entity.destroy();
- } else {
+ if (ppos.x > position.x && ppos.x < position.x + entity.component<Solid>()->width)
+ arena = entity.component<Aggro>()->arena;
+ else
direction.x = (ppos.x > position.x) ? .05 : -.05;
- }
} else if (entity.has_component<Wander>()) {
auto& countdown = entity.component<Wander>()->countdown;
}
}
});
+
+ if (!arena.empty()) {
+ ui::toggleWhiteFast();
+ ui::waitForCover();
+ game::engine.getSystem<WorldSystem>()->load(arena);
+ ui::toggleWhiteFast();
+ }
}
void PhysicsSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
if (!loadTexResult.isEmpty())
return;
- game::entities.lock();
game::entities.each<Visible, Sprite, Position>([](entityx::Entity entity, Visible &visible, Sprite &sprite, Position &pos) {
// Verticies and shit
float its = 0;
ui::setFontZ(-5.0);
ui::putStringCentered(pos.x + dim.width / 2, pos.y - ui::fontSize - HLINES(0.5), name.name);
});
- game::entities.unlock();
}
void DialogSystem::configure(entityx::EventManager &ev)
void DialogSystem::receive(const MouseClickEvent &mce)
{
- game::entities.lock();
game::entities.each<Position, Solid, Dialog, Name>(
[&](entityx::Entity e, Position &pos, Solid &dim, Dialog &d, Name &name) {
static std::atomic_bool dialogRun;
}
}
});
- game::entities.unlock();
}
void DialogSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
namespace game {
entityx::EventManager events;
- LockableEntityManager entities (events);
+ entityx::EntityManager entities (events);
//SpriteLoader sprite_l;
Engine engine;
// signature?
save << "831998 ";
- game::entities.lock();
game::entities.each<Position>([&](entityx::Entity entity, Position& pos) {
// save position
save << "p " << pos.x << ' ' << pos.y << ' ';
if (entity.has_component<Dialog>())
save << "d " << entity.component<Dialog>()->index << ' ';
});
- game::entities.unlock();
save.close();
return true;
UserAssert(wxml != nullptr, "XML Error: Cannot find a <World> or <IndoorWorld> tag in " + xmlPath);
wxml = wxml->FirstChildElement();
world.indoor = true;
+ if (world.outdoor.empty()) {
+ world.outdoor = currentXMLFile;
+ world.outdoorCoords = vec2(0, 100);
+ }
}
world.toLeft = world.toRight = "";
currentXMLFile = file;
- game::entities.lock();
game::entities.reset();
game::engine.getSystem<PlayerSystem>()->create();
}
game::events.emit<BGMToggleEvent>();
- game::entities.unlock();
}
/*
void WorldSystem::detect(entityx::TimeDelta dt)
{
- game::entities.lock();
game::entities.each<Grounded, Position, Solid>(
[&](entityx::Entity e, Grounded &g, Position &loc, Solid &dim) {
(void)e;
loc.x = -(static_cast<int>(world.startX)) - dim.width - game::HLINE;
}
});
- game::entities.unlock();
}
void WorldSystem::goWorldRight(Position& p, Solid &d)
p.x = world.outdoorCoords.x; // ineffective, player is regen'd
p.y = world.outdoorCoords.y;
} else {
- game::entities.lock();
game::entities.each<Position, Solid, Portal>(
[&](entityx::Entity entity, Position& loc, Solid &dim, Portal &portal) {
(void)entity;
return;
}
});
- game::entities.unlock();
}
if (!file.empty()) {