layer.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 
00024 // 3rd party library includes
00025 #include <SDL.h>
00026 
00027 // FIFE includes
00028 // These includes are split up in two parts, separated by one empty line
00029 // First block: files included from the FIFE root src directory
00030 // Second block: files included from the same folder
00031 #include "util/log/logger.h"
00032 #include "util/structures/purge.h"
00033 
00034 #include "layer.h"
00035 #include "instance.h"
00036 #include "map.h"
00037 #include "instancetree.h"
00038 
00039 namespace FIFE {
00040 
00041     static Logger _log(LM_STRUCTURES);
00042 
00043     Layer::Layer(const std::string& identifier, Map* map, CellGrid* grid)
00044         : m_id(identifier),
00045         m_map(map),
00046         m_instances_visibility(true),
00047         m_transparency(0),
00048         m_instanceTree(new InstanceTree()),
00049         m_grid(grid),
00050         m_pathingstrategy(CELL_EDGES_ONLY),
00051         m_changelisteners(),
00052         m_changedinstances(),
00053         m_changed(false) {
00054     }
00055 
00056     Layer::~Layer() {
00057         purge(m_instances);
00058         delete m_instanceTree;
00059     }
00060 
00061     bool Layer::hasInstances() const {
00062         return !m_instances.empty();
00063     }
00064 
00065     Instance* Layer::createInstance(Object* object, const ModelCoordinate& p, const std::string& id) {
00066         ExactModelCoordinate emc(static_cast<double>(p.x), static_cast<double>(p.y), static_cast<double>(p.z));
00067         return createInstance(object, emc, id);
00068     }
00069 
00070     Instance* Layer::createInstance(Object* object, const ExactModelCoordinate& p, const std::string& id) {
00071         Location l;
00072         l.setLayer(this);
00073         l.setExactLayerCoordinates(p);
00074 
00075         Instance* instance = new Instance(object, l, id);
00076         m_instances.push_back(instance);
00077         m_instanceTree->addInstance(instance);
00078 
00079         std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00080         while (i != m_changelisteners.end()) {
00081             (*i)->onInstanceCreate(this, instance);
00082             ++i;
00083         }
00084         m_changed = true;
00085         return instance;
00086     }
00087 
00088     bool Layer::addInstance(Instance* instance, const ExactModelCoordinate& p){
00089         if( !instance ){
00090             FL_ERR(_log, "Tried to add an instance to layer, but given instance is invalid");
00091             return false;
00092         }
00093 
00094         Location l;
00095         l.setLayer(this);
00096         l.setExactLayerCoordinates(p);
00097 
00098         m_instances.push_back(instance);
00099         m_instanceTree->addInstance(instance);
00100 
00101         std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00102         while (i != m_changelisteners.end()) {
00103             (*i)->onInstanceCreate(this, instance);
00104             ++i;
00105         }
00106         m_changed = true;
00107         return true;
00108     }
00109 
00110     void Layer::deleteInstance(Instance* instance) {
00111         std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00112         while (i != m_changelisteners.end()) {
00113             (*i)->onInstanceDelete(this, instance);
00114             ++i;
00115         }
00116 
00117         std::vector<Instance*>::iterator it = m_instances.begin();
00118         for(; it != m_instances.end(); ++it) {
00119             if(*it == instance) {
00120                 m_instanceTree->removeInstance(*it);
00121                 delete *it;
00122                 m_instances.erase(it);
00123                 break;
00124             }
00125         }
00126         m_changed = true;
00127     }
00128 
00129     Instance* Layer::getInstance(const std::string& id) {
00130         std::vector<Instance*>::iterator it = m_instances.begin();
00131         for(; it != m_instances.end(); ++it) {
00132             if((*it)->getId() == id)
00133                 return *it;
00134         }
00135 
00136         throw NotFound(id);
00137     }
00138 
00139     std::vector<Instance*> Layer::getInstances(const std::string& id) {
00140         std::vector<Instance*> matching_instances;
00141         std::vector<Instance*>::iterator it = m_instances.begin();
00142         for(; it != m_instances.end(); ++it) {
00143             if((*it)->getId() == id)
00144                 matching_instances.push_back(*it);
00145         }
00146         return matching_instances;
00147     }
00148 
00149     std::vector<Instance*> Layer::getInstancesAt(Location& loc, bool use_exactcoordinates) {
00150         std::vector<Instance*> matching_instances;
00151         std::vector<Instance*>::iterator it = m_instances.begin();
00152 
00153         for(; it != m_instances.end(); ++it) {
00154             if (use_exactcoordinates) {
00155                 if ((*it)->getLocationRef().getExactLayerCoordinatesRef() == loc.getExactLayerCoordinatesRef()) {
00156                     matching_instances.push_back(*it);
00157                 }
00158             } else {
00159                 if ((*it)->getLocationRef().getLayerCoordinates() == loc.getLayerCoordinates()) {
00160                     matching_instances.push_back(*it);
00161                 }
00162             }
00163         }
00164 
00165         return matching_instances;
00166     }
00167 
00168     void Layer::getMinMaxCoordinates(ModelCoordinate& min, ModelCoordinate& max, const Layer* layer) const {
00169         if (!layer) {
00170             layer = this;
00171         }
00172 
00173         bool first_found = false;
00174         for (std::vector<Instance*>::const_iterator i = m_instances.begin(); i != m_instances.end(); ++i) {
00175             if (!first_found) {
00176                 min = m_instances.front()->getLocationRef().getLayerCoordinates(layer);
00177                 max = min;
00178                 first_found = true;
00179             } else {
00180                 ModelCoordinate coord = (*i)->getLocationRef().getLayerCoordinates(layer);
00181 
00182                 if(coord.x < min.x) {
00183                     min.x = coord.x;
00184                 }
00185 
00186                 if(coord.x > max.x) {
00187                     max.x = coord.x;
00188                 }
00189 
00190                 if(coord.y < min.y) {
00191                     min.y = coord.y;
00192                 }
00193 
00194                 if(coord.y > max.y) {
00195                     max.y = coord.y;
00196                 }
00197             }
00198         }
00199         if (!first_found) {
00200             min = ModelCoordinate();
00201             max = min;
00202         }
00203     }
00204 
00205     void Layer::setInstancesVisible(bool vis) {
00206         m_instances_visibility = vis;
00207     }
00208 
00209     void Layer::setLayerTransparency(uint8_t transparency) {
00210         m_transparency = transparency;
00211     }
00212 
00213     uint8_t Layer::getLayerTransparency() {
00214         return m_transparency;
00215     }
00216 
00217     void Layer::toggleInstancesVisible() {
00218         m_instances_visibility = !m_instances_visibility;
00219     }
00220 
00221     bool Layer::cellContainsBlockingInstance(const ModelCoordinate& cellCoordinate) {
00222         std::list<Instance*> adjacentInstances;
00223         m_instanceTree->findInstances(cellCoordinate, 0, 0, adjacentInstances);
00224         bool blockingInstance = false;
00225         for(std::list<Instance*>::const_iterator j = adjacentInstances.begin(); j != adjacentInstances.end(); ++j) {
00226             if((*j)->getObject()->isBlocking() && (*j)->getLocationRef().getLayerCoordinates() == cellCoordinate) {
00227                 blockingInstance = true;
00228             }
00229         }
00230         return blockingInstance;
00231     }
00232 
00233     bool Layer::update() {
00234         m_changedinstances.clear();
00235         std::vector<Instance*>::iterator it = m_instances.begin();
00236         for(; it != m_instances.end(); ++it) {
00237             if ((*it)->update() != ICHANGE_NO_CHANGES) {
00238                 m_changedinstances.push_back(*it);
00239                 m_changed = true;
00240             }
00241         }
00242         if (!m_changedinstances.empty()) {
00243             std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00244             while (i != m_changelisteners.end()) {
00245                 (*i)->onLayerChanged(this, m_changedinstances);
00246                 ++i;
00247             }
00248             //std::cout << "Layer named " << Id() << " changed = 1\n";
00249         }
00250         //std::cout << "Layer named " << Id() << " changed = 0\n";
00251         bool retval = m_changed;
00252         m_changed = false;
00253         return retval;
00254     }
00255 
00256     void Layer::addChangeListener(LayerChangeListener* listener) {
00257         m_changelisteners.push_back(listener);
00258     }
00259 
00260     void Layer::removeChangeListener(LayerChangeListener* listener) {
00261         std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00262         while (i != m_changelisteners.end()) {
00263             if ((*i) == listener) {
00264                 m_changelisteners.erase(i);
00265                 return;
00266             }
00267             ++i;
00268         }
00269     }
00270 } // FIFE
Generated by  doxygen 1.6.2-20100208