The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
persist_context.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2010 - 2025
3 by Jody Northup
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#pragma once
17
18#include "config.hpp"
19#include "log.hpp"
20static lg::log_domain log_persist("engine/persistence");
21
22#define LOG_PERSIST LOG_STREAM(info, log_persist)
23#define ERR_PERSist LOG_STREAM(err, log_persist)
24config pack_scalar(const std::string &,const t_string &);
26public:
27
28 virtual ~persist_context() {}
29
30 struct name_space {
31 std::string namespace_;
32 std::string root_;
33 std::string node_;
34 std::string lineage_;
35 std::string descendants_;
36 bool valid_;
37
38 bool valid() const {
39 return valid_;
40 }
41 void parse() {
42 while (namespace_.find_first_of("^") < namespace_.size()) {
43 if (namespace_[0] == '^') {
44 //TODO: Throw a WML error
45 namespace_ = "";
46 break;
47 }
48 std::string infix = namespace_.substr(namespace_.find_first_of("^"));
49 std::size_t end = infix.find_first_not_of("^");
50 if (!((end >= infix.length()) || (infix[end] == '.'))) {
51 //TODO: Throw a WML error
52 namespace_ = "";
53 break;
54 }
55 infix = infix.substr(0,end);
56 std::string suffix = namespace_.substr(namespace_.find_first_of("^") + infix.length());
57 while (!infix.empty())
58 {
59 std::string body = namespace_.substr(0,namespace_.find_first_of("^"));
60 body = body.substr(0,body.find_last_of("."));
61 infix = infix.substr(1);
62 namespace_ = body + infix + suffix;
63 }
64 }
65 }
66 name_space next() const {
68 }
69 name_space prev() const {
70 return name_space(lineage_);
71 }
72 operator bool () const { return valid_; }
74 : namespace_()
75 , root_()
76 , node_()
77 , lineage_()
78 , descendants_()
79 , valid_(false)
80 {
81 }
82
83 name_space(const std::string &ns, bool doParse = false)
84 : namespace_(ns)
85 , root_()
86 , node_()
87 , lineage_()
88 , descendants_()
89 , valid_(false)
90 {
91 if (doParse)
92 parse();
93 valid_ = ((namespace_.find_first_not_of("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_.") > namespace_.length()) && !namespace_.empty());
94 root_ = namespace_.substr(0,namespace_.find_first_of("."));
95 node_ = namespace_.substr(namespace_.find_last_of(".") + 1);
96 if (namespace_.find_last_of(".") <= namespace_.length())
97 lineage_ = namespace_.substr(0,namespace_.find_last_of("."));
98 if (namespace_.find_first_of(".") <= namespace_.length())
99 descendants_ = namespace_.substr(namespace_.find_first_of(".") + 1);
100 }
101 };
102protected:
105 bool valid_;
107
109 : cfg_()
110 , namespace_()
111 , valid_(false)
112 , in_transaction_(false)
113 {}
114
115 persist_context(const std::string &name_space)
116 : cfg_()
117 , namespace_(name_space,true)
119 , in_transaction_(false)
120 {}
121
122 config *get_node(config &cfg, name_space &ns, bool force = false) {
123 name_space next = ns.next();
124 if (next) {
125 if (force)
126 return get_node(cfg.child_or_add(next.root_), next, true);
127 else if (cfg.has_child(next.root_))
128 return get_node(cfg.mandatory_child(next.root_), next);
129 else
130 return nullptr;
131 }
132 else
133 return &cfg;
134 }
135
136 const config *get_node(const config &cfg, const name_space &ns) const {
137 name_space next = ns.next();
138 if (next) {
139 if (cfg.has_child(next.root_))
140 return get_node(cfg.mandatory_child(next.root_), next);
141 else
142 return nullptr;
143 }
144 else
145 return &cfg;
146 }
147
148public:
149 virtual bool clear_var(const std::string &, bool immediate = false) = 0;
150 virtual config get_var(const std::string &) const = 0;
151 virtual bool set_var(const std::string &, const config &, bool immediate = false) = 0;
152 virtual bool start_transaction () = 0;
153 virtual bool end_transaction () = 0;
154 virtual bool cancel_transaction () = 0;
155 std::string get_node() const;
156 void set_node(const std::string &);
157 bool valid() const { return valid_; }
158 bool dirty() const {
159 return true;
160 }
161 operator bool() const { return valid_; }
162};
163
165private:
166 void load();
167 void init();
168 bool save_context();
169
170public:
171 persist_file_context(const std::string &name_space);
172 bool clear_var(const std::string &, bool immediate = false);
173 config get_var(const std::string &) const;
174 bool set_var(const std::string &, const config &, bool immediate = false);
175
177 if (in_transaction_)
178 return false;
179 in_transaction_ = true;
180 return true;
181 }
183 if (!in_transaction_)
184 return false;
185 in_transaction_ = false;
186 save_context();
187 return true;
188 }
190 if (!in_transaction_)
191 return false;
192 load();
193 in_transaction_ = false;
194 return true;
195 }
196};
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
config & child_or_add(std::string_view key)
Returns a reference to the first child with the given key.
Definition config.cpp:401
bool has_child(std::string_view key) const
Determine whether a config has a child or not.
Definition config.cpp:312
config & mandatory_child(std::string_view key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
Definition config.cpp:362
virtual config get_var(const std::string &) const =0
config * get_node(config &cfg, name_space &ns, bool force=false)
persist_context(const std::string &name_space)
virtual bool end_transaction()=0
std::string get_node() const
const config * get_node(const config &cfg, const name_space &ns) const
virtual bool set_var(const std::string &, const config &, bool immediate=false)=0
virtual ~persist_context()
virtual bool start_transaction()=0
void set_node(const std::string &)
virtual bool cancel_transaction()=0
virtual bool clear_var(const std::string &, bool immediate=false)=0
config get_var(const std::string &) const
bool set_var(const std::string &, const config &, bool immediate=false)
bool clear_var(const std::string &, bool immediate=false)
Definitions for the interface to Wesnoth Markup Language (WML).
const config * cfg
Standard logging facilities (interface).
static lg::log_domain log_persist("engine/persistence")
config pack_scalar(const std::string &, const t_string &)
name_space(const std::string &ns, bool doParse=false)