mail[Wesnoth-commits] r43306 - in /trunk/src: persist_context.cpp persist_context.hpp


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by upthorn on June 12, 2010 - 12:24:
Author: upthorn
Date: Sat Jun 12 12:24:09 2010
New Revision: 43306

URL: http://svn.gna.org/viewcvs/wesnoth?rev=43306&view=rev
Log:
Re-engineered persist_context struct to simplify structure, initialization, 
and garbage collection as well as reducing data duplication. Additionally, 
empty nodes are now removed from the structure when the last child or 
attribute is removed.

Modified:
    trunk/src/persist_context.cpp
    trunk/src/persist_context.hpp

Modified: trunk/src/persist_context.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/persist_context.cpp?rev=43306&r1=43305&r2=43306&view=diff
==============================================================================
--- trunk/src/persist_context.cpp (original)
+++ trunk/src/persist_context.cpp Sat Jun 12 12:24:09 2010
@@ -83,79 +83,37 @@
        cfg[name] = val;
        return cfg;
 }
-
+persist_context &persist_context::add_child(const std::string &key)  {
+//     children_[key] = new persist_context(namespace_.namespace_ + "." + 
key,this);
+//     children_[key]->cfg_.child_or_add(key);
+       return *this;//(children_[key]);
+}
 void persist_context::load() {
-       if (parent_ == NULL)
-               load_persist_data(namespace_.root(),cfg_,false);
-       for (config::all_children_iterator i = cfg_.ordered_begin(); i != 
cfg_.ordered_end(); i++) {
-               if (i->key != "variables") {
-                       if (children_.find(i->key) == children_.end()) {
-                               persist_context *child = new 
persist_context(namespace_.namespace_ + "." + i->key,this);
-                               children_[i->key] = child;
-                       }
-                       children_[i->key]->parent_ = this;
-                       children_[i->key]->cfg_ = cfg_.child_or_add(i->key);
-               }
-       }
-}
-
-void persist_context::init() {
-       if ((parent_ == NULL) && !namespace_.lineage().empty()) {
-               parent_ = new persist_context(namespace_.lineage(),*this);
-       }
-       load();
-       if (!cfg_.child("variables"))
-               cfg_.add_child("variables");
+       load_persist_data(namespace_.root_,cfg_,false);
 }
 
 persist_context::persist_context(const std::string &name_space) : 
 namespace_(name_space), 
 cfg_(),
-parent_(NULL),
-children_(),
 valid_(namespace_.valid()),
-dirty_(false),
-collected_(false)
-{
-       init();
-}
-
-persist_context::persist_context(const std::string &name_space, 
persist_context &child) : 
-namespace_(name_space), 
-cfg_(),
-parent_(NULL),
-children_(),
-valid_(namespace_.valid()),
-dirty_(false),
-collected_(false)
-{
-       children_[child.namespace_.node()] = &child;
-       init();
-       if (!cfg_.child(child.namespace_.node()))
-               cfg_.add_child(child.namespace_.node());
-}
-
-persist_context::persist_context(const std::string &name_space, 
persist_context *parent) : 
-namespace_(name_space), 
-cfg_(),
-parent_(parent),
-children_(),
-valid_(namespace_.valid()),
-dirty_(false),
-collected_(false)
-{
-       init();
-}
+root_node_(namespace_.root_,this,cfg_),
+active_(&root_node_)
+{
+       load();
+       root_node_.init();
+       active_ = &(root_node_.child(namespace_.next()));
+}
+
 persist_context::~persist_context() {
-       collected_ = true;
-       if (parent_ != NULL) {
-               if (!parent_->collected_)
-                       delete parent_;
-       }
-       for (persist_context::child_map::iterator i = children_.begin(); i != 
children_.end(); i++) {
-               if (!i->second->collected_)
-                       delete i->second;
-       }
+//     collected_ = true;
+//     if (parent_ != NULL) {
+//             if (!parent_->collected_)
+//                     delete parent_;
+//     }
+//     for (persist_context::child_map::iterator i = children_.begin(); i != 
children_.end(); i++) {
+//             if (!i->second->collected_)
+//                     delete i->second;
+//     }
 }
 
 bool persist_context::clear_var(std::string &global)
@@ -164,34 +122,46 @@
 //             load_persist_data(namespace_.root(),cfg_);
 //     }
 
