Make MapContext keep a complete copy of the map

This commit is contained in:
Matthias Schiffer 2014-09-24 17:39:36 +02:00
parent aadcecf202
commit efa8640aab
8 changed files with 36 additions and 45 deletions

View file

@ -31,18 +31,15 @@ namespace RPGEdit {
namespace Control { namespace Control {
MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, View::MapView *view0, const std::shared_ptr<const Model::Map> &map0) MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const std::shared_ptr<View::Window> &window, const Model::Map &map0)
: eventBus(eventBus0), inputHandler(inputHandler0), view(view0), map(map0) { : eventBus(eventBus0), inputHandler(inputHandler0), map(map0) {
for (const Model::Entity &entity : map->getEntities()) view = std::unique_ptr<View::MapView>(new View::MapView(window, map.getTileset()));
entities.emplace_back(new Model::Entity(entity));
playerEntity = new Model::Entity("square"); map.getEntities().emplace_back("square");
playerEntity = &map.getEntities().back();
playerEntity->moveTo(Model::Position{8, 8}); playerEntity->moveTo(Model::Position{8, 8});
entities.emplace_back(playerEntity); view->updateEntities(map.getEntities());
view->updateEntities(entities);
inputHandler->registerListener( inputHandler->registerListener(
[this] (uint16_t key, bool pressed, uint64_t time) { [this] (uint16_t key, bool pressed, uint64_t time) {

View file

@ -44,11 +44,9 @@ private:
EventBus *const eventBus; EventBus *const eventBus;
InputHandler *const inputHandler; InputHandler *const inputHandler;
View::MapView *const view; std::unique_ptr<View::MapView> view;
std::shared_ptr<const Model::Map> map; Model::Map map;
std::vector<std::unique_ptr<Model::Entity>> entities;
Model::Entity *playerEntity; Model::Entity *playerEntity;
void movePlayer(Model::Direction dir, uint64_t time); void movePlayer(Model::Direction dir, uint64_t time);
@ -60,10 +58,10 @@ private:
} }
public: public:
MapContext(EventBus *eventBus0, InputHandler *inputHandler0, View::MapView *view0, const std::shared_ptr<const Model::Map> &map0); MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const std::shared_ptr<View::Window> &window, const Model::Map &map0);
void render(uint64_t time) { void render(uint64_t time) {
view->render(entities, getViewPosition(time), time); view->render(&map, getViewPosition(time), time);
} }
}; };

View file

@ -99,12 +99,11 @@ void RPGEdit::eventLoop() {
} }
void RPGEdit::run() { void RPGEdit::run() {
std::shared_ptr<Model::Map> map = Model::Map::load("test"); std::unique_ptr<Model::Map> map = Model::Map::load("test");
window = std::make_shared<View::Window>(); window = std::make_shared<View::Window>();
mapView = std::make_shared<View::MapView>(window, map);
ctx = std::make_shared<MapContext>(&eventBus, &inputHandler, mapView.get(), map); ctx = std::make_shared<MapContext>(&eventBus, &inputHandler, window, *map);
eventThread = std::thread([this] { eventLoop(); }); eventThread = std::thread([this] { eventLoop(); });

View file

@ -46,10 +46,9 @@ private:
EventBus eventBus; EventBus eventBus;
InputHandler inputHandler; InputHandler inputHandler;
std::shared_ptr<MapContext> ctx;
std::shared_ptr<View::Window> window; std::shared_ptr<View::Window> window;
std::shared_ptr<View::MapView> mapView;
std::shared_ptr<MapContext> ctx;
std::thread eventThread; std::thread eventThread;
std::mutex modelMutex; std::mutex modelMutex;

View file

@ -31,8 +31,8 @@ namespace RPGEdit {
namespace Model { namespace Model {
std::shared_ptr<Map> Map::load(__attribute__((unused)) const std::string &name) { std::unique_ptr<Map> Map::load(__attribute__((unused)) const std::string &name) {
std::shared_ptr<Map> map(new Map(16, 16, 2)); std::unique_ptr<Map> map(new Map(16, 16, 2));
map->tileset.push_back("dirt"); map->tileset.push_back("dirt");
map->tileset.push_back("horizontal_bar"); map->tileset.push_back("horizontal_bar");

View file

@ -27,6 +27,7 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <deque>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
@ -44,7 +45,7 @@ private:
size_t width, height; size_t width, height;
std::vector<std::vector<uint32_t>> tiles; std::vector<std::vector<uint32_t>> tiles;
std::vector<Entity> entities; std::deque<Entity> entities;
Map(size_t width0, size_t height0, size_t layers) Map(size_t width0, size_t height0, size_t layers)
@ -62,11 +63,11 @@ public:
return tileset; return tileset;
} }
std::vector<Entity> & getEntities() { std::deque<Entity> & getEntities() {
return entities; return entities;
} }
const std::vector<Entity> & getEntities() const { const std::deque<Entity> & getEntities() const {
return entities; return entities;
} }
@ -96,7 +97,7 @@ public:
return tiles[layer][y*width + x]; return tiles[layer][y*width + x];
} }
static std::shared_ptr<Map> load(const std::string &name); static std::unique_ptr<Map> load(const std::string &name);
}; };
} }

