ConfigFileManager

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Brainsaw
Posts: 1242
Joined: Wed Jan 07, 2004 12:57 pm
Location: Bavaria

ConfigFileManager

Post by Brainsaw »

Hi there,

I do already have a config file manager integrated into my projects (IrrOdeCar demo, Stunt Marble Racers), but it has some backdraws:

- uses plain IrrXML
- doesn't keep configuration information that is currently not used (e.g. all the rest when the initial graphics mode dialog pops up in Stunt Marble Racers)

Because of this I have decided to make a new configuration manager. This time I have used the (de)serialization methods that Irrlicht provides. Enough talking, here's the code:

IConfiguration.h

Code: Select all

#ifndef _I_CONFIGURATION
  #define _I_CONFIGURATION

/**
 * @class IConfiguration
 * Implement this interface to have configurations saved and loaded
 * @author Christian Keimel / bulletbyte.de
 */
class IConfiguration {
  public:
    virtual ~IConfiguration() { }
    
    virtual void writeConfiguration(irr::io::IAttributes *pOut)=0;  /**<! implement this method to write configuration */
    virtual void readConfiguration(irr::io::IAttributes *pIn)=0;    /**<! implement this method to read configuration */
    
    /**
     * This method returns the name of the configuration settings. Must be unique within a project (config file)
     * @return name of the configuration part
     */
    virtual irr::core::stringc getConfigName()=0;
};

#endif
CConfigurationManager.h

Code: Select all

#ifndef _C_CONFIGURATION_MANAGER
  #define _C_CONFIGURATION_MANAGER

  #include <irrlicht.h>

class IConfiguration;
  
/**
 * @class CConfigurationManager
 * This is the managing class that takes care of loading and
 * saving. Register your implementation instances of
 * "IConfiguration" with the "addConfiguration" method
 * @author Christian Keimel / bulletbyte.de
 */
class CConfigurationManager {
  protected:
    /**
     * @class CAttributeWrap
     * This class is just used to bind together the attributes
     * and the configuration instance
     * @author Christian Keimel / bulletbyte.de
     */
    class CAttributeWrap {
      public:
        CAttributeWrap() {
          m_pAttr=NULL;
          m_pConf=NULL;
        }
        
        irr::core::stringc m_sName;     /**<! the name */
        irr::io::IAttributes *m_pAttr;  /**<! the attributes */
        IConfiguration *m_pConf;        /**<! the configuration */
    };
    
    irr::IrrlichtDevice *m_pDevice;
    irr::core::list<IConfiguration *> m_lConfigurations;
    irr::core::list<CAttributeWrap *> m_lParts;
    irr::core::stringc m_sFileName;
    
  public:
    /**
     * Constructor
     * @param sFileName the name of the configuration file
     */
    CConfigurationManager(irr::core::stringc sFileName, irr::IrrlichtDevice *pDevice);
    
    /**
     * Destructor. Does save the settings to the
     * specified file
     */
    ~CConfigurationManager();
    
    /**
     * load the settings from the specified file
     * @return "true" if loading succeeded, "false" otherwise
     */
    bool load();
    
    /**
     * save the settings to the specified file
     * @return "true" if saving succeeded, "false" otherwise
     */
    bool save();
    
    /**
     * Add a configuration to the list. Configurations can't be added more
     * the once
     * @param p configuration to add
     */
    void addConfiguration(IConfiguration *p);
    
    /**
     * Remove a configuration from the list
     * @param p configuration to remove
     * @return "true" if the configuration was removed, "false" otherwise
     */
    bool removeConfiguration(IConfiguration *p);
};

#endif
CConfigurationManager.cpp

Code: Select all

  #include <CConfigurationManager.h>
  #include <IConfiguration.h>

/**
 * Constructor
 * @param sFileName the name of the configuration file
 */
CConfigurationManager::CConfigurationManager(irr::core::stringc sFileName, irr::IrrlichtDevice *pDevice) {
  m_sFileName=sFileName;
  m_pDevice=pDevice;
}

/**
 * Destructor. Does save the settings to the
 * specified file
 */