-       config &cfg = cfg_.child("variables");
-       bool exists = cfg.has_attribute(global);
-       bool ret;
-       if (!exists) {
-               if (cfg.child(global)) {
-                       exists = true;
-                       std::string::iterator index_start = 
std::find(global.begin(),global.end(),'[');
-                       if (index_start != global.end())
-                       {
-                               const std::string::iterator index_end = 
std::find(global.begin(),global.end(),']');
-                               const std::string 
index_str(index_start+1,index_end);
-                               size_t index = 
static_cast<size_t>(lexical_cast_default<int>(index_str));
-                               cfg.remove_child(global,index);
-                       } else {
-                               cfg.clear_children(global);
-                       }
-               }
-       }
-       if (exists) {
-               cfg.remove_attribute(global);
-               if (cfg.empty()) {
-                       cfg_.clear_children("variables");
-                       cfg_.remove_attribute("variables");
-               }
-               dirty_ = true;
-               ret = save_context();
-       } else {
-               ret = exists;
+       config &cfg = active_->cfg_.child("variables");
+       bool ret = cfg;
+       if (ret) {
+               bool exists = cfg.has_attribute(global);
+               if (!exists) {
+                       if (cfg.child(global)) {
+                               exists = true;
+                               std::string::iterator index_start = 
std::find(global.begin(),global.end(),'[');
+                               if (index_start != global.end())
+                               {
+                                       const std::string::iterator index_end 
= std::find(global.begin(),global.end(),']');
+                                       const std::string 
index_str(index_start+1,index_end);
+                                       size_t index = 
static_cast<size_t>(lexical_cast_default<int>(index_str));
+                                       cfg.remove_child(global,index);
+                               } else {
+                                       cfg.clear_children(global);
+                               }
+                       }
+               }
+               if (exists) {
+                       cfg.remove_attribute(global);
+                       if (cfg.empty()) {
+                               active_->cfg_.clear_children("variables");
+                               active_->cfg_.remove_attribute("variables");
+                               while ((active_->cfg_.empty()) && 
(active_->parent_ != NULL)) {
+                                       active_ = active_->parent_;
+                                       
active_->cfg_.clear_children(namespace_.node_);
+                                       
active_->cfg_.remove_attribute(namespace_.node_);
+                                       if 
(active_->cfg_.child("variables").empty()) {
+                                               
active_->cfg_.clear_children("variables");
+                                               
active_->cfg_.remove_attribute("variables");
+                                       }
+                                       namespace_ = namespace_.prev();
+                               }
+                       }
+       //              dirty_ = true;
+                       ret = save_context();
+               } else {
+                       ret = exists;
+               }
        }
        return ret;
 }
@@ -203,30 +173,20 @@
 //             load_persist_data(namespace_,cfg_,false);
 //     }
 
-       config &cfg = cfg_.child("variables");
-       if (cfg.child(global)) {
-               ret.add_child(global,cfg.child(global));
+       config &cfg = active_->cfg_.child("variables");
+       if (cfg) {
+               if (cfg.child(global)) {
+                       ret.add_child(global,cfg.child(global));
+               } else {
+                       ret = pack_scalar(global,cfg[global]);
+               }
        } else {
-               ret = pack_scalar(global,cfg[global]);
+               ret = pack_scalar(global,"");
        }
        return ret;
 }
-void persist_context::update_configs() {
-       for (child_map::iterator i = children_.begin(); i != children_.end(); 
i++) {
-               if (i->second->dirty()) {
-                       i->second->update_configs();
-                       cfg_.clear_children(i->second->namespace_.node());
-                       cfg_.remove_attribute(i->second->namespace_.node());
-                       
cfg_.add_child(i->second->namespace_.node(),i->second->cfg_);
-                       i->second->dirty_ = false;
-               }
-       }
-}
 bool persist_context::save_context() {
-       if (parent_ != NULL)
-               return parent_->save_context();
-       update_configs();
-       return save_persist_data(namespace_.root(),cfg_);
+       return save_persist_data(namespace_.root_,cfg_);
 }
 bool persist_context::set_var(const std::string &global,const config &val)
 {
@@ -234,12 +194,12 @@
 //             load_persist_data(namespace_,cfg_);
 //     }
 
-       config &cfg = cfg_.child("variables");
+       config &cfg = active_->cfg_.child_or_add("variables");
        if (val.has_attribute(global)) {
                cfg[global] = val[global];
        } else {
                cfg.add_child(global,val.child(global));
        }
-       dirty_ = true;
+//     dirty_ = true;
        return save_context();
 }

Modified: trunk/src/persist_context.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/persist_context.hpp?rev=43306&r1=43305&r2=43306&view=diff
==============================================================================
--- trunk/src/persist_context.hpp (original)
+++ trunk/src/persist_context.hpp Sat Jun 12 12:24:09 2010
@@ -28,21 +28,18 @@
                std::string root_;
                std::string node_;
                std::string lineage_;