View file

@ -31,9 +31,8 @@ namespace RPGEdit {
namespace View { namespace View {
MapView::MapView(const std::shared_ptr<Window> &window0, MapView::MapView(const std::shared_ptr<Window> &window0, const std::vector<std::string> &tileset)
const std::shared_ptr<const Model::Map> &map0) : window(window0) {
: window(window0), map(map0) {
uint32_t rmask, gmask, bmask, amask; uint32_t rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN #if SDL_BYTEORDER == SDL_BIG_ENDIAN
@ -50,8 +49,6 @@ MapView::MapView(const std::shared_ptr<Window> &window0,
SpriteCache *spriteCache = window->getSpriteCache(); SpriteCache *spriteCache = window->getSpriteCache();
const std::vector<std::string> &tileset = map->getTileset();
SDL_Surface *surface = SDL_CreateRGBSurface(0, getTileSize()*tileset.size(), getTileSize(), 32, rmask, gmask, bmask, amask); SDL_Surface *surface = SDL_CreateRGBSurface(0, getTileSize()*tileset.size(), getTileSize(), 32, rmask, gmask, bmask, amask);
for (size_t i = 0; i < tileset.size(); i++) { for (size_t i = 0; i < tileset.size(); i++) {
@ -79,11 +76,11 @@ MapView::~MapView() {
clearEntities(); clearEntities();
} }
void MapView::updateEntities(const std::vector<std::unique_ptr<Model::Entity>> &entities) { void MapView::updateEntities(const std::deque<Model::Entity> &entities) {
SpriteCache *spriteCache = window->getSpriteCache(); SpriteCache *spriteCache = window->getSpriteCache();
for (auto &entity : entities) { for (auto &entity : entities) {
const std::string &name = entity->getName(); const std::string &name = entity.getName();
if (!entitySprites[name]) if (!entitySprites[name])
entitySprites[name] = SDL_CreateTextureFromSurface(window->getRenderer(), spriteCache->get("entity", name)); entitySprites[name] = SDL_CreateTextureFromSurface(window->getRenderer(), spriteCache->get("entity", name));
@ -91,13 +88,13 @@ void MapView::updateEntities(const std::vector<std::unique_ptr<Model::Entity>> &
} }
void MapView::clearEntities() { void MapView::clearEntities() {
for (const std::pair<std::string, SDL_Texture *> &entity : entitySprites) for (auto &entity : entitySprites)
SDL_DestroyTexture(entity.second); SDL_DestroyTexture(entity.second);
entitySprites.clear(); entitySprites.clear();
} }
void MapView::render(const std::vector<std::unique_ptr<Model::Entity>> &entities, Model::Position center, uint64_t time) { void MapView::render(const Model::Map *map, Model::Position center, uint64_t time) {
SDL_RenderClear(window->getRenderer()); SDL_RenderClear(window->getRenderer());
std::pair<int, int> viewport = window->getViewport(); std::pair<int, int> viewport = window->getViewport();
@ -139,9 +136,9 @@ void MapView::render(const std::vector<std::unique_ptr<Model::Entity>> &entities
} }
} }
for (const std::unique_ptr<Model::Entity> &entity : entities) { for (auto &entity : map->getEntities()) {
Model::Position pos = entity->getPosition(time); Model::Position pos = entity.getPosition(time);
Model::Direction dir = entity->getDirection(); Model::Direction dir = entity.getDirection();
SDL_Rect src = { SDL_Rect src = {
.x = getTileSize()*dir, .x = getTileSize()*dir,
@ -157,7 +154,7 @@ void MapView::render(const std::vector<std::unique_ptr<Model::Entity>> &entities
.h = tilePixels, .h = tilePixels,
}; };
SDL_RenderCopy(window->getRenderer(), entitySprites[entity->getName()], &src, &dst); SDL_RenderCopy(window->getRenderer(), entitySprites[entity.getName()], &src, &dst);
} }
} }

View file

@ -41,7 +41,6 @@ namespace View {
class MapView { class MapView {
private: private:
std::shared_ptr<Window> window; std::shared_ptr<Window> window;
std::shared_ptr<const Model::Map> map;
SDL_Texture *tiles; SDL_Texture *tiles;
std::map<std::string, SDL_Texture *> entitySprites; std::map<std::string, SDL_Texture *> entitySprites;
@ -51,14 +50,15 @@ private:
} }
public: public:
MapView(const std::shared_ptr<Window> &window0, MapView(const std::shared_ptr<Window> &window0, const std::vector<std::string> &tileset);
const std::shared_ptr<const Model::Map> &map0);
~MapView(); ~MapView();
void updateEntities(const std::vector<std::unique_ptr<Model::Entity>> &entities); void updateEntities(const std::deque<Model::Entity> &entities);
void clearEntities(); void clearEntities();
void render(const std::vector<std::unique_ptr<Model::Entity>> &entities, Model::Position center, uint64_t time); void clear();
void render(const Model::Map *map, Model::Position center, uint64_t time);
}; };
} }