CConfigurationManager::~CConfigurationManager() {
  save();
  
  //clear the list of parts
  while (m_lParts.getSize()>0) {
    irr::core::list<CAttributeWrap *>::Iterator it=m_lParts.begin();
    CAttributeWrap *p=*it;
    m_lParts.erase(it);
    delete p;
  }
}

/**
 * load the settings from the specified file
 * @return "true" if loading succeeded, "false" otherwise
 */
bool CConfigurationManager::load() {
  bool bRet=false;
  
  irr::io::IReadFile *pRead=m_pDevice->getFileSystem()->createAndOpenFile(m_sFileName);
  if (pRead) {
    irr::io::IXMLReader *pReader=m_pDevice->getFileSystem()->createXMLReader(m_sFileName);
    if (pReader) {
      irr::core::stringc sNodeName;
      while (pReader->read()) {
        if (pReader->getNodeType()==irr::io::EXN_ELEMENT) {
          if (irr::core::stringc("attributes")==pReader->getNodeName()) {
            irr::io::IAttributes *pAttr=m_pDevice->getFileSystem()->createEmptyAttributes(m_pDevice->getVideoDriver());
            bool bFound=false;
            pAttr->read(pReader,true);
            irr::core::list<CAttributeWrap *>::Iterator it;
            for (it=m_lParts.begin(); it!=m_lParts.end(); it++) {
              CAttributeWrap *w=*it;
              if (w->m_sName==sNodeName) {
                w->m_pAttr=pAttr;
                w->m_pConf->readConfiguration(pAttr);
                bFound=true;
              }
            }
            if (!bFound) {
              CAttributeWrap *w=new CAttributeWrap();
              w->m_sName=sNodeName;
              w->m_pAttr=pAttr;
              m_lParts.push_back(w);
            }
          }
          else sNodeName=pReader->getNodeName();
        }
      }
      bRet=true;
    }
    else printf("Unable to create xml writer for file \"%s\"\n",m_sFileName.c_str());
  }
  else printf("Unable to open file \"%s\" for loading parameters\n",m_sFileName.c_str());
  
  return bRet;
}

/**
 * save the settings to the specified file
 * @return "true" if saving succeeded, "false" otherwise
 */
bool CConfigurationManager::save() {
  bool bRet=false;
  
  irr::io::IWriteFile *pFile=m_pDevice->getFileSystem()->createAndWriteFile(m_sFileName);
  
  if (pFile) {
    irr::io::IXMLWriter *pWriter=m_pDevice->getFileSystem()->createXMLWriter(m_sFileName);
    if (pWriter) {
      pWriter->writeXMLHeader();
      pWriter->writeElement(L"configuration");
      pWriter->writeLineBreak();
      irr::core::list<CAttributeWrap *>::Iterator it;
      for (it=m_lParts.begin(); it!=m_lParts.end(); it++) {
        CAttributeWrap *w=*it;
        if (w->m_pAttr==NULL) w->m_pAttr=m_pDevice->getFileSystem()->createEmptyAttributes(m_pDevice->getVideoDriver());
        
        if (w->m_pConf!=NULL) {
          w->m_pAttr->clear();
          w->m_pConf->writeConfiguration(w->m_pAttr);
        }
        
        pWriter->writeElement(irr::core::stringw(w->m_sName.c_str()).c_str());
        pWriter->writeLineBreak();
        w->m_pAttr->write(pWriter);
        pWriter->writeClosingTag(irr::core::stringw(w->m_sName.c_str()).c_str());
        pWriter->writeLineBreak();
      }
      pWriter->writeClosingTag(L"parameters");
      pWriter->drop();
      bRet=true;
    }
    else printf("Unable to create xml writer for file \"%s\"\n",m_sFileName.c_str());
    pFile->drop();
  }
  else printf("Unable to open file \"%s\" for saving configuration",m_sFileName.c_str());
  
  return bRet;
}

/**
 * Add a configuration to the list. Configurations can't be added more
 * the once
 * @param p configuration to add
 */