+               std::string descendants_;
                bool valid_;
                bool valid() const {
                        return valid_;
                }
-               std::string lineage() const {
-                       return lineage_;
-               }
-               std::string node() const {
-                       return node_;
-               }
-               std::string root() const {
-                       return root_;
-               }
                void parse() {
                        while (namespace_.find_first_of("^") < 
namespace_.size()) {
+                               if (namespace_[0] = '^') {
+                                       //TODO: Throw a WML error
+                                       namespace_ = "";
+                                       break;
+                               }
                                std::string infix = 
namespace_.substr(namespace_.find_first_of("^"));
                                size_t end = infix.find_first_not_of("^");
                                if (!((end >= infix.length()) || (infix[end] 
== '.'))) {
@@ -61,6 +58,14 @@
                                }
                        }
                }
+               name_space next() const {
+                       return name_space(descendants_);
+               }
+               name_space prev() const {
+                       return name_space(lineage_);
+               }
+               operator bool () const { return valid_; }
+               name_space() : valid_(false) {};
                name_space(const std::string &ns) : namespace_(ns) {
                        parse();
                        valid_ = 
((namespace_.find_first_not_of("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_.")
namespace_.length()) && !namespace_.empty());
@@ -68,39 +73,69 @@
                        node_ = 
namespace_.substr(namespace_.find_last_of(".") + 1);
                        if (namespace_.find_last_of(".") <= 
namespace_.length())
                                lineage_ = 
namespace_.substr(0,namespace_.find_last_of("."));
+                       if (namespace_.find_first_of(".") <= 
namespace_.length())
+                               descendants_ = 
namespace_.substr(namespace_.find_first_of(".") + 1);
                }
        };
        // TODO: transaction support (needed for MP)
-       typedef std::map<std::string,persist_context*> child_map;
-       // TODO: parent and child members (needed for namespace embeddeding)
+       config cfg_;
        name_space namespace_;
-       config cfg_;
-       persist_context *parent_;
-       child_map children_;
+       struct node {
+               typedef std::map<std::string,node*> child_map;
+               std::string name_;
+               persist_context *root_;
+               node *parent_;
+               child_map children_;
+               config &cfg_;
+               node(std::string name, persist_context *root, config & cfg, 
node *parent = NULL) : name_(name), root_(root), cfg_(cfg),parent_(parent) { 
+               }
+               ~node() {
+                       for (child_map::iterator i = children_.begin(); i != 
children_.end(); i++)
+                               delete (i->second);
+               }
+               config &cfg() { return cfg_; }
+               node &add_child(const std::string &name) {
+                       children_[name] = new 
node(name,root_,cfg_.child_or_add(name),this);    
+                       return *(children_[name]);
+               }
+               node &child(const name_space &name) {
+                       if (name) {
+                               if (children_.find(name.root_) == 
children_.end())
+                                       add_child(name.root_);
+                               node &chld = *children_[name.root_];
+                               return chld.child(name.next());
+                       }
+                       else return *this;
+               }
+               void init () {
+                       for (config::all_children_iterator i = 
cfg_.ordered_begin(); i != cfg_.ordered_end(); i++) {
+                               if (i->key != "variables") {
+                                       child(i->key).init();
+                               }
+                       }
+                       if (!cfg_.child("variables"))
+                               cfg_.add_child("variables");
+               }
+       };
+       node root_node_;
+       node *active_;
        bool valid_;
-       bool dirty_;
-       bool collected_;
        void load();
        void init();
        bool save_context();
-       void update_configs();
+       persist_context() : valid_(false), root_node_("",this,cfg_), 
active_(&root_node_) {};
+       static persist_context invalid;
+       persist_context &add_child(const std::string &key);
 public:
-       persist_context(const std::string &);
-       persist_context(const std::string &, persist_context &);
-       persist_context(const std::string &, persist_context *);
+       persist_context(const std::string &name_space);
        ~persist_context();
        bool clear_var(std::string &);
        config get_var(const std::string &);
        bool set_var(const std::string &, const config &);
        bool valid() const { return valid_; };
        bool dirty() const { 
-               bool dirt = dirty_;
-               child_map::const_iterator i = children_.begin();
-               while ((!dirt) && (i != children_.end())) {
-                       dirt |= i->second->dirty();
-                       i++;
-               }
-               return dirt; 
+               return true;
        };
+       operator bool() { return valid_; }
 };
 #endif




Related Messages


Powered by MHonArc, Updated Sat Jun 12 15:40:10 2010