Merge remote-tracking branch 'origin/master' into Sound

# Conflicts:
#	README.md
#	resources/Schema/Components.xsd
#	resources/Schema/Types/Entity.xsd
This commit is contained in:
stiffly
2016-01-12 14:50:10 +01:00
50 changed files with 2015 additions and 840 deletions
+9 -2
View File
@@ -12,9 +12,16 @@ struct ComponentInfo
unsigned int Stride = 0;
};
struct Field_t
{
std::string Type;
unsigned int Offset;
unsigned int Stride;
};
std::string Name;
std::unordered_map<std::string, std::string> FieldTypes;
std::unordered_map<std::string, unsigned int> FieldOffsets;
std::unordered_map<std::string, Field_t> Fields;
std::vector<const Field_t*> FieldsInOrder;
Meta_t Meta;
std::shared_ptr<char> Defaults = nullptr;
};
+4 -3
View File
@@ -21,7 +21,7 @@ struct ComponentWrapper
template <typename T>
T& Property(std::string name)
{
unsigned int offset = Info.FieldOffsets.at(name);
unsigned int offset = Info.Fields.at(name).Offset;
return *reinterpret_cast<T*>(&Data[offset]);
}
@@ -78,8 +78,9 @@ public:
void AddProperty(std::string fieldName, T defaultValue)
{
m_DefaultValues.push_back(defaultValue);
m_ComponentInfo.FieldTypes[fieldName] = typeid(T).name();
m_ComponentInfo.FieldOffsets[fieldName] = m_ComponentInfo.Meta.Stride;
m_ComponentInfo.Fields[fieldName].Name = typeid(T).name();
m_ComponentInfo.Fields[fieldName].Offset = m_ComponentInfo.Meta.Stride;
m_ComponentInfo.Fields[fieldName].Stride = sizeof(T);
m_ComponentInfo.Meta.Stride += sizeof(T);
}
+20
View File
@@ -0,0 +1,20 @@
#ifndef EPlayerDamage_h__
#define EPlayerDamage_h__
#include "EventBroker.h"
#include "../Core/Entity.h"
namespace Events
{
struct PlayerDamage : Event
{
double DamageAmount;
EntityID PlayerDamagedID;
//optional TypeOfDamage
std::string TypeOfDamage;
};
}
#endif
+20
View File
@@ -0,0 +1,20 @@
#ifndef EPlayerDeath_h__
#define EPlayerDeath_h__
#include "EventBroker.h"
#include "../Core/Entity.h"
namespace Events
{
struct PlayerDeath : Event
{
//KilledBy,KilledByWhat is optional for now. It might be used later in the playerlog-system
EntityID KilledBy;
EntityID PlayerID;
std::string KilledByWhat;
};
}
#endif
+18
View File
@@ -0,0 +1,18 @@
#ifndef EPlayerHealthPickup_h__
#define EPlayerHealthPickup_h__
#include "EventBroker.h"
#include "../Core/Entity.h"
namespace Events
{
struct PlayerHealthPickup : Event
{
double HealthAmount;
EntityID PlayerHealedID;
};
}
#endif
+1
View File
@@ -2,5 +2,6 @@
#define Entity_h__
typedef unsigned int EntityID;
const static unsigned int EntityID_Invalid = -1;
#endif
+293
View File
@@ -0,0 +1,293 @@
#ifndef EntityFile_h__
#define EntityFile_h__
#include <stack>
#include <boost/lexical_cast.hpp>
#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLChar.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/framework/XMLDocumentHandler.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/XMLGrammarPoolImpl.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMLSInput.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include "../GLM.h"
#include "Util/XercesString.h"
#include "ResourceManager.h"
#include "Entity.h"
#include "ComponentInfo.h"
class EntityFileHandler
{
friend class EntityFileSAXHandler;
public:
// @param EntityID The entity found
// @param EntityID The parent of the entity
typedef std::function<void(EntityID, EntityID, const std::string&)> OnStartEntityCallback;
void SetStartEntityCallback(OnStartEntityCallback c) { m_OnStartEntityCallback = c; }
// @param EntityID The entity the component corresponds to
// @param std::string Type name of the component
typedef std::function<void(EntityID, const std::string&)> OnStartComponentCallback;
void SetStartComponentCallback(OnStartComponentCallback c) { m_OnStartComponentCallback = c; }
// @param EntityID Entity
// @param std::string Component name
// @param std::string Field name
// @param std::map<std::string, std::string> Field attribute names and values
typedef std::function<void(EntityID, const std::string&, const std::string&, const std::map<std::string, std::string>&)> OnStartFieldCallback;
void SetStartFieldCallback(OnStartFieldCallback c) { m_OnStartFieldCallback = c; }
// @param EntityID Entity
// @param std::string Component name
// @param std::string Field name
// @param char* Field data
typedef std::function<void(EntityID, const std::string&, const std::string&, const char*)> OnStartFieldDataCallback;
void SetStartFieldDataCallback(OnStartFieldDataCallback c) { m_OnStartFieldDataCallback = c; }
private:
OnStartEntityCallback m_OnStartEntityCallback = nullptr;
OnStartComponentCallback m_OnStartComponentCallback = nullptr;
OnStartFieldCallback m_OnStartFieldCallback = nullptr;
OnStartFieldDataCallback m_OnStartFieldDataCallback = nullptr;
};
class EntityFileSAXHandler : public xercesc::DefaultHandler
{
public:
enum class State
{
Unknown,
Entity,
Component,
ComponentField
};
EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader)
: m_Handler(handler)
, m_Reader(reader)
{
// 0 is imaginary world entity
m_EntityStack.push(0);
m_StateStack.push(State::Unknown);
}
void startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) override
{
std::string name = XS::ToString(_localName);
if (m_StateStack.top() == State::Unknown || m_StateStack.top() == State::Entity) {
if (name == "Entity") {
m_StateStack.push(State::Entity);
onStartEntity(attrs);
return;
}
if (name == "EntityRef") {
onStartEntityRef(attrs);
return;
}
}
std::string uri = XS::ToString(_uri);
if (m_StateStack.top() == State::Entity) {
if (uri == "components") {
m_StateStack.push(State::Component);
onStartComponent(name);
return;
}
}
if (m_StateStack.top() == State::Component) {
m_StateStack.push(State::ComponentField);
onStartComponentField(name, attrs);
return;
}
}
void characters(const XMLCh* const chars, const XMLSize_t length) override
{
if (m_StateStack.top() == State::ComponentField) {
char* transcoded = xercesc::XMLString::transcode(chars);
onFieldData(transcoded);
}
}
void endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) override
{
std::string name = XS::ToString(_localName);
if (m_StateStack.top() == State::Entity) {
if (name == "Entity") {
m_StateStack.pop();
onEndEntity();
return;
}
}
std::string uri = XS::ToString(_uri);
if (m_StateStack.top() == State::Component) {
//if (uri == "components") {
m_StateStack.pop();
onEndComponent(name);
return;
//}
}
if (m_StateStack.top() == State::ComponentField) {
m_StateStack.pop();
onEndComponentField(name);
return;
}
}
void fatalError(const xercesc::SAXParseException& e)
{
XS::ToString s(e.getMessage());
LOG_ERROR("SAXParseException: %s", ((std::string)s).c_str());
//throw e;
}
private:
const EntityFileHandler* m_Handler;
xercesc::XMLGrammarPool* m_GrammarPool;
xercesc::SAX2XMLReader* m_Reader;
//State m_CurrentScope = State::Unknown;
std::stack<State> m_StateStack;
unsigned int m_NextEntityID = 0;
std::stack<EntityID> m_EntityStack;
std::string m_CurrentComponent;
std::string m_CurrentField;
std::map<std::string, std::string> m_CurrentAttributes;
void onStartEntity(const xercesc::Attributes& attrs)
{
EntityID parent = m_EntityStack.top();
if (m_Handler->m_OnStartEntityCallback) {
std::string name;
auto xName = attrs.getValue(XS::ToXMLCh("name"));
if (xName != nullptr) {
name = XS::ToString(xName);
}
m_Handler->m_OnStartEntityCallback(m_NextEntityID, parent, name);
}
m_EntityStack.push(m_NextEntityID);
m_NextEntityID++;
}
void onEndEntity()
{
m_EntityStack.pop();
}
void onStartEntityRef(const xercesc::Attributes& attrs)
{
std::string path = XS::ToString(attrs.getValue(XS::ToXMLCh("file")));
xercesc::SAX2XMLReader* parser = xercesc::XMLReaderFactory::createXMLReader();
parser->setContentHandler(this);
parser->setErrorHandler(this);
parser->parse(path.c_str());
delete parser;
}
void onStartComponent(const std::string& name)
{
//LOG_DEBUG(" Component: %s", name.c_str());
m_CurrentComponent = name;
if (m_Handler->m_OnStartComponentCallback) {
m_Handler->m_OnStartComponentCallback(m_EntityStack.top(), name);
}
}
void onEndComponent(const std::string& name) { }
void onStartComponentField(const std::string& field, const xercesc::Attributes& attrs)
{
//LOG_DEBUG(" Field: %s", field.c_str());
m_CurrentField = field;
m_CurrentAttributes.clear();
for (int i = 0; i < attrs.getLength(); i++) {
auto name = attrs.getQName(i);
auto value = attrs.getValue(name);
//LOG_DEBUG(" %s = %s", (char*)XS::ToString(name), (char*)XS::ToString(value));
m_CurrentAttributes[XS::ToString(name).operator std::string()] = XS::ToString(value).operator std::string();
}
if (m_Handler->m_OnStartFieldCallback) {
m_Handler->m_OnStartFieldCallback(m_EntityStack.top(), m_CurrentComponent, field, m_CurrentAttributes);
}
}
void onEndComponentField(const std::string& field) { }
void onFieldData(char* data)
{
//LOG_DEBUG(" Data: %s", data);
if (m_Handler->m_OnStartFieldDataCallback) {
m_Handler->m_OnStartFieldDataCallback(m_EntityStack.top(), m_CurrentComponent, m_CurrentField, data);
}
xercesc::XMLString::release(&data);
}
};
class EntityFileXMLErrorHandler : 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 EntityFile : public Resource
{
friend class ResourceManager;
private:
EntityFile(boost::filesystem::path path);
~EntityFile();
public:
static std::size_t GetTypeStride(std::string typeName);
static void WriteAttributeData(char* outData, const ComponentInfo::Field_t& field, const std::map<std::string, std::string>& attributes);
static void WriteValueData(char* outData, const ComponentInfo::Field_t& field, 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;
};
#endif
+28
View File
@@ -0,0 +1,28 @@
#ifndef EntityFileParser_h__
#define EntityFileParser_h__
#include "EntityFile.h"
#include "World.h"
class EntityFileParser
{
public:
EntityFileParser(const EntityFile* entityFile);
void MergeEntities(World* world);
private:
const EntityFile* m_EntityFile;
EntityFileHandler m_Handler;
World* m_World = nullptr;
// 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, const std::string& name);
void onStartComponent(EntityID entity, const std::string& component);
void onStartComponentField(EntityID entity, const std::string& componentType, const std::string& fieldName, const std::map<std::string, std::string>& attributes);
void onFieldData(EntityID entity, const std::string& componentType, const std::string& fieldName, const char* fieldData);
};
#endif
@@ -0,0 +1,36 @@
#ifndef EntityFilePreprocessor_h__
#define EntityFilePreprocessor_h__
#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/MemBufFormatTarget.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include "Util/XercesString.h"
#include "ResourceManager.h"
#include "World.h"
#include "EntityFile.h"
class EntityFilePreprocessor
{
public:
EntityFilePreprocessor(const EntityFile* entityFile);
void RegisterComponents(World* world);
private:
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);
void parseComponentInfo();
void parseDefaults();
};
#endif
+39
View File
@@ -0,0 +1,39 @@
#ifndef EntityFileWriter_h__
#define EntityFileWriter_h__
#include <boost/filesystem.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include "Util/XercesString.h"
#include "EntityFile.h"
#include "World.h"
class EntityFileWriter
{
public:
EntityFileWriter(boost::filesystem::path file)
: m_FilePath(file)
{
using namespace xercesc;
m_DOMImplementation = DOMImplementationRegistry::getDOMImplementation(XS::ToXMLCh("LS"));
m_DOMLSSerializer = static_cast<DOMImplementationLS*>(m_DOMImplementation)->createLSSerializer();
m_DOMLSSerializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTDiscardDefaultContent, true);
m_DOMLSSerializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
}
void WriteWorld(World* world);
void WriteEntity(World* world, EntityID entity);
private:
boost::filesystem::path m_FilePath;
xercesc::DOMImplementation* m_DOMImplementation;
xercesc::DOMLSSerializer* m_DOMLSSerializer;
void appendEntityChildren(xercesc::DOMElement* parentElement, const World* world, EntityID entity);
void appentEntityComponents(xercesc::DOMElement* parentElemetn, const World* world, EntityID entity);
};
#endif
-141
View File
@@ -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
+40 -27
View File
@@ -14,21 +14,28 @@ public:
{ }
~SystemPipeline()
{
for (auto& pair : m_Systems) {
delete pair.second;
for (UnorderedSystems& group : m_OrderedSystemGroups) {
for (auto& pair : group.Systems) {
delete pair.second;
}
}
}
template <typename T, typename... Arguments>
void AddSystem(Arguments... args)
//All systems with orderlevel 0 will be updated first, then 1, 2, etc.
void AddSystem(int updateOrderLevel, Arguments... args)
{
if (updateOrderLevel + 1 > m_OrderedSystemGroups.size()) {
m_OrderedSystemGroups.resize(updateOrderLevel + 1);
}
UnorderedSystems& group = m_OrderedSystemGroups[updateOrderLevel];
System* system = new T(m_EventBroker, args...);
m_Systems[typeid(T).name()] = system;
group.Systems[typeid(T).name()] = system;
if (std::is_base_of<PureSystem, T>::value) {
PureSystem* pureSystem = static_cast<PureSystem*>(system);
if (!pureSystem->m_ComponentType.empty()) {
m_PureSystems[pureSystem->m_ComponentType].push_back(pureSystem);
group.PureSystems[pureSystem->m_ComponentType].push_back(pureSystem);
} else {
LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name());
}
@@ -36,41 +43,47 @@ public:
if (std::is_base_of<ImpureSystem, T>::value) {
ImpureSystem* impureSystem = static_cast<ImpureSystem*>(system);
m_ImpureSystems.push_back(impureSystem);
group.ImpureSystems.push_back(impureSystem);
}
}
void Update(World* world, double dt)
{
// Process events
for (auto& pair : m_Systems) {
m_EventBroker->Process(pair.first);
}
// Update
for (auto& pair : m_PureSystems) {
const std::string& componentName = pair.first;
auto& systems = pair.second;
const ComponentPool* pool = world->GetComponents(componentName);
if (pool == nullptr) {
continue;
for (UnorderedSystems& group : m_OrderedSystemGroups) {
// Process events
for (auto& pair : group.Systems) {
m_EventBroker->Process(pair.first);
}
for (auto& component : *pool) {
for (auto& system : systems) {
system->UpdateComponent(world, component, dt);
// Update
for (auto& pair : group.PureSystems) {
const std::string& componentName = pair.first;
auto& systems = pair.second;
const ComponentPool* pool = world->GetComponents(componentName);
if (pool == nullptr) {
continue;
}
for (auto& component : *pool) {
for (auto& system : systems) {
system->UpdateComponent(world, component, dt);
}
}
}
}
for (auto& system : m_ImpureSystems) {
system->Update(world, dt);
for (auto& system : group.ImpureSystems) {
system->Update(world, dt);
}
}
}
private:
EventBroker* m_EventBroker;
std::map<std::string, System*> m_Systems;
std::map<std::string, std::vector<PureSystem*>> m_PureSystems;
std::vector<ImpureSystem*> m_ImpureSystems;
struct UnorderedSystems
{
std::map<std::string, System*> Systems;
std::map<std::string, std::vector<PureSystem*>> PureSystems;
std::vector<ImpureSystem*> ImpureSystems;
};
std::vector<UnorderedSystems> m_OrderedSystemGroups;
};
#endif
+46
View File
@@ -0,0 +1,46 @@
#ifndef Util_XercesString_h__
#define Util_XercesString_h__
#include <string>
#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/XMLString.hpp>
namespace XS
{
class ToString
{
public:
ToString(const XMLCh* const str) { m_AsChar = xercesc::XMLString::transcode(str); }
~ToString()
{
if (m_AsChar != nullptr) {
xercesc::XMLString::release(&m_AsChar);
}
}
operator std::string() const { return std::string(m_AsChar); }
private:
char* m_AsChar = nullptr;
};
class ToXMLCh
{
public:
ToXMLCh(const std::string str) { m_Transcoded = xercesc::XMLString::transcode(str.c_str()); }
ToXMLCh(const char* str) { m_Transcoded = xercesc::XMLString::transcode(str); }
~ToXMLCh()
{
if (m_Transcoded != nullptr) {
xercesc::XMLString::release(&m_Transcoded);
}
}
operator const XMLCh*() const { return m_Transcoded; }
private:
XMLCh* m_Transcoded = nullptr;
};
}
#endif
+9 -3
View File
@@ -16,13 +16,14 @@ public:
EntityID CreateEntity(EntityID parent = 0);
// Delete entity and all components within
void DeleteEntity(EntityID entity);
// Check if an entity exists
bool ValidEntity(EntityID entity) const;
// Register a component type and allocate space for it
void RegisterComponent(ComponentInfo& ci);
// Attach a component to an entity and fill it with default values
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
// Check if an entity has a component
bool HasComponent(EntityID entity, std::string componentType);
bool HasComponent(EntityID entity, std::string componentType) const;
// Get a component of an entity
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
// Delete a component off an entity
@@ -37,14 +38,19 @@ public:
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
// Get the entity children map
const std::unordered_multimap<EntityID, EntityID>& GetEntityChildren() const { return m_EntityChildren; }
// Set the textual name of an entity
void SetName(EntityID entity, const std::string& name);
// Get the textual name of an entity
std::string GetName(EntityID entity) const;
private:
EntityID m_CurrentEntityID = 1;
EntityID m_CurrentEntityID = 0;
std::unordered_map<EntityID, EntityID> m_EntityParents;
// TODO: This should be a more effective structure
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
std::unordered_map<std::string, ComponentPool*> m_ComponentPools;
std::unordered_map<EntityID, std::string> m_EntityNames;
EntityID generateEntityID();
};
+25 -10
View File
@@ -1,6 +1,7 @@
#include <imgui/imgui.h>
#include <glm/gtx/common.hpp>
#include <boost/filesystem/path.hpp>
#include <nativefiledialog/nfd.h>
#include "../Core/System.h"
#include "../Core/EMousePress.h"
#include "../Core/EMouseRelease.h"
@@ -11,6 +12,9 @@
#include "../Rendering/EPicking.h"
#include "../Core/EFileDropped.h"
#include "../Rendering/RenderQueueFactory.h"
#include "../Core/EntityFilePreprocessor.h"
#include "../Core/EntityFileParser.h"
#include "../Core/EntityFileWriter.h"
class EditorSystem : public ImpureSystem
{
@@ -25,6 +29,8 @@ private:
bool m_Enabled;
bool m_Visible;
boost::filesystem::path m_DefaultEntityDir;
boost::filesystem::path m_CurrentFile;
std::vector<glm::vec2> m_PickingQueue;
enum class WidgetMode
@@ -41,22 +47,26 @@ private:
Global
} m_WidgetSpace = WidgetSpace::Global;
EntityID m_Widget = 0;
EntityID m_WidgetX = 0;
EntityID m_WidgetPlaneX = 0;
EntityID m_WidgetY = 0;
EntityID m_WidgetPlaneY = 0;
EntityID m_WidgetZ = 0;
EntityID m_WidgetPlaneZ = 0;
EntityID m_WidgetOrigin = 0;
EntityID m_Widget = EntityID_Invalid;
EntityID m_WidgetX = EntityID_Invalid;
EntityID m_WidgetPlaneX = EntityID_Invalid;
EntityID m_WidgetY = EntityID_Invalid;
EntityID m_WidgetPlaneY = EntityID_Invalid;
EntityID m_WidgetZ = EntityID_Invalid;
EntityID m_WidgetPlaneZ = EntityID_Invalid;
EntityID m_WidgetOrigin = EntityID_Invalid;
glm::vec3 m_WidgetCurrentAxis;
float m_WidgetPickingDepth = 0.f;
EntityID m_Selection = 0;
EntityID m_LastSelection = 0;
EntityID m_Selection = EntityID_Invalid;
EntityID m_LastSelection = EntityID_Invalid;
EntityID m_UIDraggingEntity = EntityID_Invalid;
glm::vec3 m_Position;
std::string m_LastDroppedFile;
static boost::filesystem::path openDialog(boost::filesystem::path defaultPath);
static boost::filesystem::path saveDialog(boost::filesystem::path defaultPath);
EventRelay<EditorSystem, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
EventRelay<EditorSystem, Events::MouseRelease> m_EMouseRelease;
@@ -70,10 +80,15 @@ private:
EventRelay<EditorSystem, Events::FileDropped> m_EFileDropped;
bool OnFileDropped(const Events::FileDropped& e);
void createWidget();
void updateWidget();
void setWidgetMode(WidgetMode newMode);
void setWidgetSpace(WidgetSpace space);
void drawUI(World* world, double dt);
bool createDeleteButton(std::string componentType);
bool createEntityNode(World* world, EntityID entity);
void changeParent(EntityID entity, EntityID newParent);
void fileImport(World* world);
void fileSave(World* world);
void fileSaveAs(World* world);
};
+1 -1
View File
@@ -51,7 +51,7 @@ public:
if (it != PickingColorsToEntity->end()) {
pickData.Entity = it->second;
} else {
pickData.Entity = 0;
pickData.Entity = EntityID_Invalid;
}
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix);