forked from mia/Aegisub
Change json::Object's backing store from a list to a map. Cajun used list to preserve order, but json objects do not guarantee that order will be preserved
Originally committed to SVN as r5747.
This commit is contained in:
parent
2f64a116a7
commit
9dc9047c11
10 changed files with 43 additions and 108 deletions
|
@ -76,20 +76,18 @@ Hotkey::Hotkey(const std::string &file, const std::string &default_config)
|
|||
json::Object object = hotkey_root;
|
||||
|
||||
for (json::Object::const_iterator index(object.begin()); index != object.end(); index++) {
|
||||
const json::Object::Member& member = *index;
|
||||
const json::Object& obj = member.element;
|
||||
BuildHotkey(member.name, obj);
|
||||
const json::Object& obj = index->second;
|
||||
BuildHotkey(index->first, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Hotkey::BuildHotkey(std::string const& context, const json::Object& object) {
|
||||
for (json::Object::const_iterator index(object.begin()); index != object.end(); index++) {
|
||||
const json::Object::Member& member = *index;
|
||||
const json::Array& array = member.element;
|
||||
const json::Array& array = index->second;
|
||||
|
||||
for (json::Array::const_iterator arr_index(array.begin()); arr_index != array.end(); arr_index++) {
|
||||
Combo combo(context, member.name);
|
||||
Combo combo(context, index->first);
|
||||
|
||||
const json::Object& obj = *arr_index;
|
||||
|
||||
|
|
|
@ -37,11 +37,8 @@ MRUManager::MRUManager(const std::string &config, const std::string &default_con
|
|||
json::Object::const_iterator index_object(root_new.begin()), index_objectEnd(root_new.end());
|
||||
|
||||
for (; index_object != index_objectEnd; ++index_object) {
|
||||
const json::Object::Member& member = *index_object;
|
||||
const std::string &member_name = member.name;
|
||||
const json::UnknownElement& element = member.element;
|
||||
|
||||
Load(member_name, (json::Array)element);
|
||||
const std::string &member_name = index_object->first;
|
||||
Load(member_name, (json::Array)index_object->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -239,10 +239,10 @@ bool Options::PutOption(json::Object &obj, const std::string &path, const json::
|
|||
|
||||
// New key, make object.
|
||||
if (pos == obj.end())
|
||||
pos = obj.insert(json::Object::Member(thispart, json::Object()));
|
||||
pos = obj.insert(make_pair(thispart, json::Object()));
|
||||
|
||||
PutOptionVisitor visitor(restpart, value);
|
||||
pos->element.Accept(visitor);
|
||||
pos->second.Accept(visitor);
|
||||
return visitor.result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,9 +43,8 @@ void ConfigVisitor::Visit(const json::Object& object) {
|
|||
name += "/";
|
||||
|
||||
for (; index != index_end; ++index) {
|
||||
const json::Object::Member& member = *index;
|
||||
const std::string &member_name = member.name;
|
||||
const json::UnknownElement& element = member.element;
|
||||
const std::string &member_name = index->first;
|
||||
const json::UnknownElement& element = index->second;
|
||||
|
||||
ConfigVisitor config_visitor(values, name + member_name);
|
||||
|
||||
|
@ -61,11 +60,10 @@ void ConfigVisitor::Visit(const json::Array& array) {
|
|||
for (; index != indexEnd; ++index) {
|
||||
const json::Object& index_array = *index;
|
||||
|
||||
json::Object::const_iterator index_object(index_array.begin()), index_objectEnd(index_array.end());
|
||||
json::Object::const_iterator it(index_array.begin()), index_objectEnd(index_array.end());
|
||||
|
||||
for (; index_object != index_objectEnd; ++index_object) {
|
||||
const json::Object::Member& member = *index_object;
|
||||
const std::string& member_name = member.name;
|
||||
for (; it != index_objectEnd; ++it) {
|
||||
const std::string& member_name = it->first;
|
||||
|
||||
// This can only happen once since a list must always be of the same
|
||||
// type, if we try inserting another type into it we want it to fail.
|
||||
|
@ -86,27 +84,16 @@ void ConfigVisitor::Visit(const json::Array& array) {
|
|||
}
|
||||
|
||||
try {
|
||||
if (member_name == "string") {
|
||||
std::string val = (json::String)member.element;
|
||||
array_list->InsertString(val);
|
||||
|
||||
} else if (member_name == "int") {
|
||||
int64_t val = (int64_t)(json::Number)member.element;
|
||||
array_list->InsertInt(val);
|
||||
|
||||
} else if (member_name == "double") {
|
||||
double val = (json::Number)member.element;
|
||||
array_list->InsertDouble(val);
|
||||
|
||||
} else if (member_name == "bool") {
|
||||
bool val = (json::Boolean)member.element;
|
||||
array_list->InsertBool(val);
|
||||
|
||||
} else if (member_name == "colour") {
|
||||
std::string val = (json::String)member.element;
|
||||
Colour col(val);
|
||||
array_list->InsertColour(col);
|
||||
}
|
||||
if (member_name == "string")
|
||||
array_list->InsertString((json::String)it->second);
|
||||
else if (member_name == "int")
|
||||
array_list->InsertInt((int64_t)(json::Number)it->second);
|
||||
else if (member_name == "double")
|
||||
array_list->InsertDouble((json::Number)it->second);
|
||||
else if (member_name == "bool")
|
||||
array_list->InsertBool((json::Boolean)it->second);
|
||||
else if (member_name == "colour")
|
||||
array_list->InsertColour((std::string)(json::String)it->second);
|
||||
} catch (agi::Exception&) {
|
||||
delete array_list;
|
||||
throw OptionJsonValueArray("Attempt to insert value into array of wrong type");
|
||||
|
|
|
@ -185,17 +185,7 @@ private:
|
|||
class Object
|
||||
{
|
||||
public:
|
||||
struct Member {
|
||||
Member(const std::string& nameIn = std::string(), const UnknownElement& elementIn = UnknownElement())
|
||||
: name(nameIn), element(elementIn) { }
|
||||
|
||||
bool operator == (const Member& member) const;
|
||||
|
||||
std::string name;
|
||||
UnknownElement element;
|
||||
};
|
||||
|
||||
typedef std::list<Member> Members; // map faster, but does not preserve order
|
||||
typedef std::map<std::string, UnknownElement> Members;
|
||||
typedef Members::iterator iterator;
|
||||
typedef Members::const_iterator const_iterator;
|
||||
|
||||
|
@ -209,10 +199,10 @@ public:
|
|||
size_t size() const { return m_Members.size(); }
|
||||
bool empty() const { return m_Members.empty(); }
|
||||
|
||||
iterator find(const std::string& name);
|
||||
const_iterator find(const std::string& name) const;
|
||||
iterator find(const std::string& name) { return m_Members.find(name); }
|
||||
const_iterator find(const std::string& name) const { return m_Members.find(name); }
|
||||
|
||||
iterator insert(const Member& member);
|
||||
iterator insert(std::pair<std::string, UnknownElement> const& ele);
|
||||
iterator erase(iterator it) { return m_Members.erase(it); }
|
||||
void clear() { m_Members.clear(); }
|
||||
|
||||
|
@ -220,8 +210,6 @@ public:
|
|||
const UnknownElement& operator [](const std::string& name) const;
|
||||
|
||||
private:
|
||||
class Finder;
|
||||
|
||||
Members m_Members;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,18 +7,10 @@ Author: Terry Caton
|
|||
***********************************************/
|
||||
|
||||
#include "visitor.h"
|
||||
#include "reader.h"
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
* better documentation
|
||||
|
||||
*/
|
||||
|
||||
namespace json
|
||||
{
|
||||
|
||||
|
@ -199,40 +191,13 @@ inline bool UnknownElement::operator == (const UnknownElement& element) const
|
|||
|
||||
//////////////////
|
||||
// Object members
|
||||
|
||||
inline bool Object::Member::operator == (const Member& member) const
|
||||
inline Object::iterator Object::insert(std::pair<std::string, UnknownElement> const& ele)
|
||||
{
|
||||
return name == member.name && element == member.element;
|
||||
}
|
||||
|
||||
class Object::Finder : public std::unary_function<Object::Member, bool>
|
||||
{
|
||||
std::string m_name;
|
||||
public:
|
||||
Finder(const std::string& name) : m_name(name) {}
|
||||
bool operator () (const Object::Member& member) {
|
||||
return member.name == m_name;
|
||||
}
|
||||
};
|
||||
|
||||
inline Object::iterator Object::find(const std::string& name)
|
||||
{
|
||||
return std::find_if(m_Members.begin(), m_Members.end(), Finder(name));
|
||||
}
|
||||
|
||||
inline Object::const_iterator Object::find(const std::string& name) const
|
||||
{
|
||||
return std::find_if(m_Members.begin(), m_Members.end(), Finder(name));
|
||||
}
|
||||
|
||||
inline Object::iterator Object::insert(const Member& member)
|
||||
{
|
||||
iterator it = find(member.name);
|
||||
iterator it = find(ele.first);
|
||||
if (it != m_Members.end())
|
||||
throw Exception("Object member already exists: " + member.name);
|
||||
throw Exception("Object member already exists: " + ele.first);
|
||||
|
||||
m_Members.push_back(member);
|
||||
return --it;
|
||||
return m_Members.insert(ele).first;
|
||||
}
|
||||
|
||||
inline UnknownElement& Object::operator [](const std::string& name)
|
||||
|
@ -240,9 +205,9 @@ inline UnknownElement& Object::operator [](const std::string& name)
|
|||
iterator it = find(name);
|
||||
if (it == m_Members.end())
|
||||
{
|
||||
it = insert(Member(name));
|
||||
it = insert(make_pair(name, UnknownElement()));
|
||||
}
|
||||
return it->element;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline const UnknownElement& Object::operator [](const std::string& name) const
|
||||
|
@ -250,7 +215,7 @@ inline const UnknownElement& Object::operator [](const std::string& name) const
|
|||
const_iterator it = find(name);
|
||||
if (it == end())
|
||||
throw Exception("Object member not found: " + name);
|
||||
return it->element;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
|
|
|
@ -402,17 +402,17 @@ inline void Reader::Parse(Object& object, Reader::TokenStream& tokenStream)
|
|||
tokenStream.Peek().nType != Token::TOKEN_OBJECT_END);
|
||||
while (bContinue)
|
||||
{
|
||||
Object::Member member;
|
||||
std::pair<std::string, UnknownElement> member;
|
||||
|
||||
// first the member name. save the token in case we have to throw an exception
|
||||
const Token& tokenName = tokenStream.Peek();
|
||||
member.name = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
|
||||
member.first = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
|
||||
|
||||
// ...then the key/value separator...
|
||||
MatchExpectedToken(Token::TOKEN_MEMBER_ASSIGN, tokenStream);
|
||||
|
||||
// ...then the value itself (can be anything).
|
||||
Parse(member.element, tokenStream);
|
||||
Parse(member.second, tokenStream);
|
||||
|
||||
// try adding it to the object (this could throw)
|
||||
try
|
||||
|
@ -422,7 +422,7 @@ inline void Reader::Parse(Object& object, Reader::TokenStream& tokenStream)
|
|||
catch (Exception&)
|
||||
{
|
||||
// must be a duplicate name
|
||||
throw ParseException("Duplicate object member token: " + member.name, tokenName.locBegin, tokenName.locEnd);
|
||||
throw ParseException("Duplicate object member token: " + member.first, tokenName.locBegin, tokenName.locEnd);
|
||||
}
|
||||
|
||||
bContinue = (tokenStream.EOS() == false &&
|
||||
|
|
|
@ -82,8 +82,8 @@ inline void Writer::Write_i(const Object& object)
|
|||
Object::const_iterator it(object.begin()),
|
||||
itend(object.end());
|
||||
while (it != itend) {
|
||||
m_ostr << std::string(m_nTabDepth, '\t') << '"' << it->name << "\" : ";
|
||||
Write_i(it->element);
|
||||
m_ostr << std::string(m_nTabDepth, '\t') << '"' << it->first << "\" : ";
|
||||
Write_i(it->second);
|
||||
|
||||
if (++it != itend)
|
||||
m_ostr << ',';
|
||||
|
|
|
@ -231,7 +231,7 @@ struct CommandMenuBar : public wxMenuBar {
|
|||
bool read_entry(json::Object const& obj, const char *name, std::string *value) {
|
||||
json::Object::const_iterator it = obj.find(name);
|
||||
if (it == obj.end()) return false;
|
||||
*value = static_cast<json::String const&>(it->element);
|
||||
*value = static_cast<json::String const&>(it->second);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ menu_items const& get_menu(std::string const& name) {
|
|||
|
||||
menu_map::const_iterator it = root.find(name);
|
||||
if (it == root.end()) throw menu::UnknownMenu("Menu named " + name + " not found");
|
||||
return it->element;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
wxMenu *build_menu(std::string const& name, agi::Context *c, CommandManager *cm, wxMenu *menu = 0);
|
||||
|
|
|
@ -100,7 +100,7 @@ namespace {
|
|||
|
||||
int icon_size = OPT_GET("App/Toolbar Icon Size")->GetInt();
|
||||
|
||||
json::Array arr = it->element;
|
||||
json::Array arr = it->second;
|
||||
commands.reserve(arr.size());
|
||||
bool needs_onidle = false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue