// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdgeorges.h" #include "nel/misc/i_xml.h" #include "nel/misc/o_xml.h" #include "nel/misc/common.h" #include "nel/misc/path.h" #include "nel/georges/form.h" #include "nel/georges/form_loader.h" #ifdef DEBUG_NEW #define new DEBUG_NEW #endif using namespace NLMISC; namespace NLGEORGES { // *************************************************************************** // Misc // *************************************************************************** void warning (bool exception, const char *format, ... ) { // Make a buffer string va_list args; va_start( args, format ); char buffer[1024]; vsnprintf( buffer, 1024, format, args ); va_end( args ); // Set the warning if (exception) { // Make an error message char tmp[1024]; smprintf (tmp, 1024, "NeL::Georges %s", buffer); throw EXmlParsingError (tmp); } else { nlwarning ("NeL::Georges %s", buffer); } } // *************************************************************************** // UForm // *************************************************************************** UForm::~UForm () { } // *************************************************************************** UFormElm& CForm::getRootNode () { return Elements; } // *************************************************************************** const UFormElm& CForm::getRootNode () const { return Elements; } // *************************************************************************** // CForm // *************************************************************************** CForm::CForm () : Elements (this, NULL, NULL, 0xffffffff) { uint i; for (i=0; iwrite (node, this, NULL, true); } // Header Header.write (node); } // *************************************************************************** void CForm::readParent (const char *parent, CFormLoader &loader) { // Load the parent CForm *theParent = (CForm*)loader.loadForm (parent); if (theParent != NULL) { // Set the parent if (!insertParent (getParentCount (), parent, theParent)) { // Make an error message std::string parentName = parent; // Delete the value xmlFree ((void*)parent); // Throw exception warning (true, "readParent", "Can't set the parent FORM named (%s). Check if it is the same form or if it use a differnt formDfn.", parentName.c_str ()); } } else { // Make an error message std::string parentName = parent; // Delete the value xmlFree ((void*)parent); // Throw exception warning (true, "readParent", "Can't load the parent FORM named (%s).", parentName.c_str ()); } } // *************************************************************************** void CForm::read (xmlNodePtr node, CFormLoader &loader, CFormDfn *dfn, const std::string &filename) { // Save the filename _Filename = CFile::getFilename (filename); // Reset form clean (); // Check node name if ( ((const char*)node->name == NULL) || (strcmp ((const char*)node->name, "FORM") != 0) ) { // Make an error message warning (true, "read", "XML Syntax error in block line %d, node (%s) should be FORM.", (sint)node->line, node->name); } // Get first struct node xmlNodePtr child = CIXml::getFirstChildNode (node, "STRUCT"); if (child == NULL) { // Throw exception warning (true, "read", "Syntax error in block line %d, node (%s) should have a STRUCT child node.", (sint)node->line, node->name); } // Read the struct Elements.read (child, loader, dfn, this); // Get next struct node child = CIXml::getNextChildNode (node, "STRUCT"); uint index = 0; while ( (child != NULL) && (index < HeldElementCount)) { HeldElements[index]->read (child, loader, dfn, this); index++; } while (index < HeldElementCount) { // Build the Form HeldElements[index]->build (dfn); index++; } // Get the old parent parameter const char *parent = (const char*)xmlGetProp (node, (xmlChar*)"Parent"); if (parent) { // Add a parent, xmlFree is done by readParent readParent (parent, loader); } // Read the new parent nodes uint parentCount = CIXml::countChildren (node, "PARENT"); // Reserve some parents ParentList.reserve (ParentList.size () + parentCount); // Enum children node child = CIXml::getFirstChildNode (node, "PARENT"); while (child) { parent = (const char*)xmlGetProp (child, (xmlChar*)"Filename"); // Add a parent, xmlFree is done by readParent readParent (parent, loader); // Next node child = CIXml::getNextChildNode (child, "PARENT"); } // Read the header Header.read (node); } // *************************************************************************** const std::string &CForm::getComment () const { return Header.Comments; } // *************************************************************************** void CForm::write (class NLMISC::IStream &stream) { // Xml stream COXml xmlStream; xmlStream.init (&stream); // Write the file write (xmlStream.getDocument (), NULL); } // *************************************************************************** bool CForm::insertParent (uint before, const std::string &filename, CForm *parent) { // Set or reset ? nlassert (parent); // Must have the same DFN if (parent->Elements.FormDfn == Elements.FormDfn) { // Set members std::vector::iterator ite = ParentList.insert (ParentList.begin() + before, CParent()); ite->Parent = parent; ite->ParentFilename = filename; return true; } else { // Output an error warning (false, "insertParent", "Can't insert parent form (%s) that has not the same DFN.", filename.c_str()); } return false; } // *************************************************************************** void CForm::removeParent (uint parent) { ParentList.erase (ParentList.begin() + parent); } // *************************************************************************** CForm *CForm::getParent (uint parent) const { return ParentList[parent].Parent; } // *************************************************************************** const std::string &CForm::getParentFilename (uint parent) const { return ParentList[parent].ParentFilename; } // *************************************************************************** uint CForm::getParentCount () const { return (uint)ParentList.size (); } // *************************************************************************** void CForm::clean () { clearParents (); } // *************************************************************************** void CForm::clearParents () { ParentList.clear (); } // *************************************************************************** const std::string &CForm::getFilename () const { return _Filename; } // *************************************************************************** void CForm::warning (bool exception, const std::string &function, const char *format, ... ) const { // Make a buffer string va_list args; va_start( args, format ); char buffer[1024]; vsnprintf( buffer, 1024, format, args ); va_end( args ); // Set the warning NLGEORGES::warning (exception, "(CForm::%s) in form (%s) : %s", function.c_str(), _Filename.c_str (), buffer); } // *************************************************************************** void CForm::getDependencies (std::set &dependencies) const { // Add me if (dependencies.insert (toLower(CFile::getFilename (_Filename))).second) { // Add parents uint i; for (i=0; igetDependencies (dependencies); } } // Add elements Elements.getDependencies (dependencies); } } // *************************************************************************** uint CForm::getNumParent () const { return getParentCount(); } // *************************************************************************** UForm *CForm::getParentForm (uint parent) const { CForm *form = getParent (parent); return form; } // *************************************************************************** } // NLGEORGES