From 09ce7366c86fd96f1bfd9dff242db5c084208eb9 Mon Sep 17 00:00:00 2001
From: auria <auria@178a84e3-b1eb-0310-8ba1-8eac791a3b58>
Date: Tue, 23 Jun 2009 01:44:49 +0000
Subject: [PATCH] Added saving challenges to config file

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3640 178a84e3-b1eb-0310-8ba1-8eac791a3b58
---
 src/challenges/challenge.cpp      | 37 ++++++++++++++++++++-----------
 src/challenges/challenge.hpp      | 13 +++++------
 src/challenges/challenge_data.hpp |  1 +
 src/challenges/unlock_manager.cpp | 20 ++++++++++++-----
 src/challenges/unlock_manager.hpp | 10 ++++-----
 src/config/user_config.cpp        |  9 ++++++--
 6 files changed, 57 insertions(+), 33 deletions(-)

diff --git a/src/challenges/challenge.cpp b/src/challenges/challenge.cpp
index 3c460b7d4..83c72ec61 100644
--- a/src/challenges/challenge.cpp
+++ b/src/challenges/challenge.cpp
@@ -19,6 +19,9 @@
 
 #include "challenges/challenge.hpp"
 
+#include <iostream>
+
+#include "io/xml_node.hpp"
 #include "karts/kart_properties_manager.hpp"
 #include "karts/kart_properties.hpp"
 #include "race/grand_prix_manager.hpp"
@@ -137,26 +140,34 @@ const std::string Challenge::getUnlockedMessage() const
 
 //-----------------------------------------------------------------------------
 /** Loads the state for a challenge object (esp. m_state), and calls the
- *  virtual function loadState for additional information
+ *  virtual function loadAdditionalInfo for additional information
  */
-void Challenge::load(const lisp::Lisp* config)
+void Challenge::load(const XMLNode* challengesNode)
 {
-    const lisp::Lisp* subnode= config->getLisp(getId());
-    if(!subnode) return;
-
+    const XMLNode* node = challengesNode->getNode( getId() );
+    if(node == NULL) return;
+    
     // See if the challenge is solved (it's activated later from the
     // unlock_manager).
-    bool finished=false;
-    subnode->get("solved", finished);
+    
+    std::string solvedString;
+    node->get("solved", &solvedString);
+    
+    bool finished = (solvedString == "true");
     m_state = finished ? CH_SOLVED : CH_INACTIVE;
-    if(!finished) loadState(subnode);
+    
+    if(m_state == CH_SOLVED)
+    {
+        std::cout << "Solved challenge!! " << getId().c_str() << std::endl;
+    }
+    
+    if(!finished) loadAdditionalInfo(node);
 }   // load
 
 //-----------------------------------------------------------------------------
-void Challenge::save(lisp::Writer* writer)
+void Challenge::save(std::ofstream& writer)
 {
-    writer->beginList(getId());
-    writer->write("solved", isSolved());
-    if(!isSolved()) saveState(writer);
-    writer->endList(getId());
+    writer << "        <" << getId() << " solved=\"" << (isSolved() ? "true" : "false") << "\"";
+    if(!isSolved()) saveAdditionalInfo(writer);
+    writer << " />\n";
 }   // save
diff --git a/src/challenges/challenge.hpp b/src/challenges/challenge.hpp
index 539e72192..99c698ff7 100644
--- a/src/challenges/challenge.hpp
+++ b/src/challenges/challenge.hpp
@@ -22,10 +22,9 @@
 
 #include <string>
 #include <vector>
