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
00031 #include "util/base/exception.h"
00032 #include "util/log/logger.h"
00033 #include "model/structures/instance.h"
00034 #include "util/structures/rect.h"
00035
00036 #include "instancetree.h"
00037
00038
00039 namespace FIFE {
00040 static Logger _log(LM_STRUCTURES);
00041
00042 InstanceTree::InstanceTree(): FifeClass() {
00043 }
00044
00045 InstanceTree::~InstanceTree() {
00046 }
00047
00048 void InstanceTree::addInstance(Instance* instance) {
00049 ModelCoordinate coords = instance->getLocationRef().getLayerCoordinates();
00050 InstanceTreeNode * node = m_tree.find_container(coords.x,coords.y,0,0);
00051 InstanceList& list = node->data();
00052 list.push_back(instance);
00053 if( m_reverse.find(instance) != m_reverse.end() ) {
00054 FL_WARN(_log, "InstanceTree::addInstance() - Duplicate Instance. Ignoring.");
00055 return;
00056 }
00057 m_reverse[instance] = node;
00058 }
00059
00060 void InstanceTree::removeInstance(Instance* instance) {
00061 ModelCoordinate coords = instance->getLocationRef().getLayerCoordinates();
00062 InstanceTreeNode * node = m_reverse[instance];
00063 if( !node ) {
00064 FL_WARN(_log, "InstanceTree::removeInstance() - Instance not part of tree.");
00065 return;
00066 }
00067 m_reverse.erase(instance);
00068 InstanceList& list = node->data();
00069 for(InstanceList::iterator i = list.begin(); i != list.end(); ++i) {
00070 if((*i) == instance) {
00071 list.erase(i);
00072 return;
00073 }
00074 }
00075 FL_WARN(_log, "InstanceTree::removeInstance() - Instance part of tree but not found in the expected tree node.");
00076 }
00077
00078 class InstanceListCollector {
00079 public:
00080 InstanceTree::InstanceList& instanceList;
00081 Rect searchRect;
00082 InstanceListCollector(InstanceTree::InstanceList& a_instanceList, const Rect& rect)
00083 : instanceList(a_instanceList), searchRect(rect) {
00084 }
00085 bool visit(InstanceTree::InstanceTreeNode* node, int32_t d);
00086 };
00087
00088 bool InstanceListCollector::visit(InstanceTree::InstanceTreeNode* node, int32_t d) {
00089 InstanceTree::InstanceList& list = node->data();
00090 for(InstanceTree::InstanceList::const_iterator it(list.begin()); it != list.end(); ++it) {
00091 ModelCoordinate coords = (*it)->getLocationRef().getLayerCoordinates();
00092 if( searchRect.contains(Point(coords.x,coords.y)) ) {
00093 instanceList.push_back(*it);
00094 }
00095 }
00096 return true;
00097 }
00098
00099 void InstanceTree::findInstances(const ModelCoordinate& point, int32_t w, int32_t h, InstanceTree::InstanceList& list) {
00100 InstanceTreeNode * node = m_tree.find_container(point.x, point.y, w, h);
00101 Rect rect(point.x, point.y, w, h);
00102 InstanceListCollector collector(list,rect);
00103
00104 node->apply_visitor(collector);
00105
00106 node = node->parent();
00107 while( node ) {
00108 for(InstanceList::const_iterator it(node->data().begin()); it != node->data().end(); ++it) {
00109 ModelCoordinate coords = (*it)->getLocationRef().getLayerCoordinates();
00110 if( rect.contains(Point(coords.x,coords.y)) ) {
00111 list.push_back(*it);
00112 }
00113 }
00114 node = node->parent();
00115 }
00116 }
00117
00118 }