Cleaned up code
This commit is contained in:
@@ -275,79 +275,19 @@ private:
|
||||
|
||||
public:
|
||||
static std::size_t GetTypeStride(std::string typeName);
|
||||
|
||||
static void WriteAttributeData(char* outData, const std::string fieldType, const std::map<std::string, std::string>& attributes)
|
||||
{
|
||||
if (fieldType == "Vector") {
|
||||
glm::vec3 vec;
|
||||
vec.x = boost::lexical_cast<float>(attributes.at("X"));
|
||||
vec.y = boost::lexical_cast<float>(attributes.at("Y"));
|
||||
vec.z = boost::lexical_cast<float>(attributes.at("Z"));
|
||||
memcpy(outData, reinterpret_cast<char*>(&vec), EntityFile::GetTypeStride(fieldType));
|
||||
} else if (fieldType == "Color") {
|
||||
glm::vec4 vec;
|
||||
vec.r = boost::lexical_cast<float>(attributes.at("R"));
|
||||
vec.g = boost::lexical_cast<float>(attributes.at("G"));
|
||||
vec.b = boost::lexical_cast<float>(attributes.at("B"));
|
||||
vec.a = boost::lexical_cast<float>(attributes.at("A"));
|
||||
memcpy(outData, reinterpret_cast<char*>(&vec), EntityFile::GetTypeStride(fieldType));
|
||||
} else if (fieldType == "Quaternion") {
|
||||
glm::quat q;
|
||||
q.x = boost::lexical_cast<float>(attributes.at("X"));
|
||||
q.y = boost::lexical_cast<float>(attributes.at("Y"));
|
||||
q.z = boost::lexical_cast<float>(attributes.at("Z"));
|
||||
q.w = boost::lexical_cast<float>(attributes.at("W"));
|
||||
memcpy(outData, reinterpret_cast<char*>(&q), EntityFile::GetTypeStride(fieldType));
|
||||
} else if (!attributes.empty()) {
|
||||
LOG_WARNING("%i attributes not handled by any type conversion!", attributes.size());
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteValueData(char* outData, const std::string fieldType, const char* valueData)
|
||||
{
|
||||
if (fieldType == "int") {
|
||||
int value = boost::lexical_cast<int>(valueData);
|
||||
memcpy(outData, reinterpret_cast<char*>(&value), EntityFile::GetTypeStride(fieldType));
|
||||
} else if (fieldType == "float") {
|
||||
float value = boost::lexical_cast<float>(valueData);
|
||||
memcpy(outData, reinterpret_cast<char*>(&value), EntityFile::GetTypeStride(fieldType));
|
||||
} else if (fieldType == "double") {
|
||||
double value = boost::lexical_cast<double>(valueData);
|
||||
memcpy(outData, reinterpret_cast<char*>(&value), EntityFile::GetTypeStride(fieldType));
|
||||
} else if (fieldType == "bool") {
|
||||
bool value = (valueData[0] == 't'); // Lazy bool evaluation
|
||||
memcpy(outData, reinterpret_cast<char*>(&value), EntityFile::GetTypeStride(fieldType));
|
||||
} else if (fieldType == "string") {
|
||||
new (outData) std::string(valueData);
|
||||
} else {
|
||||
LOG_WARNING("Unknown value data type: %s", fieldType.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Parse(const EntityFileHandler* handler);
|
||||
//const std::map<std::string, ::ComponentInfo>& ComponentInfo() const { return m_ComponentInfo; }
|
||||
//const std::vector<std::string>& EntityReferences() const { return m_EntityReferences; }
|
||||
static void WriteAttributeData(char* outData, const std::string fieldType, const std::map<std::string, std::string>& attributes);
|
||||
static void WriteValueData(char* outData, const std::string fieldType, const char* valueData);
|
||||
|
||||
xercesc::XMLGrammarPool* GrammarPool() const { return m_GrammarPool; }
|
||||
|
||||
void Parse(const EntityFileHandler* handler) const;
|
||||
|
||||
private:
|
||||
boost::filesystem::path m_FilePath;
|
||||
xercesc::XMLGrammarPool* m_GrammarPool;
|
||||
xercesc::SAX2XMLReader* m_SAX2XMLReader;
|
||||
//std::map<std::string, ::ComponentInfo> m_ComponentInfo;
|
||||
//std::vector<std::string> m_EntityReferences;
|
||||
static float getFloatAttribute(const xercesc::DOMElement* element, const char* attribute)
|
||||
{
|
||||
using namespace xercesc;
|
||||
XSValue::Status status;
|
||||
XSValue* val = XSValue::getActualValue(element->getAttribute(XS::ToXMLCh(attribute)), xercesc::XSValue::DataType::dt_double, status);
|
||||
if (val == nullptr) {
|
||||
LOG_ERROR("Element \"%s\" doesn't have an \"%s\" attribute!", ((std::string)XS::ToString(element->getTagName())).c_str(), attribute);
|
||||
return 0.f;
|
||||
} else {
|
||||
return static_cast<float>(val->fData.fValue.f_double);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -4,67 +4,20 @@
|
||||
class EntityFileParser
|
||||
{
|
||||
public:
|
||||
EntityFileParser(EntityFile* entityFile)
|
||||
: m_EntityFile(entityFile)
|
||||
{
|
||||
m_Handler.SetStartEntityCallback(std::bind(&EntityFileParser::onStartEntity, this, std::placeholders::_1, std::placeholders::_2));
|
||||
m_Handler.SetStartComponentCallback(std::bind(&EntityFileParser::onStartComponent, this, std::placeholders::_1, std::placeholders::_2));
|
||||
m_Handler.SetStartFieldCallback(std::bind(&EntityFileParser::onStartComponentField, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
|
||||
m_Handler.SetStartFieldDataCallback(std::bind(&EntityFileParser::onFieldData, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
|
||||
}
|
||||
EntityFileParser(const EntityFile* entityFile);
|
||||
|
||||
void MergeEntities(World* world)
|
||||
{
|
||||
m_World = world;
|
||||
m_EntityIDMapper[0] = 0;
|
||||
m_EntityFile->Parse(&m_Handler);
|
||||
}
|
||||
void MergeEntities(World* world);
|
||||
|
||||
private:
|
||||
EntityFile* m_EntityFile;
|
||||
const EntityFile* m_EntityFile;
|
||||
EntityFileHandler m_Handler;
|
||||
World* m_World = nullptr;
|
||||
// Maps EntityIDs local to the file to real IDs in the world
|
||||
// Maps EntityIDs local to the file to real IDs in the world after they've been
|
||||
// created in order to resolve parent-child relationships.
|
||||
std::map<EntityID, EntityID> m_EntityIDMapper;
|
||||
|
||||
void onStartEntity(EntityID entity, EntityID parent)
|
||||
{
|
||||
EntityID realParent = m_EntityIDMapper.at(parent);
|
||||
EntityID realEntity = m_World->CreateEntity(realParent);
|
||||
m_EntityIDMapper[entity] = realEntity;
|
||||
LOG_DEBUG("Created entity #%i (%i) with parent %i (%i)", entity, realEntity, parent, realParent);
|
||||
}
|
||||
|
||||
void onStartComponent(EntityID entity, std::string component)
|
||||
{
|
||||
EntityID realEntity = m_EntityIDMapper.at(entity);
|
||||
m_World->AttachComponent(entity, component);
|
||||
LOG_DEBUG("Attached component of type \"%s\" to entity #%i (%i)", component.c_str(), entity, realEntity);
|
||||
}
|
||||
|
||||
void onStartComponentField(EntityID entity, std::string componentType, std::string fieldName, std::map<std::string, std::string> attributes)
|
||||
{
|
||||
EntityID realEntity = m_EntityIDMapper.at(entity);
|
||||
ComponentWrapper component = m_World->GetComponent(realEntity, componentType);
|
||||
std::string fieldType = component.Info.FieldTypes.at(fieldName);
|
||||
|
||||
LOG_DEBUG("Field \"%s\" type \"%s\"", fieldName.c_str(), fieldType.c_str());
|
||||
LOG_DEBUG("Attributes:");
|
||||
for (auto& kv : attributes) {
|
||||
LOG_DEBUG("\t%s = %s", kv.first.c_str(), kv.second.c_str());
|
||||
}
|
||||
|
||||
char* data = component.Data + component.Info.FieldOffsets.at(fieldName);
|
||||
EntityFile::WriteAttributeData(data, fieldType, attributes);
|
||||
}
|
||||
|
||||
void onFieldData(EntityID entity, std::string componentType, std::string fieldName, const char* fieldData)
|
||||
{
|
||||
EntityID realEntity = m_EntityIDMapper.at(entity);
|
||||
ComponentWrapper component = m_World->GetComponent(realEntity, componentType);
|
||||
std::string fieldType = component.Info.FieldTypes.at(fieldName);
|
||||
|
||||
char* data = component.Data + component.Info.FieldOffsets.at(fieldName);
|
||||
EntityFile::WriteValueData(data, fieldType, fieldData);
|
||||
}
|
||||
void onStartEntity(EntityID entity, EntityID parent);
|
||||
void onStartComponent(EntityID entity, std::string component);
|
||||
void onStartComponentField(EntityID entity, std::string componentType, std::string fieldName, std::map<std::string, std::string> attributes);
|
||||
void onFieldData(EntityID entity, std::string componentType, std::string fieldName, const char* fieldData);
|
||||
};
|
||||
@@ -16,233 +16,16 @@
|
||||
class EntityFilePreprocessor
|
||||
{
|
||||
public:
|
||||
EntityFilePreprocessor(std::string path)
|
||||
: m_FilePath(path)
|
||||
{
|
||||
m_EntityFile = ResourceManager::Load<EntityFile>(path);
|
||||
EntityFileHandler handler;
|
||||
handler.SetStartComponentCallback(std::bind(&EntityFilePreprocessor::onStartComponent, this, std::placeholders::_1, std::placeholders::_2));
|
||||
m_EntityFile->Parse(&handler);
|
||||
EntityFilePreprocessor(const EntityFile* entityFile);
|
||||
|
||||
LOG_DEBUG("___ COMPONENT DEFINITIONS ___");
|
||||
for (auto& kv : m_ComponentCounts) {
|
||||
LOG_DEBUG("%s: %i", kv.first.c_str(), kv.second);
|
||||
}
|
||||
|
||||
parseComponentInfo();
|
||||
|
||||
for (auto& kv : m_ComponentInfo) {
|
||||
auto& info = kv.second;
|
||||
LOG_DEBUG("Component: %s (%s)", info.Name.c_str(), info.Meta.Annotation.c_str());
|
||||
LOG_DEBUG("Stride: %i", info.Meta.Stride);
|
||||
LOG_DEBUG("Allocation: %i", info.Meta.Allocation);
|
||||
for (auto& kv : info.FieldTypes) {
|
||||
LOG_DEBUG("\t%i\t%s %s", info.FieldOffsets[kv.first], kv.second.c_str(), kv.first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
parseDefaults();
|
||||
}
|
||||
|
||||
void RegisterComponents(World* world)
|
||||
{
|
||||
for (auto& kv : m_ComponentInfo) {
|
||||
world->RegisterComponent(kv.second);
|
||||
}
|
||||
}
|
||||
void RegisterComponents(World* world);
|
||||
|
||||
private:
|
||||
std::string m_FilePath;
|
||||
EntityFile* m_EntityFile;
|
||||
const EntityFile* m_EntityFile;
|
||||
std::map<std::string, unsigned int> m_ComponentCounts;
|
||||
std::map<std::string, ComponentInfo> m_ComponentInfo;
|
||||
|
||||
void onStartComponent(EntityID entity, std::string type)
|
||||
{
|
||||
//LOG_DEBUG("Component: %s", type.c_str());
|
||||
m_ComponentCounts[type]++;
|
||||
}
|
||||
|
||||
void parseComponentInfo()
|
||||
{
|
||||
using namespace xercesc;
|
||||
EntityFileXMLErrorHandler errorHandler;
|
||||
auto grammarPool = m_EntityFile->GrammarPool();
|
||||
bool whateverTheFuckThisIs;
|
||||
auto xsModel = grammarPool->getXSModel(whateverTheFuckThisIs);
|
||||
|
||||
// Find component xsd element declarations
|
||||
std::cout << "Enumerating components..." << std::endl;
|
||||
// <xs:element name="ComponentName">
|
||||
auto topLevelElements = xsModel->getComponents(XSConstants::ELEMENT_DECLARATION);
|
||||
for (unsigned int i = 0; i < topLevelElements->getLength(); ++i) {
|
||||
auto element = static_cast<XSElementDeclaration*>(topLevelElements->item(i));
|
||||
|
||||
std::string nameSpace = XS::ToString(element->getNamespace());
|
||||
if (nameSpace != "components") {
|
||||
continue;
|
||||
}
|
||||
|
||||
ComponentInfo compInfo;
|
||||
|
||||
// Name
|
||||
compInfo.Name = XS::ToString(element->getName());
|
||||
// Known allocation
|
||||
compInfo.Meta.Allocation = m_ComponentCounts[compInfo.Name];
|
||||
// Annotation
|
||||
auto componentAnnotation = element->getAnnotation();
|
||||
if (componentAnnotation != nullptr) {
|
||||
// Parse annotation XML
|
||||
char* annotationString = XMLString::transcode(componentAnnotation->getAnnotationString());
|
||||
MemBufInputSource annotationInput(reinterpret_cast<const XMLByte*>(annotationString), strlen(annotationString), "MemBuf: Annotation String");
|
||||
XercesDOMParser parser(nullptr, XMLPlatformUtils::fgMemoryManager, grammarPool);
|
||||
parser.setErrorHandler(&errorHandler);
|
||||
parser.parse(annotationInput);
|
||||
XMLString::release(&annotationString);
|
||||
auto doc = parser.getDocument();
|
||||
|
||||
// TODO: Add allocation estimations from external file on map-to-map basis
|
||||
// Add allocation estimation(s)
|
||||
//auto allocationTags = doc->getElementsByTagName(XSTR("meta:allocation"));
|
||||
//for (int i = 0; i < allocationTags->getLength(); ++i) {
|
||||
// auto allocation = dynamic_cast<DOMElement*>(allocationTags->item(i));
|
||||
// auto child = allocation->getFirstChild();
|
||||
// if (child == nullptr) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// XSValue::Status status;
|
||||
// XSValue* val = XSValue::getActualValue(child->getNodeValue(), XSValue::dt_integer, status);
|
||||
// compInfo.Meta.Allocation += val->fData.fValue.f_int;
|
||||
//}
|
||||
|
||||
// Save documentation string
|
||||
auto documentationTags = doc->getElementsByTagName(XS::ToXMLCh("xs:documentation"));
|
||||
if (documentationTags->getLength() != 0) {
|
||||
auto child = documentationTags->item(0)->getFirstChild();
|
||||
if (child != nullptr) {
|
||||
compInfo.Meta.Annotation = XS::ToString(child->getNodeValue());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_WARNING("Component is missing an annotation!");
|
||||
}
|
||||
|
||||
// <xs:complexType>
|
||||
auto typeDefinition = element->getTypeDefinition();
|
||||
if (typeDefinition->getTypeCategory() != XSTypeDefinition::COMPLEX_TYPE) {
|
||||
LOG_ERROR("Type definition wasn't COMPLEX_TYPE! Skipping.");
|
||||
continue;
|
||||
}
|
||||
auto complexTypeDefinition = dynamic_cast<XSComplexTypeDefinition*>(typeDefinition);
|
||||
|
||||
// <xs:all>
|
||||
auto modelGroupParticle = complexTypeDefinition->getParticle();
|
||||
if (modelGroupParticle->getTermType() != XSParticle::TERM_MODELGROUP) {
|
||||
LOG_ERROR("Model group particle wasn't TERM_MODELGROUP! Skipping.");
|
||||
continue;
|
||||
}
|
||||
auto modelGroup = modelGroupParticle->getModelGroupTerm();
|
||||
|
||||
// <xs:element...
|
||||
// <xs:attribute...
|
||||
unsigned int fieldOffset = 0;
|
||||
auto particles = modelGroup->getParticles();
|
||||
for (unsigned int i = 0; i < particles->size(); ++i) {
|
||||
auto particle = particles->elementAt(i);
|
||||
if (particle->getTermType() != XSParticle::TERM_ELEMENT) {
|
||||
LOG_ERROR("Particle wasn't TERM_ELEMENT! Skipping.");
|
||||
continue;
|
||||
}
|
||||
auto elementDeclaration = particle->getElementTerm();
|
||||
|
||||
std::string name = XS::ToString(elementDeclaration->getName());
|
||||
std::string type = XS::ToString(elementDeclaration->getTypeDefinition()->getName());
|
||||
|
||||
size_t stride = EntityFile::GetTypeStride(type);
|
||||
if (stride == 0) {
|
||||
std::cout << "Warning: Field \"" << name << "\" in component \"" << compInfo.Name << "\" uses unexpected field type \"" << type << "\". Skipping." << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
compInfo.FieldTypes[name] = type;
|
||||
compInfo.FieldOffsets[name] = fieldOffset;
|
||||
fieldOffset += stride;
|
||||
}
|
||||
|
||||
compInfo.Meta.Stride = fieldOffset;
|
||||
m_ComponentInfo[compInfo.Name] = compInfo;
|
||||
}
|
||||
}
|
||||
|
||||
void parseDefaults()
|
||||
{
|
||||
using namespace xercesc;
|
||||
|
||||
EntityFileXMLErrorHandler errorHandler;
|
||||
|
||||
for (auto& ci : m_ComponentInfo) {
|
||||
// Allocate memory for default values
|
||||
ci.second.Defaults = std::shared_ptr<char>(new char[ci.second.Meta.Stride]);
|
||||
memset(ci.second.Defaults.get(), 0, ci.second.Meta.Stride);
|
||||
|
||||
XercesDOMParser parser(nullptr, XMLPlatformUtils::fgMemoryManager);
|
||||
parser.setErrorHandler(&errorHandler);
|
||||
|
||||
std::string componentName = ci.first;
|
||||
LOG_DEBUG("Parsing defaults for component %s", componentName.c_str());
|
||||
boost::filesystem::path defaultsFile = "Schema/Components/" + componentName + ".xml";
|
||||
|
||||
parser.parse(defaultsFile.string().c_str());
|
||||
auto doc = parser.getDocument();
|
||||
if (doc == nullptr) {
|
||||
LOG_ERROR("%s not found! Skipping.", defaultsFile.string().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the node in the components namespace matching the component name
|
||||
std::string tagName = "c:" + componentName;
|
||||
auto rootNodes = doc->getElementsByTagName(XS::ToXMLCh(tagName));
|
||||
if (rootNodes->getLength() == 0) {
|
||||
LOG_ERROR("Couldn't find defaults for component \"%s\"! Skipping.", componentName.c_str());
|
||||
continue;
|
||||
}
|
||||
auto componentElement = dynamic_cast<DOMElement*>(rootNodes->item(0));
|
||||
|
||||
// Fill the default value buffer with values
|
||||
for (auto& field : ci.second.FieldOffsets) {
|
||||
std::string fieldName = field.first;
|
||||
auto fieldNodes = componentElement->getElementsByTagName(XS::ToXMLCh(fieldName));
|
||||
auto fieldNode = fieldNodes->item(0);
|
||||
if (fieldNode == nullptr) {
|
||||
LOG_ERROR("Defaults for component \"%s\" is missing field \"%s\"!", componentName.c_str(), fieldName.c_str());
|
||||
continue;
|
||||
}
|
||||
auto fieldElement = dynamic_cast<DOMElement*>(fieldNode);
|
||||
|
||||
std::string fieldType = ci.second.FieldTypes.at(fieldName);
|
||||
unsigned int fieldOffset = ci.second.FieldOffsets.at(fieldName);
|
||||
char* data = ci.second.Defaults.get() + fieldOffset;
|
||||
|
||||
// Handle potential field attributes
|
||||
if (fieldElement->hasAttributes()) {
|
||||
std::map<std::string, std::string> attributes;
|
||||
auto attributeMap = fieldElement->getAttributes();
|
||||
for (int i = 0; i < attributeMap->getLength(); ++i) {
|
||||
auto attribItem = attributeMap->item(i);
|
||||
attributes[XS::ToString(attribItem->getNodeName())] = XS::ToString(attribItem->getNodeValue());
|
||||
}
|
||||
EntityFile::WriteAttributeData(data, fieldType, attributes);
|
||||
}
|
||||
|
||||
// Handle potential field values
|
||||
auto childNode = fieldElement->getFirstChild();
|
||||
if (childNode != nullptr && childNode->getNodeType() == DOMNode::TEXT_NODE) {
|
||||
char* cstrValue = XMLString::transcode(childNode->getNodeValue());
|
||||
EntityFile::WriteValueData(data, fieldType, cstrValue);
|
||||
XMLString::release(&cstrValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void onStartComponent(EntityID entity, std::string type);
|
||||
void parseComponentInfo();
|
||||
void parseDefaults();
|
||||
};
|
||||
@@ -1,141 +0,0 @@
|
||||
#ifndef EntityXMLFile_h__
|
||||
#define EntityXMLFile_h__
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "../Common.h"
|
||||
#include "../GLM.h"
|
||||
#include <xercesc/dom/DOM.hpp>
|
||||
#include <xercesc/dom/DOMLSInput.hpp>
|
||||
#include <xercesc/dom/DOMElement.hpp>
|
||||
#include <xercesc/framework/Wrapper4InputSource.hpp>
|
||||
#include <xercesc/framework/LocalFileInputSource.hpp>
|
||||
#include <xercesc/framework/LocalFileFormatTarget.hpp>
|
||||
#include <xercesc/framework/MemBufFormatTarget.hpp>
|
||||
#include <xercesc/framework/MemBufInputSource.hpp>
|
||||
#include <xercesc/sax/HandlerBase.hpp>
|
||||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
#include <xercesc/util/XMLFloat.hpp>
|
||||
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
|
||||
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
|
||||
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
|
||||
#include <xercesc/framework/psvi/XSParticle.hpp>
|
||||
#include <xercesc/framework/psvi/XSModelGroup.hpp>
|
||||
#include <xercesc/framework/psvi/XSAnnotation.hpp>
|
||||
#include <xercesc/framework/psvi/XSValue.hpp>
|
||||
#include <xercesc/framework/XMLValidator.hpp>
|
||||
|
||||
#include "ResourceManager.h"
|
||||
#include "Entity.h"
|
||||
#include "ComponentInfo.h"
|
||||
class World;
|
||||
|
||||
class EntityPreprocessorXMLErrorHandler : public xercesc::DOMErrorHandler
|
||||
{
|
||||
public:
|
||||
bool handleError(const xercesc::DOMError &e) override
|
||||
{
|
||||
char* message = xercesc::XMLString::transcode(e.getMessage());
|
||||
std::cerr << "Preprocessor DOMError: " << message << std::endl;
|
||||
xercesc::XMLString::release(&message);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class EntityParserXMLErrorHandler : public xercesc::ErrorHandler
|
||||
{
|
||||
public:
|
||||
void warning(const xercesc::SAXParseException& e) override
|
||||
{
|
||||
reportParseException("Warning", e);
|
||||
}
|
||||
void error(const xercesc::SAXParseException& e) override
|
||||
{
|
||||
reportParseException("Error", e);
|
||||
}
|
||||
void fatalError(const xercesc::SAXParseException& e) override
|
||||
{
|
||||
reportParseException("FATAL ERROR", e);
|
||||
}
|
||||
void resetErrors() override { }
|
||||
|
||||
private:
|
||||
void reportParseException(std::string type, const xercesc::SAXParseException& e)
|
||||
{
|
||||
char* message = xercesc::XMLString::transcode(e.getMessage());
|
||||
char* systemID = xercesc::XMLString::transcode(e.getSystemId());
|
||||
std::cerr << systemID << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << std::endl;
|
||||
std::cerr << type << ": " << message << std::endl;
|
||||
xercesc::XMLString::release(&systemID);
|
||||
xercesc::XMLString::release(&message);
|
||||
}
|
||||
};
|
||||
|
||||
class XSTR
|
||||
{
|
||||
public:
|
||||
XSTR(const XMLCh* const xmlString)
|
||||
{
|
||||
m_AsChar = xercesc::XMLString::transcode(xmlString);
|
||||
}
|
||||
|
||||
XSTR(const char* normalString)
|
||||
{
|
||||
m_AsXMLCh = xercesc::XMLString::transcode(normalString);
|
||||
}
|
||||
|
||||
~XSTR()
|
||||
{
|
||||
if (m_AsChar != nullptr) {
|
||||
xercesc::XMLString::release(&m_AsChar);
|
||||
}
|
||||
if (m_AsXMLCh != nullptr) {
|
||||
xercesc::XMLString::release(&m_AsXMLCh);
|
||||
}
|
||||
}
|
||||
|
||||
operator const char*() const { return m_AsChar; }
|
||||
operator const XMLCh*() const { return m_AsXMLCh; }
|
||||
|
||||
private:
|
||||
char* m_AsChar = nullptr;
|
||||
XMLCh* m_AsXMLCh = nullptr;
|
||||
};
|
||||
|
||||
class EntityXMLFile : public Resource
|
||||
{
|
||||
friend class ResourceManager;
|
||||
|
||||
private:
|
||||
EntityXMLFile(std::string path);
|
||||
|
||||
public:
|
||||
~EntityXMLFile();
|
||||
|
||||
void PopulateWorld(World* world);
|
||||
|
||||
private:
|
||||
static unsigned int InstanceCount;
|
||||
|
||||
std::string m_EntityFile;
|
||||
xercesc::XMLGrammarPool* m_GrammarPool = nullptr;
|
||||
EntityParserXMLErrorHandler* m_ErrorHandler = nullptr;
|
||||
xercesc::XercesDOMParser* m_DOMParser = nullptr;
|
||||
xercesc::DOMDocument* m_DOMDocument = nullptr;
|
||||
std::map<std::string, ComponentInfo> m_ComponentInfo;
|
||||
|
||||
// Preprocesses the entity file to insert include-by-copy child entities
|
||||
// TODO: Make this work in memory instead of saving to file
|
||||
void preprocess(std::string inPath, std::string outPath);
|
||||
|
||||
void parseComponentInfo();
|
||||
void parseDefaults();
|
||||
void predictComponentAllocation();
|
||||
void parseEntityGraph(World* world, xercesc::DOMElement* parent, EntityID parentEntity);
|
||||
std::size_t getTypeStride(std::string typeName);
|
||||
float getFloatAttribute(const xercesc::DOMElement* element, const char* attribute) const;
|
||||
void writeData(const xercesc::DOMElement* element, std::string typeName, char* outData);
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user