+#include <fstream>
 
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/writer.hpp"
+class XMLNode;
 
 enum REWARD_TYPE
    {UNLOCK_TRACK,
@@ -86,13 +85,13 @@ public:
     void  setActive()                            {m_state = CH_ACTIVE;            }
     const std::vector<std::string>& 
           getPrerequisites() const               {return m_prerequisites;         }
-    void  load(const lisp::Lisp* config);
-    void  save(lisp::Writer* writer);
+    void  load(const XMLNode* config);
+    void  save(std::ofstream& writer);
 
     // These functions are meant for customisation, e.g. load/save
     // additional state information specific to the challenge
-    virtual void loadState(const lisp::Lisp* config) {};
-    virtual void saveState(lisp::Writer* writer)     {};
+    virtual void loadAdditionalInfo(const XMLNode* config) {};
+    virtual void saveAdditionalInfo(std::ofstream& writer)     {};
 
     // These functions are called when a race/gp is finished. It allows
     // the challenge to unlock features (when returning true), otherwise
diff --git a/src/challenges/challenge_data.hpp b/src/challenges/challenge_data.hpp
index dd6ce0aa2..2c3996b73 100644
--- a/src/challenges/challenge_data.hpp
+++ b/src/challenges/challenge_data.hpp
@@ -26,6 +26,7 @@
 
 #include "challenges/challenge.hpp"
 #include "race/race_manager.hpp"
+#include "lisp/lisp.hpp"
 
 class ChallengeData : public Challenge
 {
diff --git a/src/challenges/unlock_manager.cpp b/src/challenges/unlock_manager.cpp
index 47b658594..152e52fff 100644
--- a/src/challenges/unlock_manager.cpp
+++ b/src/challenges/unlock_manager.cpp
@@ -167,24 +167,32 @@ Challenge* UnlockManager::getChallenge(const std::string& id)
 //-----------------------------------------------------------------------------
 /** This is called from user_config when reading the config file
 */
-void UnlockManager::load(const lisp::Lisp* config)
+void UnlockManager::load(const XMLNode* configRoot)
 {
+    const XMLNode* challengesNode = configRoot->getNode("challenges");
+    if(challengesNode == NULL) return;
+    
     for(AllChallengesType::iterator i =m_all_challenges.begin(); 
                                     i!=m_all_challenges.end();  i++)
     {
-        i->second->load(config);
+        i->second->load(challengesNode);
     }
     computeActive();
 }   // load
 
 //-----------------------------------------------------------------------------
-void UnlockManager::save(lisp::Writer* writer)
+void UnlockManager::save(std::ofstream& writer)
 {
-    for(AllChallengesType::iterator i =m_all_challenges.begin(); 
-                                    i!=m_all_challenges.end();  i++)
+    writer << "    <challenges>\n";
+    
+    for(AllChallengesType::iterator i = m_all_challenges.begin(); 
+                                    i!= m_all_challenges.end();  i++)
     {
         i->second->save(writer);
-    }   // for i in m_all_challenges
+    }
+    
+    writer << "    </challenges>\n\n";
+    
 }   // save
 
 //-----------------------------------------------------------------------------
diff --git a/src/challenges/unlock_manager.hpp b/src/challenges/unlock_manager.hpp
index 69ddd2250..dc54ec718 100644
--- a/src/challenges/unlock_manager.hpp
+++ b/src/challenges/unlock_manager.hpp
@@ -23,9 +23,9 @@
 #include <map>
 
 #include "challenges/challenge.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/writer.hpp"
+#include <fstream>
+
+class XMLNode;
 
 class UnlockManager
 {
@@ -40,8 +40,8 @@ public:
                UnlockManager    ();
     void       addChallenge     (Challenge *c);
     void       addChallenge     (const std::string& filename);
-    void       load             (const lisp::Lisp*);
-    void       save             (lisp::Writer* writer);
+    void       load             (const XMLNode*);
+    void       save             (std::ofstream& writer);
     std::vector<const Challenge*> 
                getActiveChallenges();
     const std::vector<const Challenge*> 
diff --git a/src/config/user_config.cpp b/src/config/user_config.cpp
index f9980b9af..8a9c79141 100644
--- a/src/config/user_config.cpp
+++ b/src/config/user_config.cpp
@@ -527,6 +527,10 @@ bool UserConfig::loadConfig(const std::string& filename)
         std::cout << "----- player : " << name.c_str() << std::endl;
     }
 
+    // --- Read challenges
+    
+    unlock_manager->load(root);
+    
     delete root;
     return true;
 
@@ -536,8 +540,6 @@ bool UserConfig::loadConfig(const std::string& filename)
 /** Write settings to config file. */
 void UserConfig::saveConfig(const std::string& filepath)
 {
-    // TODO : save challenges state
-
     const int DIR_EXIST = CheckAndCreateDir();
     // Check if the config directory exists (again, since it was already checked
     // when reading the config file - this is done in case that the problem was
@@ -568,6 +570,9 @@ void UserConfig::saveConfig(const std::string& filepath)
         //std::cout << "saving parameter " << i << " to file\n";
         all_params[i].write(configfile);
     }
+    
+    unlock_manager->save(configfile);
+    
     configfile << "</stkconfig>\n";
     configfile.close();