Commit 42f78272 authored by nanahira's avatar nanahira

missing files

parent d4ecb00c
#include "CXMLNode.h"
CXMLNODETYPE CXMLNode::getType() { return type; }
void CXMLNode::setType(CXMLNODETYPE newtype) { type = newtype; }
void CXMLNode::setName(const wchar_t* newname) { name = newname; }
const wchar_t* CXMLNode::getName() { return name.c_str(); }
CXMLNode *CXMLNode::getThis() { return this; }
void CXMLNode::setValue(const wchar_t* newvalue) {
value = newvalue;
}
CXMLNode *CXMLNode::getParent() {
return parent;
}
void CXMLNode::setParent(CXMLNode *newparent) {
parent = newparent;
}
/*
bool CXMLNode::getValueAsBool() {
if(!value.size()) return false;
if(value.equals_ignore_case((core::stringw)"true")) return true;
return false;
}
s32 CXMLNode::getValueAsInt() {
if(!value.size()) return 0;
return _wtoi(value.c_str());
}
const wchar_t* CXMLNode::getValueAsCStr() {
if(!value.size()) return false;
return value.c_str();
}
*/
/*
u16 CXMLNode::getChildCount() {
return children.getSize();
}
irr::core::list<CXMLNode*>::Iterator CXMLNode::getFirstChild() {
//if(children.empty()) return 0;
return children.begin();
}
irr::core::list<CXMLNode*>::Iterator CXMLNode::getLastChild() {
//if(children.empty()) return 0;
return children.getLast();
}
*/
const wchar_t* CXMLNode::getValue() {
return value.c_str();
}
void CXMLNode::addChild(CXMLNode *newchild) {
children.push_back(newchild);
}
void CXMLNode::drop() {
if(children.getSize() != 0) {
core::list<CXMLNode*>::Iterator it;
for( it = children.begin(); it != children.end(); it++ ) {
( *it )->drop();
}
children.clear();
}
}
CXMLNode *CXMLNode::findChildByName(const wchar_t *name) {
core::list<CXMLNode*>::Iterator it;
core::stringw tmp;
CXMLNode *node = NULL;
tmp = name;
for( it = children.begin(); it != children.end(); it++ ) {
if(tmp.equals_ignore_case((*it)->getName())) {
node = (*it);
break;
}
}
return node;
}
core::array<const wchar_t*> *CXMLNode::listChildrenByType(CXMLNODETYPE nodetype) {
core::array<const wchar_t*> *ret = new core::array<const wchar_t*>;
//core::stringw construct = L"";
core::list<CXMLNode*>::Iterator it;
for( it = children.begin(); it != children.end(); it++ ) {
if((*it)->getType() == nodetype) {
ret->push_front((*it)->getName());
}
}
return ret;
}
core::array<const wchar_t*> *CXMLNode::listNonNodeChildren() {
return listChildrenByType(CXMLNODETYPE_VALUE);
}
core::array<const wchar_t*> *CXMLNode::listNodeChildren() {
return listChildrenByType(CXMLNODETYPE_NODE);
}
void CXMLNode::populateTreeView(irr::gui::IGUITreeViewNode *node) {
irr::gui::IGUITreeViewNode *myNode;
irr::core::stringw myText;
core::list<CXMLNode*>::Iterator it;
// If I'm a value, I have nothing to add, my parent will do that
if(type == CXMLNODETYPE_VALUE) return;
// So I'm a node, if im not the toplevel node, write me
if(parent != NULL) {
//myText = L"(Key) ";
myText += getName();
myNode = node->addChildBack(myText.c_str());
}
else
myNode = node;
// If I dont have children, I'm done
if(children.empty()) return;
// setup my children
for( it = children.begin(); it != children.end(); it++ ) {
switch((*it)->getType()) {
case CXMLNODETYPE_NODE :
myText = L"";
myText += (core::stringw)(*it)->getName();
(*it)->populateTreeView(myNode);
break;
case CXMLNODETYPE_VALUE :
myText = L"";
myText += (core::stringw)(*it)->getName();
myText += L":";
myText += (core::stringw)(*it)->getValue();
myNode->addChildBack(myText.c_str());
}
}
}
void CXMLNode::writeOut(io::IXMLWriter* xml) {
core::array<core::stringw> names;
core::array<core::stringw> values;
core::list<CXMLNode*>::Iterator it;
bool nodeChildren = false;
// If I'm a value, I have nothing to write, I'll be written by my parent
if(type == CXMLNODETYPE_VALUE) return;
// If I'm a node with no values, which also means no children write as empty and return
if(children.empty()) {
xml->writeElement(name.c_str(),true);
xml->writeLineBreak();
return;
}
// Need to figure out myself first
for( it = children.begin(); it != children.end(); it++ ) {
// cache all my values for writing, and set a flag if I have node children, ie non empty
switch((*it)->getType()) {
case CXMLNODETYPE_VALUE:
names.push_front((core::stringw)(*it)->getName());
values.push_front((core::stringw)(*it)->getValue());
break;
case CXMLNODETYPE_NODE:
nodeChildren = true;
}
}
// At this point I just need to write myself
xml->writeElement(name.c_str(),nodeChildren?false:true,names,values);
xml->writeLineBreak();
// Now I need to see if I have to tell my node children to write
if(!nodeChildren) return;
for( it = children.begin(); it != children.end(); it++ ) {
// If I have a node child, tell it to write, recursion made easy!
if((*it)->getType() == CXMLNODETYPE_NODE) {
(*it)->writeOut(xml);
}
}
xml->writeClosingTag(name.c_str());
xml->writeLineBreak();
}
\ No newline at end of file
// Madoc 05/09
#ifndef __C_XMLNODE_H_INCLUDED__
#define __C_XMLNODE_H_INCLUDED__
#include <irrlicht.h>
using namespace irr;
enum CXMLNODETYPE {
CXMLNODETYPE_VALUE,
CXMLNODETYPE_NODE,
//CXMLNODETYPE_COMMENT
};
class CXMLNode {
public :
/* Decided to move this up to the registry object, reduce mem use.
s32 getValueAsInt();
const wchar_t* getValueAsCStr();
bool getValueAsBool();
*/
CXMLNODETYPE getType();
const wchar_t* getName();
const wchar_t* getValue();
void setType(CXMLNODETYPE newtype);
void setName(const wchar_t* newname);
void setValue(const wchar_t* newvalue);
void addChild(CXMLNode *newchild);
void writeOut(irr::io::IXMLWriter* xml);
void populateTreeView(irr::gui::IGUITreeViewNode *node);
//u16 getChildCount();
void drop();
/*
irr::core::list<CXMLNode*>::Iterator getFirstChild();
// get last is not get end point, this causes problems with iterators
// Screw it, I'll keep all pointers internal
irr::core::list<CXMLNode*>::Iterator getLastChild();
*/
// Careful with these, mem leak waiting to happen
// Maby I should steal IReferenceCounted from irrlicht, would at
// least give me autodetection of mem leaks
core::array<const wchar_t *> *listNonNodeChildren();
core::array<const wchar_t *> *listNodeChildren();
CXMLNode *getThis();
CXMLNode *findChildByName(const wchar_t *name);
CXMLNode *getParent();
void setParent(CXMLNode *newparent);
private :
CXMLNode *parent;
irr::core::stringw value;
irr::core::stringw name;
CXMLNODETYPE type;
irr::core::list<CXMLNode*> children;
irr::core::array<const wchar_t *> *listChildrenByType(CXMLNODETYPE nodetype);
};
#endif
#include "CXMLRegistry.h"
#ifndef _WIN32
inline int _wtoi(const wchar_t * str){
return (int)wcstol(str, 0, 10);
}
#endif
CXMLRegistry::CXMLRegistry(io::IFileSystem *fsys) {
fileSystem = fsys;
fileSystem->grab();
registry = NULL;
}
CXMLRegistry::~CXMLRegistry() {
if(registry != NULL) registry->drop();
fileSystem->drop();
}
bool CXMLRegistry::isTopLevelNode(const wchar_t *node) {
if(registry->findChildByName(node)) return true;
else return false;
}
CXMLNode *CXMLRegistry::resolveContext(const wchar_t* context) {
core::stringw sContext;
CXMLNode *currentNode;
u16 start;
s16 end;
if(!context) return currentContext;
sContext = context;
if(sContext.size() == 0) return 0;
// Make sure the context ends in a /
if(sContext.lastChar() != L'/')
sContext += L'/';
start = 0;
end = sContext.findFirst('/');
// Theres no values in the top level nodes
if(end == -1) return 0;
currentNode = registry;
while(end != -1) {
currentNode = currentNode->findChildByName(sContext.subString(start,end-start).c_str());
if(currentNode == NULL) return NULL;
start = end+1;
end = sContext.findNext('/',start);
}
return currentNode;
}
void CXMLRegistry::setContext(const wchar_t *context) { currentContext = resolveContext(context); }
const wchar_t *CXMLRegistry::convertBoolToText(bool boolval) {
if(boolval) return L"true";
else return L"false";
}
bool CXMLRegistry::convertTextToBool(const wchar_t *textval) {
if(((core::stringw)textval).equals_ignore_case(L"true")) return true;
return false;
}
bool CXMLRegistry::setValue(const wchar_t *index, bool boolval, const wchar_t *context) {
return setValue(index,convertBoolToText(boolval),context);
}
bool CXMLRegistry::setValue(const wchar_t *index, u16 intval, const wchar_t *context) {
return setValue(index,((core::stringw)intval).c_str(),context);
}
bool CXMLRegistry::setValue(const wchar_t *index, const wchar_t * txtval, const wchar_t *context) {
CXMLNode *targetNode;
targetNode = resolveContext(context);
if(!targetNode) return false;
targetNode = targetNode->findChildByName(index);
if(!targetNode) return false;
targetNode->setValue(txtval);
return true;
}
bool CXMLRegistry::populateTreeView(irr::gui::IGUITreeView *control, const wchar_t *context) {
CXMLNode *targetNode = NULL;
if(context == 0)
targetNode = registry;
else
targetNode = resolveContext(context);
if(!targetNode) return false;
targetNode->populateTreeView(control->getRoot());
return true;
}
bool CXMLRegistry::getValueAsBool(const wchar_t *index, const wchar_t *context) {
return convertTextToBool(getValueAsCStr(index,context));
}
// little more robust
u16 CXMLRegistry::getValueAsInt(const wchar_t *index, const wchar_t *context) {
core::stringw tmp = getValueAsCStr(index,context);
if(tmp.equals_ignore_case("")) return 0;
else return _wtoi(tmp.c_str());
}
core::array<const wchar_t*>* CXMLRegistry::listNonNodeChildren(const wchar_t *node,const wchar_t *context) {
CXMLNode *targetNode;
targetNode = resolveContext(context);
if(!targetNode) return 0;
return targetNode->listNonNodeChildren();
}
core::array<const wchar_t*>* CXMLRegistry::listNodeChildren(const wchar_t *node,const wchar_t *context) {
CXMLNode *targetNode;
targetNode = resolveContext(context);
if(!targetNode) return 0;
return targetNode->listNodeChildren();
}
//BROKEN
/*
const irr::c8 *CXMLRegistry::getValueAsCharCStr(const wchar_t *index, const wchar_t *context) {
irr::core::stringc temp;
temp = getValueAsCStr(index,context);
return (const irr::c8 *)temp.c_str();
}
*/
const wchar_t *CXMLRegistry::getValueAsCStr(const wchar_t *index, const wchar_t *context) {
CXMLNode *targetNode;
targetNode = resolveContext(context);
if(!targetNode) return 0;
targetNode = targetNode->findChildByName(index);
if(!targetNode) return 0;
return targetNode->getValue();
}
irr::core::rect<u32> CXMLRegistry::getValueAsRect(const wchar_t *context) {
CXMLNode *targetNode = resolveContext(context);
irr::u32 tx,ty,bx,by;
if(!targetNode) return irr::core::rect<u32>(0,0,0,0);
tx = _wtoi(targetNode->findChildByName(L"tlx")->getValue());
ty = _wtoi(targetNode->findChildByName(L"tly")->getValue());
bx = _wtoi(targetNode->findChildByName(L"brx")->getValue());
by = _wtoi(targetNode->findChildByName(L"bry")->getValue());
// Hrm what to return on err, cant return null, 0,0,0,0 might be a real loc
// Its u32, maby some HUGE value? maxint?
// Still takes out a value but its less likely
if(!tx || !ty || !bx || !by) return irr::core::rect<u32>(0,0,0,0);
else return irr::core::rect<u32>(tx,ty,bx,by);
}
// Made more robust
irr::video::SColor CXMLRegistry::getValueAsColor(const wchar_t *context) {
CXMLNode *targetNode = resolveContext(context);
if(!targetNode) return NULL;
irr::u32 r,g,b,a;
irr::core::stringw tmp;
tmp = targetNode->findChildByName(L"r")->getValue();
if(tmp.size()) r = _wtoi(tmp.c_str());
tmp = targetNode->findChildByName(L"g")->getValue();
if(tmp.size()) g = _wtoi(tmp.c_str());
tmp = targetNode->findChildByName(L"b")->getValue();
if(tmp.size()) b = _wtoi(tmp.c_str());
tmp = targetNode->findChildByName(L"a")->getValue();
if(tmp.size()) a = _wtoi(tmp.c_str());
return irr::video::SColor(a,r,g,b);
}
bool CXMLRegistry::writeFile(const irr::c8 *fname,const c8 *path) {
io::IXMLWriter* xml;
CXMLNode *currentnode = 0;
core::stringw wstmp;
core::stringc fileName;
wstmp = fname;
currentnode = registry->findChildByName(wstmp.c_str());
if(!currentnode) return false;
fileName = path;
fileName += fname;
fileName += ".xml";
xml = fileSystem->createXMLWriter(fileName.c_str());
xml->writeXMLHeader();
currentnode->writeOut(xml);
// Get rid of double top level end tag
//xml->writeClosingTag(currentnode->getName());
//xml->writeLineBreak();
//if(xml) xml->drop();
delete xml;
return true;
}
// check current folder, if there isnt anything in current, use default
const c8 *CXMLRegistry::resolveConfigPath(const c8 *fname) {
core::string <c8> filename;
bool useCurrent = true;
filename = "config/current/";
filename += fname;
filename += ".xml";
if(!fileSystem->existFile(filename.c_str())) {
useCurrent = false;
}
return useCurrent?"config/current/":"config/defaults/";
}
bool CXMLRegistry::loadConfigFile(const c8 *fname) {
return loadFile(fname, resolveConfigPath(fname));
}
bool CXMLRegistry::writeConfigFile(const c8 *fname) {
return writeFile(fname,"config/current/");
}
// This is tricky, we have to keep track of which nodes are 'open'
bool CXMLRegistry::loadFile(const c8 *fname, const c8 *path) {
io::IXMLReader* xml;
CXMLNode *currentNode = 0;
CXMLNode *topNode = 0;
CXMLNode *currentParent;
core::string <c8> filename;
filename = path;
filename += fname;
// If it dosnt end in .xml add it
if(!filename.subString(filename.size()-4,4).equals_ignore_case(".xml"))
filename += ".xml";
xml = fileSystem->createXMLReader(filename.c_str());
if(!registry) {
registry = new CXMLNode;
registry->setName(L"TopLevelNode");
registry->setType(CXMLNODETYPE_NODE);
}
while(xml && xml->read()) {
CXMLNode *newNode = 0;
switch(xml->getNodeType()) {
case io::EXN_ELEMENT :
u16 i;
newNode = new CXMLNode;
newNode->setName(xml->getNodeName());
newNode->setType(CXMLNODETYPE_NODE);
if(!topNode) {
newNode->setParent(NULL);
registry->addChild(newNode);
topNode = newNode;
currentParent = newNode;
}
else {
newNode->setParent(currentParent);
currentParent->addChild(newNode);
if(!xml->isEmptyElement())
currentParent = newNode;
}
currentNode = newNode;
i = xml->getAttributeCount();
while(i--) {
newNode = new CXMLNode;
newNode->setName(xml->getAttributeName(i));
newNode->setType(CXMLNODETYPE_VALUE);
newNode->setValue(xml->getAttributeValue(i));
currentNode->addChild(newNode);
}
break;
case io::EXN_ELEMENT_END :
// NEVER go back further then the topNode
// Even if the XML is screwed up
if(currentParent->getParent() != NULL)
currentParent = currentParent->getParent();
break;
/*
case io::EXN_COMMENT :
newNode = new CXMLNode;
newNode->setType(CXMLNODETYPE_COMMENT);
//newNode->setValue(xml->getNodeType
currentNode->addChild(newNode);
break;
*/
}
}
//if(xml) xml->drop();
// Documentation says delete not drop
delete xml;
// To support loading multiple files or 'hives' have to
// see if this load ADDED any to decide succcessful or not
if(topNode == 0) return false;
return true;
}
\ No newline at end of file
// Madoc 05/09
#ifndef __C_XMLREGISTRY_H_INCLUDED__
#define __C_XMLREGISTRY_H_INCLUDED__
#include <irrlicht.h>
using namespace irr;
#include "CXMLNode.h"
//File->
// Node1->
// Name1/Value
// Node2->
// Name2/Value
// Oddity: Very little error checking, crashes if you look at it funny
// Oddity: When using setValue ala setValue("someindex",100); compiler cant tell if 100 is a bool or an int, silly compiler,
// casting to u16 works ala setValue("someindex",(u16)100); I see why, but its still silly, and casts are slow
class CXMLRegistry {
public:
CXMLRegistry(io::IFileSystem *fsys);
~CXMLRegistry();
bool loadFile(const c8 *fname, const c8 *path);
bool loadConfigFile(const c8 *fname);
bool writeFile(const c8 *fname, const c8 *path);
bool writeConfigFile(const c8 *fname);
const wchar_t *getValueAsCStr(const wchar_t *index,const wchar_t *context = 0);
// Dosnt work, just declare a stringc and assign the wchar_t to it
//const irr::c8 *getValueAsCharCStr(const wchar_t *index,const wchar_t *context = 0);
bool getValueAsBool(const wchar_t *index, const wchar_t *context = 0);
u16 getValueAsInt(const wchar_t *index, const wchar_t *context = 0);
// This one only takes a context because its going to read 4 childrens values
irr::core::rect<u32> getValueAsRect(const wchar_t *context = 0);
// This one only takes a context because its going to read 4 childrens values
video::SColor getValueAsColor(const wchar_t *context = 0);
irr::core::array<const wchar_t*> *listNonNodeChildren(const wchar_t *node,const wchar_t *context = 0);
irr::core::array<const wchar_t*> *listNodeChildren(const wchar_t *node,const wchar_t *context = 0);
bool setValue(const wchar_t *index, bool boolval, const wchar_t *context = 0);
bool setValue(const wchar_t *index, u16 intval, const wchar_t *context = 0);
bool setValue(const wchar_t *index, const wchar_t *txtval,const wchar_t *context = 0);
// Speed improvement, why search if we want multiple values from the same context
void setContext(const wchar_t *context);
bool isTopLevelNode(const wchar_t *node);
bool populateTreeView(irr::gui::IGUITreeView *control,const wchar_t *context = 0);
// TODO: These are trivial to do, just dont need them yet
// renameNode(context(?),TYPE)
// deleteNode(context(?) (CAREFUL WITH CHILDREN)
// addNode(context, value, type)
// CXMLNODETYPE_COMMENT
// Loading/saving of CDATA, easiest would be just save it in the value of
// the CXMLNODETYPE_NODE their accosicated with.
// make registry inherit node instead of containing an instance of it.
// context(?) might be tricky with CXMLNODETYPE_VALUE
//
//
private:
io::IFileSystem* fileSystem;
CXMLNode* registry;
CXMLNode* currentContext;
const wchar_t *convertBoolToText(bool boolval);
bool convertTextToBool(const wchar_t* textval);
CXMLNode *resolveContext(const wchar_t* context);
const irr::c8 *resolveConfigPath(const irr::c8 *fname);
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment