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 location;
00072 location.setLayer(this);
00073 location.setExactLayerCoordinates(p);
00074
00075 Instance* instance = new Instance(object, location, id);
00076 if(instance->isActive()) {
00077 setInstanceActivityStatus(instance, instance->isActive());
00078 }
00079 m_instances.push_back(instance);
00080 m_instanceTree->addInstance(instance);
00081
00082 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00083 while (i != m_changelisteners.end()) {
00084 (*i)->onInstanceCreate(this, instance);
00085 ++i;
00086 }
00087 m_changed = true;
00088 return instance;
00089 }
00090
00091 bool Layer::addInstance(Instance* instance, const ExactModelCoordinate& p){
00092 if( !instance ){
00093 FL_ERR(_log, "Tried to add an instance to layer, but given instance is invalid");
00094 return false;
00095 }
00096
00097 Location location;
00098 location.setLayer(this);
00099 location.setExactLayerCoordinates(p);
00100 instance->setLocation(location);
00101
00102 m_instances.push_back(instance);
00103 m_instanceTree->addInstance(instance);
00104 if(instance->isActive()) {
00105 setInstanceActivityStatus(instance, instance->isActive());
00106 }
00107
00108 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00109 while (i != m_changelisteners.end()) {
00110 (*i)->onInstanceCreate(this, instance);
00111 ++i;
00112 }
00113 m_changed = true;
00114 return true;
00115 }
00116
00117 void Layer::deleteInstance(Instance* instance) {
00118 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00119 while (i != m_changelisteners.end()) {
00120 (*i)->onInstanceDelete(this, instance);
00121 ++i;
00122 }
00123 setInstanceActivityStatus(instance, false);
00124 std::vector<Instance*>::iterator it = m_instances.begin();
00125 for(; it != m_instances.end(); ++it) {
00126 if(*it == instance) {
00127 m_instanceTree->removeInstance(*it);
00128 delete *it;
00129 m_instances.erase(it);
00130 break;
00131 }
00132 }
00133 m_changed = true;
00134 }
00135
00136 void Layer::setInstanceActivityStatus(Instance* instance, bool active) {
00137 if(active) {
00138 m_active_instances.insert(instance);
00139 } else {
00140 m_active_instances.erase(instance);
00141 }
00142 }
00143
00144 Instance* Layer::getInstance(const std::string& id) {
00145 std::vector<Instance*>::iterator it = m_instances.begin();
00146 for(; it != m_instances.end(); ++it) {
00147 if((*it)->getId() == id)
00148 return *it;
00149 }
00150
00151 return 0;
00152 }
00153
00154 std::vector<Instance*> Layer::getInstances(const std::string& id) {
00155 std::vector<Instance*> matching_instances;
00156 std::vector<Instance*>::iterator it = m_instances.begin();
00157 for(; it != m_instances.end(); ++it) {
00158 if((*it)->getId() == id)
00159 matching_instances.push_back(*it);
00160 }
00161 return matching_instances;
00162 }
00163
00164 std::vector<Instance*> Layer::getInstancesAt(Location& loc, bool use_exactcoordinates) {
00165 std::vector<Instance*> matching_instances;
00166 std::vector<Instance*>::iterator it = m_instances.begin();
00167
00168 for(; it != m_instances.end(); ++it) {
00169 if (use_exactcoordinates) {
00170 if ((*it)->getLocationRef().getExactLayerCoordinatesRef() == loc.getExactLayerCoordinatesRef()) {
00171 matching_instances.push_back(*it);
00172 }
00173 } else {
00174 if ((*it)->getLocationRef().getLayerCoordinates() == loc.getLayerCoordinates()) {
00175 matching_instances.push_back(*it);
00176 }
00177 }
00178 }
00179
00180 return matching_instances;
00181 }
00182
00183 void Layer::getMinMaxCoordinates(ModelCoordinate& min, ModelCoordinate& max, const Layer* layer) const {
00184 if (!layer) {
00185 layer = this;
00186 }
00187
00188 bool first_found = false;
00189 for (std::vector<Instance*>::const_iterator i = m_instances.begin(); i != m_instances.end(); ++i) {
00190 if (!first_found) {
00191 min = m_instances.front()->getLocationRef().getLayerCoordinates(layer);
00192 max = min;
00193 first_found = true;
00194 } else {
00195 ModelCoordinate coord = (*i)->getLocationRef().getLayerCoordinates(layer);
00196
00197 if(coord.x < min.x) {
00198 min.x = coord.x;
00199 }
00200
00201 if(coord.x > max.x) {
00202 max.x = coord.x;
00203 }
00204
00205 if(coord.y < min.y) {
00206 min.y = coord.y;
00207 }
00208
00209 if(coord.y > max.y) {
00210 max.y = coord.y;
00211 }
00212 }
00213 }
00214 if (!first_found) {
00215 min = ModelCoordinate();
00216 max = min;
00217 }
00218 }
00219
00220 void Layer::setInstancesVisible(bool vis) {
00221 m_instances_visibility = vis;
00222 }
00223
00224 void Layer::setLayerTransparency(uint8_t transparency) {
00225 m_transparency = transparency;
00226 }
00227
00228 uint8_t Layer::getLayerTransparency() {
00229 return m_transparency;
00230 }
00231
00232 void Layer::toggleInstancesVisible() {
00233 m_instances_visibility = !m_instances_visibility;
00234 }
00235
00236 bool Layer::cellContainsBlockingInstance(const ModelCoordinate& cellCoordinate) {
00237 std::list<Instance*> adjacentInstances;
00238 m_instanceTree->findInstances(cellCoordinate, 0, 0, adjacentInstances);
00239 bool blockingInstance = false;
00240 for(std::list<Instance*>::const_iterator j = adjacentInstances.begin(); j != adjacentInstances.end(); ++j) {
00241 if((*j)->isBlocking() && (*j)->getLocationRef().getLayerCoordinates() == cellCoordinate) {
00242 blockingInstance = true;
00243 }
00244 }
00245 return blockingInstance;
00246 }
00247
00248 bool Layer::update() {
00249 m_changedinstances.clear();
00250 std::set<Instance*>::iterator it = m_active_instances.begin();
00251 for(; it != m_active_instances.end(); ++it) {
00252 if ((*it)->update() != ICHANGE_NO_CHANGES) {
00253 m_changedinstances.push_back(*it);
00254 m_changed = true;
00255 }
00256 }
00257 if (!m_changedinstances.empty()) {
00258 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00259 while (i != m_changelisteners.end()) {
00260 (*i)->onLayerChanged(this, m_changedinstances);
00261 ++i;
00262 }
00263
00264 }
00265
00266 bool retval = m_changed;
00267 m_changed = false;
00268 return retval;
00269 }
00270
00271 void Layer::addChangeListener(LayerChangeListener* listener) {
00272 m_changelisteners.push_back(listener);
00273 }
00274
00275 void Layer::removeChangeListener(LayerChangeListener* listener) {
00276 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
00277 while (i != m_changelisteners.end()) {
00278 if ((*i) == listener) {
00279 m_changelisteners.erase(i);
00280 return;
00281 }
00282 ++i;
00283 }
00284 }
00285 }