00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "component.hpp"
00022 #include "engine.hpp"
00023 #include "property_handler.hpp"
00024 #include "../../config.hpp"
00025 #include "../../log.hpp"
00026 #include "../../foreach.hpp"
00027
00028 #include "../formula/ai.hpp"
00029
00030 #include <boost/lexical_cast.hpp>
00031 #include <boost/regex.hpp>
00032
00033 namespace pathfind {
00034
00035 struct pathfind;
00036
00037 }
00038
00039 namespace ai {
00040
00041 static lg::log_domain log_ai_component("ai/component");
00042 #define DBG_AI_COMPONENT LOG_STREAM(debug, log_ai_component)
00043 #define LOG_AI_COMPONENT LOG_STREAM(info, log_ai_component)
00044 #define ERR_AI_COMPONENT LOG_STREAM(err, log_ai_component)
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 component* component::get_child(const path_element &child)
00074 {
00075 std::map<std::string, property_handler_ptr>::iterator i = property_handlers_.find(child.property);
00076 if (i!=property_handlers_.end()) {
00077 return i->second->handle_get(child);
00078 }
00079 return NULL;
00080 }
00081
00082
00083 bool component::add_child(const path_element &child, const config &cfg)
00084 {
00085 std::map<std::string, property_handler_ptr>::iterator i = property_handlers_.find(child.property);
00086 if (i!=property_handlers_.end()) {
00087 return i->second->handle_add(child,cfg);
00088 }
00089 return false;
00090 }
00091
00092
00093 bool component::change_child(const path_element &child, const config &cfg)
00094 {
00095 std::map<std::string, property_handler_ptr>::iterator i = property_handlers_.find(child.property);
00096 if (i!=property_handlers_.end()) {
00097 return i->second->handle_change(child,cfg);
00098 }
00099 return false;
00100 }
00101
00102
00103 bool component::delete_child(const path_element &child)
00104 {
00105 std::map<std::string, property_handler_ptr>::iterator i = property_handlers_.find(child.property);
00106 if (i!=property_handlers_.end()) {
00107 return i->second->handle_delete(child);
00108 }
00109 return false;
00110 }
00111
00112
00113 std::vector<component*> component::get_children(const std::string &type)
00114 {
00115 property_handler_map::iterator i = property_handlers_.find(type);
00116 if (i!=property_handlers_.end()) {
00117 return i->second->handle_get_children();
00118 }
00119
00120 return std::vector<component*>();
00121 }
00122
00123
00124 std::vector<std::string> component::get_children_types()
00125 {
00126 std::vector<std::string> types;
00127 foreach (property_handler_map::value_type &ph, property_handlers_) {
00128 types.push_back(ph.first);
00129 }
00130 return types;
00131 }
00132
00133
00134 property_handler_map& component::property_handlers()
00135 {
00136 return property_handlers_;
00137 }
00138
00139 static component *find_component(component *root, const std::string &path, path_element &tail)
00140 {
00141 if (root==NULL) {
00142 return NULL;
00143 }
00144
00145
00146 boost::regex re("([^\\.^\\[]+)(\\[(\\d*)\\]|\\[([^\\]]+)\\]|())");
00147 int const sub_matches[] = {1,3,4};
00148 boost::sregex_token_iterator i(path.begin(), path.end(), re, sub_matches);
00149 boost::sregex_token_iterator j;
00150
00151 component *c = root;
00152
00153 std::vector< path_element > elements;
00154 while(i != j)
00155 {
00156 path_element pe;
00157 pe.property = *i++;
00158 std::string position = *i++;
00159 pe.id = *i++;
00160 if (position.empty()) {
00161 pe.position = -2;
00162 } else {
00163 try {
00164 pe.position = boost::lexical_cast<int>(position);
00165 } catch (boost::bad_lexical_cast){
00166 pe.position = -2;
00167 }
00168 }
00169
00170 elements.push_back(pe);
00171 }
00172 if (elements.size()<1) {
00173 return NULL;
00174 }
00175
00176 std::vector< path_element >::iterator k_max = elements.end()-1;
00177 for (std::vector< path_element >::iterator k = elements.begin(); k!=k_max; ++k) {
00178
00179 c = c->get_child(*k);
00180 if (c==NULL) {
00181 return NULL;
00182 }
00183 }
00184
00185 tail = *k_max;
00186 return c;
00187
00188 }
00189
00190
00191 bool component_manager::add_component(component *root, const std::string &path, const config &cfg)
00192 {
00193 path_element tail;
00194 component *c = find_component(root,path,tail);
00195 if (c==NULL) {
00196 return false;
00197 }
00198 const config &ch = cfg.child(tail.property);
00199 if (!ch) {
00200 return false;
00201 }
00202 return c->add_child(tail, ch);
00203
00204 }
00205
00206 bool component_manager::change_component(component *root, const std::string &path, const config &cfg)
00207 {
00208 path_element tail;
00209 component *c = find_component(root,path,tail);
00210 if (c==NULL) {
00211 return false;
00212 }
00213 const config &ch = cfg.child(tail.property);
00214 if (!ch) {
00215 return false;
00216 }
00217 return c->change_child(tail,ch);
00218 }
00219
00220 bool component_manager::delete_component(component *root, const std::string &path)
00221 {
00222 path_element tail;
00223 component *c = find_component(root,path,tail);
00224 if (c==NULL) {
00225 return false;
00226 }
00227 return c->delete_child(tail);
00228 }
00229
00230
00231 static void print_component(component *root, const std::string &type, std::stringstream &s, int offset)
00232 {
00233 std::stringstream offset_ss;
00234 for (int i=0;i<offset;++i) {
00235 offset_ss<<" ";
00236 }
00237 const std::string &offset_str = offset_ss.str();
00238
00239 const std::vector<std::string> &t_list = root->get_children_types();
00240
00241 s << offset_str << type<<"["<<root->get_id() <<"] "<<root->get_engine()<<" "<<root->get_name()<< std::endl;
00242
00243 foreach (std::string t, t_list) {
00244 std::vector<component*> c_list = root->get_children(t);
00245 foreach (component *c, c_list) {
00246 print_component(c,t,s,offset+1);
00247 }
00248 }
00249 }
00250
00251 std::string component_manager::print_component_tree(component *root, const std::string &path)
00252 {
00253 path_element tail;
00254 component *c;
00255 if (!path.empty()) {
00256 c = find_component(root,path,tail);
00257 if (c==NULL) {
00258 ERR_AI_COMPONENT << "unable to find component" <<std::endl;
00259 return "";
00260 }
00261 } else {
00262 c = root;
00263 }
00264 std::stringstream s;
00265 print_component(c, "", s, 0);
00266 return s.str();
00267 }
00268
00269 }
00270
00271
00272 std::ostream &operator<<(std::ostream &o, const ai::path_element &e)
00273 {
00274 o << "property["<<e.property<<"] id["<<e.id <<"] position["<<e.position<<"]"<<std::endl;
00275 return o;
00276 }