layer.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <SDL.h>
00026
00027
00028
00029
00030
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
00249 }
00250
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 }