map.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 #include <string>
00024 
00025 // 3rd party library includes
00026 #include <boost/lexical_cast.hpp>
00027 
00028 // FIFE includes
00029 // These includes are split up in two parts, separated by one empty line
00030 // First block: files included from the FIFE root src directory
00031 // Second block: files included from the same folder
00032 #include "util/base/exception.h"
00033 #include "util/structures/purge.h"
00034 #include "util/structures/rect.h"
00035 #include "view/camera.h"
00036 #include "view/rendererbase.h"
00037 #include "video/renderbackend.h"
00038 
00039 #include "map.h"
00040 #include "layer.h"
00041 
00042 namespace FIFE {
00043 
00044     Map::Map(const std::string& identifier, RenderBackend* renderBackend,
00045             const std::vector<RendererBase*>& renderers, TimeProvider* tp_master):
00046         m_id(identifier),
00047         m_filename(""),
00048         m_timeprovider(tp_master),
00049         m_changelisteners(),
00050         m_changedlayers(),
00051         m_renderbackend(renderBackend),
00052         m_renderers(renderers),
00053         m_changed(false){
00054     }
00055 
00056     Map::~Map() {
00057         // remove all cameras
00058         std::vector<Camera*>::iterator iter = m_cameras.begin();
00059         for ( ; iter != m_cameras.end(); ++iter) {
00060             delete *iter;
00061         }
00062         m_cameras.clear();
00063 
00064         deleteLayers();
00065     }
00066 
00067     Layer* Map::getLayer(const std::string& id) {
00068         std::list<Layer*>::const_iterator it = m_layers.begin();
00069         for(; it != m_layers.end(); ++it) {
00070             if((*it)->getId() == id)
00071                 return *it;
00072         }
00073 
00074         throw NotFound(id);
00075     }
00076 
00077     uint32_t Map::getLayerCount() const {
00078         return m_layers.size();
00079     }
00080 
00081     Layer* Map::createLayer(const std::string& identifier, CellGrid* grid) {
00082         std::list<Layer*>::const_iterator it = m_layers.begin();
00083         for(; it != m_layers.end(); ++it) {
00084             if(identifier == (*it)->getId())
00085                 throw NameClash(identifier);
00086         }
00087 
00088         Layer* layer = new Layer(identifier, this, grid);
00089         m_layers.push_back(layer);
00090         m_changed = true;
00091         std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00092         while (i != m_changelisteners.end()) {
00093             (*i)->onLayerCreate(this, layer);
00094             ++i;
00095         }
00096 
00097         return layer;
00098     }
00099 
00100     void Map::deleteLayer(Layer* layer) {
00101         std::list<Layer*>::iterator it = m_layers.begin();
00102         for(; it != m_layers.end(); ++it) {
00103             if((*it) == layer) {
00104                 std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00105                 while (i != m_changelisteners.end()) {
00106                     (*i)->onLayerDelete(this, layer);
00107                     ++i;
00108                 }
00109                 delete layer;
00110                 m_layers.erase(it);
00111                 return ;
00112             }
00113         }
00114         m_changed = true;
00115     }
00116 
00117     void Map::deleteLayers() {
00118         std::list<Layer*>::iterator it = m_layers.begin();
00119         for(; it != m_layers.end(); ++it) {
00120             std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00121             while (i != m_changelisteners.end()) {
00122                 (*i)->onLayerDelete(this, *it);
00123                 ++i;
00124             }
00125         }
00126         purge(m_layers);
00127         m_layers.clear();
00128     }
00129 
00130     void Map::getMinMaxCoordinates(ExactModelCoordinate& min, ExactModelCoordinate& max) {
00131         Location lmin;
00132         Location lmax;
00133         std::list<Layer*>::iterator it = m_layers.begin();
00134         Layer* layer = *it;
00135         for (; it != m_layers.end(); ++it) {
00136             ModelCoordinate newMin, newMax;
00137             (*it)->getMinMaxCoordinates(newMin, newMax, layer);
00138 
00139             if (newMin.x < min.x) {
00140                 min.x = newMin.x;
00141             }
00142             if (newMax.x > max.x) {
00143                 max.x = newMax.x;
00144             }
00145             if (newMin.y < min.y) {
00146                 min.y = newMin.y;
00147             }
00148             if (newMax.y > max.y) {
00149                 max.y = newMax.y;
00150             }
00151         }
00152         lmin.setLayer(layer);
00153         lmax.setLayer(layer);
00154         lmin.setExactLayerCoordinates(min);
00155         lmax.setExactLayerCoordinates(max);
00156 
00157         min = lmin.getMapCoordinates();
00158         max = lmax.getMapCoordinates();
00159     }
00160 
00161     bool Map::update() {
00162         m_changedlayers.clear();
00163         std::list<Layer*>::iterator it = m_layers.begin();
00164         for(; it != m_layers.end(); ++it) {
00165             if ((*it)->update()) {
00166                 m_changedlayers.push_back(*it);
00167             }
00168         }
00169         if (!m_changedlayers.empty()) {
00170             std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00171             while (i != m_changelisteners.end()) {
00172                 (*i)->onMapChanged(this, m_changedlayers);
00173                 ++i;
00174             }
00175         }
00176 
00177         // loop over cameras and update if enabled
00178         std::vector<Camera*>::iterator camIter = m_cameras.begin();
00179         for ( ; camIter != m_cameras.end(); ++camIter) {
00180             if ((*camIter)->isEnabled()) {
00181                 (*camIter)->update();
00182                 (*camIter)->render();
00183             }
00184         }
00185 
00186         bool retval = m_changed;
00187         m_changed = false;
00188         return retval;
00189     }
00190 
00191     void Map::addChangeListener(MapChangeListener* listener) {
00192         m_changelisteners.push_back(listener);
00193     }
00194 
00195     void Map::removeChangeListener(MapChangeListener* listener) {
00196         std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00197         while (i != m_changelisteners.end()) {
00198             if ((*i) == listener) {
00199                 m_changelisteners.erase(i);
00200                 return;
00201             }
00202             ++i;
00203         }
00204     }
00205 
00206     Camera* Map::addCamera(const std::string &id, Layer *layer, const Rect& viewport) {
00207         if (layer == NULL) {
00208             throw NotSupported("Must have valid layer for camera");
00209         }
00210 
00211         if (getCamera(id)) {
00212             std::string errorStr = "Camera: " + id + " already exists";
00213             throw NameClash(errorStr);
00214         }
00215 
00216         // create new camera and add to list of cameras
00217         Camera* camera = new Camera(id, layer, viewport, m_renderbackend);
00218         m_cameras.push_back(camera);
00219 
00220         std::vector<RendererBase*>::iterator iter = m_renderers.begin();
00221         for ( ; iter != m_renderers.end(); ++iter) {
00222             camera->addRenderer((*iter)->clone());
00223         }
00224 
00225         return camera;
00226     }
00227 
00228     void Map::removeCamera(const std::string &id) {
00229         std::vector<Camera*>::iterator iter = m_cameras.begin();
00230         for ( ; iter != m_cameras.end(); ++iter) {
00231             if ((*iter)->getId() == id) {
00232                 // camera has been found delete it
00233                 delete *iter;
00234 
00235                 // now remove it from the vector
00236                 // note this invalidates iterators, but we do not need
00237                 // to worry about it in this case since we are done
00238                 m_cameras.erase(iter);
00239 
00240                 break;
00241             }
00242         }
00243     }
00244 
00245     Camera* Map::getCamera(const std::string &id) {
00246         std::vector<Camera*>::iterator iter = m_cameras.begin();
00247         for ( ; iter != m_cameras.end(); ++iter) {
00248             if ((*iter)->getId() == id) {
00249                 return *iter;
00250             }
00251         }
00252 
00253         return NULL;
00254     }
00255 
00256     const std::vector<Camera*>& Map::getCameras() const {
00257         return m_cameras;
00258     }
00259 
00260 } //FIFE
00261