9 #include <mrpt/core/format.h> 10 #include <mrpt/core/lock_helper.h> 11 #include <mrpt/system/filesystem.h> 25 using namespace mvsim;
31 load_from_XML(fil_xml.data(), xmlFileNamePath.c_str());
35 const std::string& xml_text,
const std::string& fileNameForPath)
42 mrpt::system::trim(mrpt::system::extractFileDirectory(fileNameForPath));
45 auto lck = mrpt::lockHelper(world_cs_);
52 std::make_shared<DummyInvisibleBlock>(
this);
54 simulableObjectsMtx_.lock();
55 simulableObjects_.emplace(
"__standaloneSensorHost", standaloneSensorHost);
56 simulableObjectsMtx_.unlock();
62 if (0 != strcmp(root->name(),
"mvsim_world"))
63 throw runtime_error(mrpt::format(
64 "XML root element is '%s' ('mvsim_world' expected)", root->name()));
67 const xml_attribute<>* attrb_version = root->first_attribute(
"version");
68 int version_major = 1, version_min = 0;
72 attrb_version->
value(),
"%i.%i", &version_major, &version_min);
74 throw runtime_error(mrpt::format(
75 "Error parsing version attribute: '%s' ('%%i.%%i' " 77 attrb_version->
value()));
81 register_standard_xml_tag_parsers();
89 internal_recursive_parse_XML({node, basePath_});
95 internal_initialize();
100 if (!xmlParsers_.empty())
return;
122 using namespace std::string_literals;
128 const auto savedBasePath = basePath_;
132 if (
auto itParser = xmlParsers_.find(node->
name());
133 itParser != xmlParsers_.end())
135 itParser->second(ctx);
142 MRPT_LOG_WARN_STREAM(
143 "[World::load_from_XML] *Warning* Ignoring unknown XML node " 145 << node->
name() <<
"'");
150 basePath_ = savedBasePath;
157 worldElements_.emplace_back(e);
159 auto lckListObjs = mrpt::lockHelper(getListOfSimulableObjectsMtx());
160 simulableObjects_.emplace(
161 e->getName(), std::dynamic_pointer_cast<
Simulable>(e));
169 veh->setVehicleIndex(vehicles_.size());
172 vehicles_.count(veh->getName()) == 0,
173 mrpt::format(
"Duplicated vehicle name: '%s'", veh->getName().c_str()));
175 vehicles_.insert(VehicleList::value_type(veh->getName(), veh));
177 auto lckListObjs = mrpt::lockHelper(getListOfSimulableObjectsMtx());
178 simulableObjects_.emplace(
179 veh->getName(), std::dynamic_pointer_cast<
Simulable>(veh));
191 auto lckListObjs = mrpt::lockHelper(getListOfSimulableObjectsMtx());
195 simulableObjects_.find(
"__standaloneSensorHost")->second);
196 ASSERT_(standaloneSensorHost);
200 standaloneSensorHost->add_sensor(sensor);
219 guiOptions_.parse_from(*ctx.
node, *
this);
225 lightOptions_.parse_from(*ctx.
node, *
this);
230 process_load_walls(*ctx.
node);
238 "XML tag '<include />' must have a 'file=\"xxx\"' attribute)");
240 const std::string relFile =
241 mvsim::parse(fileAttrb->value(), user_defined_variables());
243 const auto absFile = this->local_to_abs_path(relFile);
244 MRPT_LOG_DEBUG_STREAM(
"XML parser: including file: '" << absFile <<
"'");
246 std::map<std::string, std::string> vars;
250 if (strcmp(attr->name(),
"file") == 0)
continue;
251 vars[attr->name()] = attr->value();
258 const auto newBasePath =
259 mrpt::system::trim(mrpt::system::extractFileDirectory(absFile));
260 internal_recursive_parse_XML({root, newBasePath});
268 "XML tag '<variable />' must have a 'name=\"xxx\"' attribute)");
269 const auto name = nameAttr->value();
274 "XML tag '<variable />' must have a 'value=\"xxx\"' attribute)");
276 const std::string finalValue =
277 mvsim::parse(valueAttr->value(), userDefinedVariables_);
279 userDefinedVariables_[name] = finalValue;
286 varAttr,
"XML tag '<for />' must have a 'var=\"xxx\"' attribute)");
287 const auto varName = varAttr->value();
291 varFrom,
"XML tag '<for />' must have a 'from=\"xxx\"' attribute)");
292 const auto fromStr =
mvsim::parse(varFrom->value(), userDefinedVariables_);
295 ASSERTMSG_(varTo,
"XML tag '<for />' must have a 'to=\"xxx\"' attribute)");
296 const auto toStr =
mvsim::parse(varTo->value(), userDefinedVariables_);
298 bool forBodyEmpty =
true;
303 forBodyEmpty =
false;
304 for (
int curVal = std::stoi(fromStr); curVal <= std::stoi(toStr);
307 userDefinedVariables_[varName] = std::to_string(curVal);
308 internal_recursive_parse_XML({childNode, basePath_});
314 MRPT_LOG_WARN_STREAM(
315 "[World::load_from_XML] *Warning* <for ...> </for> loop has no " 325 varCond,
"XML tag '<if />' must have a 'condition=\"xxx\"' attribute)");
326 const auto str =
mvsim::parse(varCond->value(), userDefinedVariables_);
329 std::optional<int> intVal;
330 char* retStr =
nullptr;
331 const long long ret = std::strtoll(str.c_str(), &retStr, 0 );
332 if (retStr != 0 && retStr != str.c_str()) intVal = ret;
334 bool isTrue = str ==
"y" || str ==
"Y" || str ==
"yes" || str ==
"Yes" ||
335 str ==
"YES" || str ==
"true" || str ==
"True" ||
336 str ==
"TRUE" || str ==
"on" || str ==
"ON" || str ==
"On" ||
337 (intVal.has_value() && intVal.value() != 0);
344 internal_recursive_parse_XML({childNode, basePath_});
This file contains rapidxml parser and DOM implementation.
void parse_tag_for(const XmlParserContext &ctx)
void parse_tag_include(const XmlParserContext &ctx)
static Ptr factory(World *parent, const rapidxml::xml_node< char > *xml_node, const char *class_name=nullptr)
void parse_tag_variable(const XmlParserContext &ctx)
Represents data loaded from a file.
static Ptr factory(World *parent, const rapidxml::xml_node< char > *xml_node)
void parse_tag_block_class(const XmlParserContext &ctx)
bool parse_xmlnode_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions ¶ms, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
static Ptr factory(World *parent, const rapidxml::xml_node< char > *xml_node)
static void register_block_class(const rapidxml::xml_node< char > *xml_node)
void parse_tag_lights(const XmlParserContext &ctx)
void parse_tag_element(const XmlParserContext &ctx)
<element>
void internal_recursive_parse_XML(const XmlParserContext &ctx)
This will parse a main XML file, or its included.
void parse_tag_block(const XmlParserContext &ctx)
std::shared_ptr< Block > Ptr
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
void parse_tag_vehicle(const XmlParserContext &ctx)
<vehicle>
std::shared_ptr< WorldElementBase > Ptr
void register_standard_xml_tag_parsers()
void parse_tag_if(const XmlParserContext &ctx)
std::shared_ptr< SensorBase > Ptr
std::shared_ptr< VehicleBase > Ptr
void parse_tag_walls(const XmlParserContext &ctx)
std::string parse(const std::string &input, const std::map< std::string, std::string > &variableNamesValues={})
std::tuple< XML_Doc_Data::Ptr, rapidxml::xml_node<> * > readXmlAndGetRoot(const std::string &pathToFile, const std::map< std::string, std::string > &variables, const std::set< std::string > &varsRetain={})
static void register_vehicle_class(const rapidxml::xml_node< char > *xml_node)
const std::string currentBasePath
std::shared_ptr< DummyInvisibleBlock > Ptr
void load_from_XML_file(const std::string &xmlFileNamePath)
void load_from_XML(const std::string &xml_text, const std::string &fileNameForPath=std::string("."))
typedef void(GLAD_API_PTR *GLDEBUGPROC)(GLenum source
void parse_tag_vehicle_class(const XmlParserContext &ctx)
This file contains rapidxml printer implementation.
xml_node< Ch > * next_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
static SensorBase::Ptr factory(Simulable &parent, const rapidxml::xml_node< char > *xml_node)
void parse_tag_sensor(const XmlParserContext &ctx)
<sensor>
void parse_tag_gui(const XmlParserContext &ctx)
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
const rapidxml::xml_node< char > * node
std::tuple< std::shared_ptr< rapidxml::xml_document<> >, rapidxml::xml_node<> * > readXmlTextAndGetRoot(const std::string &xmlData, const std::string &pathToFile)
xml_attribute< Ch > * next_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const