void CConfigurationManager::addConfiguration(IConfiguration *p) {
  //we only want one instance in the list one time. Exit method if it's already registered
  irr::core::list<IConfiguration *>::Iterator it;
  for (it=m_lConfigurations.begin(); it!=m_lConfigurations.end(); it++) if (*it==p) return;
  CAttributeWrap *w=new CAttributeWrap();
  w->m_sName=p->getConfigName();
  w->m_pConf=p;
  m_lParts.push_back(w);
  m_lConfigurations.push_back(p);
}

/**
 * Remove a configuration from the list
 * @param p configuration to remove
 * @return "true" if the configuration was removed, "false" otherwise
 */
bool CConfigurationManager::removeConfiguration(IConfiguration *p) {
  irr::core::list<IConfiguration *>::Iterator it;
  for (it=m_lConfigurations.begin(); it!=m_lConfigurations.end(); it++) 
    if (*it==p) {
      m_lConfigurations.erase(it);
      return true;;
    }
  
  return false;
}
main.cpp (for testing, and to see how the code is used):

Code: Select all

  #include <stdio.h>
  #include <irrlicht.h>
  
  #include <CConfigurationManager.h>
  #include <IConfiguration.h>

using namespace std;

class CTest1 : public IConfiguration {
  public:
    virtual void writeConfiguration(irr::io::IAttributes *pOut) {
      pOut->addInt("value1",1);
      pOut->addInt("value2",2);
      pOut->addInt("value3",3);
      pOut->addString("name","Test1");
    }
    
    virtual void readConfiguration(irr::io::IAttributes *pIn) {
      printf("value: %i\n",pIn->getAttributeAsInt("value1"));
      printf("value: %i\n",pIn->getAttributeAsInt("value2"));
      printf("value: %i\n",pIn->getAttributeAsInt("value3"));
      printf("name: %s\n",pIn->getAttributeAsString("name").c_str());
    }
    
    virtual irr::core::stringc getConfigName() {
      return irr::core::stringc("TestConfig1");
    }
};

class CTest2 : public IConfiguration {
  public:
    virtual void writeConfiguration(irr::io::IAttributes *pOut) {
      pOut->addFloat("firstValue",5.23);
      pOut->addString("myName","ConfigurationTest2");
    }
    
    virtual void readConfiguration(irr::io::IAttributes *pIn) {
      printf("firstValue: %.2f\n",pIn->getAttributeAsFloat("firstValue"));
      printf("myName: %s\n",pIn->getAttributeAsString("myName").c_str());
    }
    
    virtual irr::core::stringc getConfigName() {
      return irr::core::stringc("TestConfig2");
    }
};

class CTest3 : public IConfiguration {
  public:
    virtual void writeConfiguration(irr::io::IAttributes *pOut) {
      pOut->addInt("AnInteger",23);
      pOut->addString("AnotherName","ConfigurationTest3");
    }
    
    virtual void readConfiguration(irr::io::IAttributes *pIn) {
      printf("AnInteger: %i\n",pIn->getAttributeAsInt("AnInteger"));
      printf("AnotherName: %s\n",pIn->getAttributeAsString("AnotherName").c_str());
    }
    
    virtual irr::core::stringc getConfigName() {
      return irr::core::stringc("TestConfig3");
    }
};

int main() {
  irr::IrrlichtDevice *pDevice=irr::createDevice(irr::video::EDT_NULL);
  CConfigurationManager *p=new CConfigurationManager("test1.xml",pDevice);
  
  CTest1 t1;
  p->addConfiguration(&t1);
  p->load();
  p->save();
  delete p;
  
  CTest2 t2;
  CTest3 t3;
  
  printf("\t\t**** new configuration\n");
  p=new CConfigurationManager("test1.xml",pDevice);
  p->addConfiguration(&t2);
  p->addConfiguration(&t3);
  p->load();
  p->save();
  
  delete p;
  return 0;
}
I haven't (yet) integrated it into any "real" programs, but it might be helpful for someone around here (zlib licence of course).
Image
Dustbin::Games on the web: https://www.dustbin-online.de/
Post Reply