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