Ejemplo n.º 1
0
Archivo: Body.cpp Proyecto: bilwis/RMD
string Body::loadBody(const char *filename){
	
	//###XML FILE HANDLING###
	using namespace rapidxml;
	char *buffer;

	//Load XML file
	try{
	std::ifstream is (filename);

	if (is) {
		//Get file length
		is.seekg(0, is.end);

		int length = is.tellg();
		is.seekg(0, is.beg);

		buffer = new char[length];

		is.read(buffer, length);
		//buffer now holds entire XML file
	} else { return false; }

	//Parse XML file
	// WARNING: FILE MUST BE NULL-TERMINATED!

	xml_document<> doc;
	doc.parse<0>(buffer);


	//###TISSUE DATA###

	//Temporary variables
	char *id = nullptr, *name = nullptr;
	float pain = -1.0f, blood_flow = -1.0f, resistance = -1.0f, impairment = -1.0f; //Initialize with illegal values

	//Load the tissue data (First first_node() is "body_def",
	// data starts with second level "tissues")
	xml_node<> *tissues = doc.first_node()->first_node("tissues");

	char *_name;

	//Iterate through all tissue definitions
	for (xml_node<> *tissue = tissues->first_node();
			tissue;
			tissue = tissue->next_sibling())
	{
		//Iterate through the tissue attributes
		for (xml_node<> *attr = tissue->first_node();
				attr;
				attr = attr->next_sibling())
		{

			_name = attr->name();
			if (!strcmp(_name,"id")){ id = attr->value(); }
			else if (!strcmp(_name,"name")){ name = attr->value(); }
			else if (!strcmp(_name,"pain")){ pain = atof(attr->value()); }
			else if (!strcmp(_name,"blood_flow")){ blood_flow = atof(attr->value()); }
			else if (!strcmp(_name,"resistance")){ resistance = atof(attr->value()); }
			else if (!strcmp(_name,"impairment")){ impairment = atof(attr->value()); }
		}

		debug_print("Read Tissue:\n\tID: %s \n\tName: %s \n\tBlood Flow: %f \n\tResistance: %f \n\tImpairment: %f\n",
				id, name, blood_flow, resistance, impairment);

		//Create a new Tissue and store the shared pointer to it in the tissue map
		boost::shared_ptr<Tissue> t_tissue(new Tissue(id, name, pain, blood_flow, resistance, impairment));
		tissue_map->insert(std::pair<std::string, boost::shared_ptr<Tissue>>(std::string(id), t_tissue));
	}

	//###BODYPART DATA###

	//maps for child linking and organ linking
	//K: UUID of the child, V: UUID of the parent
	std::map<string, string>* child_map = new std::map<string, string>();
	//K: UUID of the organ, V: IID(!) of its connector
	std::map<string, string>* organ_link_map = new std::map<string, string>();

	//Load the bodypart data (First first_node() is "body_def", 
	// data starts with the second level "body" 
	xml_node<> *body = doc.first_node()->first_node("body");
	string root_uuid = enter(body->first_node(), child_map, organ_link_map);

	//Destroy the XML data in memory
	delete[] buffer;

	//Build IID<->UUID map, which is required for linking 
	makeIdMap();

	//Link children and organs
	for (std::map<string, string>::iterator ch_it = child_map->begin();
		ch_it != child_map->end(); ch_it++) 
	{
		if (getPartByUUID(ch_it->first) == nullptr)
		{
			debug_error("ERROR during body part linking: Part UUID %s was requested, but is not in part map!\n",
				ch_it->first.c_str());
			return nullptr;
		}
		if (getPartByUUID(ch_it->second) == nullptr)
		{
			debug_error("ERROR during body part linking: Part UUID %s was requested, but is not in part map!\n",
				ch_it->second.c_str());
			return nullptr;
		}
		
		BodyPart* parent = dynamic_cast<BodyPart*>(getPartByUUID(ch_it->second).get());
		if (parent == nullptr) 
		{
			debug_error("ERROR during body part linking: Casting from Part* to BodyPart* on Part %s failed!\n",
				ch_it->second.c_str());
			return nullptr;
		}

		parent->addChild(ch_it->first);
	}

	for (std::map<string, string>::iterator or_it = organ_link_map->begin();
		or_it != organ_link_map->end(); or_it++)
	{
		if (getPartByUUID(or_it->first) == nullptr)
		{
			debug_error("ERROR during body part linking: Part UUID %s was requested, but is not in part map!\n",
				or_it->first.c_str());
			return nullptr;
		}
		if (getPartByIID(or_it->second) == nullptr)
		{
			debug_error("ERROR during body part linking: Part IID %s was requested, but is not in part map!\n",
				or_it->second.c_str());
			return nullptr;
		}
		Part* temp = getPartByIID(or_it->second).get();
		Organ* connector = dynamic_cast<Organ*>(temp);
		if (connector == nullptr){
			debug_error("ERROR during body part linking: Casting from Part* to Organ* on Part %s failed!\n",
				or_it->second.c_str());
			return nullptr;
		}
		connector->addConnectedOrgan(or_it->first);
	}

	//Successfully parsed the body definition file!
	//Return the address of the newly created body part.
	return root_uuid;

	} catch (std::exception& e) {
		debug_error("ERROR: %s \n", e.what());
		return NULL;
	}
	catch (bdef_parse_error& pe) {
		debug_error("ERROR: %s \n", pe.what());
		return NULL;
	}

	return NULL;
}