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 #include "video/imagepool.h"
00039 #include "video/animationpool.h"
00040 
00041 #include "map.h"
00042 #include "layer.h"
00043 
00044 namespace FIFE {
00045 
00046     Map::Map(const std::string& identifier, RenderBackend* renderBackend, 
00047             const std::vector<RendererBase*>& renderers, ImagePool* imagePool, 
00048             AnimationPool* animPool, TimeProvider* tp_master):
00049         m_id(identifier), 
00050         m_timeprovider(tp_master),
00051         m_changelisteners(),
00052         m_changedlayers(),
00053         m_changed(false),
00054         m_renderbackend(renderBackend),
00055         m_imagepool(imagePool),
00056         m_animpool(animPool),
00057         m_renderers(renderers) {
00058 
00059     }
00060 
00061     Map::~Map() {
00062         deleteLayers();
00063     }
00064 
00065     Layer* Map::getLayer(const std::string& id) {
00066         std::list<Layer*>::const_iterator it = m_layers.begin();
00067         for(; it != m_layers.end(); ++it) {
00068             if((*it)->getId() == id)
00069                 return *it;
00070         }
00071 
00072         throw NotFound(id);
00073     }
00074 
00075     size_t Map::getNumLayers() const {
00076         return m_layers.size();
00077     }
00078 
00079     Layer* Map::createLayer(const std::string& identifier, CellGrid* grid) {
00080         std::list<Layer*>::const_iterator it = m_layers.begin();
00081         for(; it != m_layers.end(); ++it) {
00082             if(identifier == (*it)->getId())
00083                 throw NameClash(identifier);
00084         }
00085 
00086         Layer* layer = new Layer(identifier, this, grid);
00087         m_layers.push_back(layer);
00088         m_changed = true;
00089         std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00090         while (i != m_changelisteners.end()) {
00091             (*i)->onLayerCreate(this, layer);
00092             ++i;
00093         }
00094         
00095         return layer;
00096     }
00097 
00098     void Map::deleteLayer(Layer* layer) {
00099         std::list<Layer*>::iterator it = m_layers.begin();
00100         for(; it != m_layers.end(); ++it) {
00101             if((*it) == layer) {
00102                 std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00103                 while (i != m_changelisteners.end()) {
00104                     (*i)->onLayerDelete(this, layer);
00105                     ++i;
00106                 }
00107                 delete layer;
00108                 m_layers.erase(it);
00109                 return ;
00110             }
00111         }
00112         m_changed = true;
00113     }
00114 
00115     void Map::deleteLayers() {
00116         std::list<Layer*>::iterator it = m_layers.begin();
00117         for(; it != m_layers.end(); ++it) {
00118             std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00119             while (i != m_changelisteners.end()) {
00120                 (*i)->onLayerDelete(this, *it);
00121                 ++i;
00122             }
00123         }
00124         purge(m_layers);
00125         m_layers.clear();
00126     }
00127 
00128     bool Map::update() {
00129         m_changedlayers.clear();
00130         std::list<Layer*>::iterator it = m_layers.begin();
00131         for(; it != m_layers.end(); ++it) {
00132             if ((*it)->update()) {
00133                 m_changedlayers.push_back(*it);
00134             }
00135         }
00136         if (!m_changedlayers.empty()) {
00137             std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00138             while (i != m_changelisteners.end()) {
00139                 (*i)->onMapChanged(this, m_changedlayers);
00140                 ++i;
00141             }
00142         }
00143 
00144         // loop over cameras and update if enabled
00145         std::vector<Camera*>::iterator camIter = m_cameras.begin();
00146         for ( ; camIter != m_cameras.end(); ++camIter) {
00147             if ((*camIter)->isEnabled()) {
00148                 (*camIter)->update();
00149                 (*camIter)->render();
00150             }
00151         }
00152 
00153         bool retval = m_changed;
00154         m_changed = false;
00155         return retval;
00156     }
00157     
00158     void Map::addChangeListener(MapChangeListener* listener) {
00159         m_changelisteners.push_back(listener);
00160     }
00161 
00162     void Map::removeChangeListener(MapChangeListener* listener) {
00163         std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
00164         while (i != m_changelisteners.end()) {
00165             if ((*i) == listener) {
00166                 m_changelisteners.erase(i);
00167                 return;
00168             }
00169             ++i;
00170         }
00171     }
00172 
00173     Camera* Map::addCamera(const std::string &id, Layer *layer, 
00174                             const Rect& viewport, const ExactModelCoordinate& emc) {
00175         if (layer == NULL) {
00176             throw NotSupported("Must have valid layer for camera");
00177         }
00178 
00179         if (getCamera(id)) {
00180             std::string errorStr = "Camera: " + id + " already exists";
00181             throw NameClash(errorStr);
00182         }
00183 
00184         // create new camera and add to list of cameras
00185         Camera* camera = new Camera(id, layer, viewport, emc, m_renderbackend, m_imagepool, m_animpool);
00186         m_cameras.push_back(camera);
00187 
00188         std::vector<RendererBase*>::iterator iter = m_renderers.begin();
00189         for ( ; iter != m_renderers.end(); ++iter) {
00190             camera->addRenderer((*iter)->clone());
00191         }
00192 
00193         return camera;
00194     }
00195 
00196     void Map::removeCamera(const std::string &id) {
00197         std::vector<Camera*>::iterator iter = m_cameras.begin();
00198         for ( ; iter != m_cameras.end(); ++iter) {
00199             if ((*iter)->getId() == id) {
00200                 // camera has been found delete it
00201                 delete *iter;
00202 
00203                 // now remove it from the vector
00204                 // note this invalidates iterators, but we do not need
00205                 // to worry about it in this case since we are done
00206                 m_cameras.erase(iter);
00207 
00208                 break;
00209             }
00210         }
00211     }
00212 
00213     Camera* Map::getCamera(const std::string &id) {
00214         std::vector<Camera*>::iterator iter = m_cameras.begin();
00215         for ( ; iter != m_cameras.end(); ++iter) {
00216             if ((*iter)->getId() == id) {
00217                 return *iter;
00218             }
00219         }
00220 
00221         return NULL;
00222     }
00223 
00224     std::vector<Camera*>& Map::getCameras() {
00225         return m_cameras;
00226     }
00227 
00228 } //FIFE
00229 
Generated by  doxygen 1.6.2-20100208