mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-09 05:07:43 +00:00
Non-clobbering YAML serialize operation
This commit is contained in:
2
hecl/extern/athena
vendored
2
hecl/extern/athena
vendored
Submodule hecl/extern/athena updated: de55c9acdf...42b97e0306
2
hecl/extern/boo
vendored
2
hecl/extern/boo
vendored
Submodule hecl/extern/boo updated: 25dc238c44...1d70723c98
@@ -19,14 +19,14 @@ using namespace std::literals;
|
|||||||
#define DEFAULT_GRAPHICS_API "OpenGL"sv
|
#define DEFAULT_GRAPHICS_API "OpenGL"sv
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class CVarCommons
|
struct CVarCommons
|
||||||
{
|
{
|
||||||
CVarManager& m_mgr;
|
CVarManager& m_mgr;
|
||||||
CVar* m_graphicsApi = nullptr;
|
CVar* m_graphicsApi = nullptr;
|
||||||
CVar* m_drawSamples = nullptr;
|
CVar* m_drawSamples = nullptr;
|
||||||
CVar* m_texAnisotropy = nullptr;
|
CVar* m_texAnisotropy = nullptr;
|
||||||
CVar* m_deepColor = nullptr;
|
CVar* m_deepColor = nullptr;
|
||||||
public:
|
|
||||||
CVarCommons(CVarManager& manager) : m_mgr(manager)
|
CVarCommons(CVarManager& manager) : m_mgr(manager)
|
||||||
{
|
{
|
||||||
m_graphicsApi = m_mgr.findOrMakeCVar("graphicsApi"sv,
|
m_graphicsApi = m_mgr.findOrMakeCVar("graphicsApi"sv,
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ void CVarManager::deserialize(CVar* cvar)
|
|||||||
if (!cvar || (!cvar->isArchive() && !cvar->isInternalArchivable()))
|
if (!cvar || (!cvar->isArchive() && !cvar->isInternalArchivable()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CVarContainer container;
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + com_configfile->toWideLiteral();
|
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + com_configfile->toWideLiteral();
|
||||||
#else
|
#else
|
||||||
@@ -85,12 +84,33 @@ void CVarManager::deserialize(CVar* cvar)
|
|||||||
|
|
||||||
if (m_useBinary)
|
if (m_useBinary)
|
||||||
{
|
{
|
||||||
|
CVarContainer container;
|
||||||
filename += _S(".bin");
|
filename += _S(".bin");
|
||||||
if (hecl::Stat(filename.c_str(), &st) || !S_ISREG(st.st_mode))
|
if (hecl::Stat(filename.c_str(), &st) || !S_ISREG(st.st_mode))
|
||||||
return;
|
return;
|
||||||
athena::io::FileReader reader(filename);
|
athena::io::FileReader reader(filename);
|
||||||
if (reader.isOpen())
|
if (reader.isOpen())
|
||||||
container.read(reader);
|
container.read(reader);
|
||||||
|
|
||||||
|
if (container.cvars.size() > 0)
|
||||||
|
{
|
||||||
|
auto serialized = std::find_if(container.cvars.begin(),
|
||||||
|
container.cvars.end(),
|
||||||
|
[&cvar](const DNACVAR::CVar& c) { return c.m_name == cvar->name(); });
|
||||||
|
|
||||||
|
if (serialized != container.cvars.end())
|
||||||
|
{
|
||||||
|
DNACVAR::CVar& tmp = *serialized;
|
||||||
|
|
||||||
|
if (cvar->m_value != tmp.m_value)
|
||||||
|
{
|
||||||
|
cvar->unlock();
|
||||||
|
cvar->fromLiteralToType(tmp.m_value, true);
|
||||||
|
cvar->m_wasDeserialized = true;
|
||||||
|
cvar->lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -99,25 +119,27 @@ void CVarManager::deserialize(CVar* cvar)
|
|||||||
return;
|
return;
|
||||||
athena::io::FileReader reader(filename);
|
athena::io::FileReader reader(filename);
|
||||||
if (reader.isOpen())
|
if (reader.isOpen())
|
||||||
container.fromYAMLStream(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (container.cvars.size() > 0)
|
|
||||||
{
|
|
||||||
auto serialized = std::find_if(container.cvars.begin(), container.cvars.end(), [&cvar](const DNACVAR::CVar& c) -> bool
|
|
||||||
{ return c.m_name == cvar->name(); });
|
|
||||||
|
|
||||||
if (serialized != container.cvars.end())
|
|
||||||
{
|
{
|
||||||
DNACVAR::CVar& tmp = *serialized;
|
athena::io::YAMLDocReader docReader;
|
||||||
|
if (docReader.parse(&reader))
|
||||||
if (cvar->m_value != tmp.m_value)
|
|
||||||
{
|
{
|
||||||
cvar->unlock();
|
std::unique_ptr<athena::io::YAMLNode> root = docReader.releaseRootNode();
|
||||||
cvar->fromLiteralToType(tmp.m_value, true);
|
auto serialized = std::find_if(root->m_mapChildren.begin(),
|
||||||
cvar->m_wasDeserialized = true;
|
root->m_mapChildren.end(),
|
||||||
cvar->lock();
|
[&cvar](const auto& c) { return c.first == cvar->name(); });
|
||||||
|
|
||||||
|
if (serialized != root->m_mapChildren.end())
|
||||||
|
{
|
||||||
|
const std::unique_ptr<athena::io::YAMLNode>& tmp = serialized->second;
|
||||||
|
|
||||||
|
if (cvar->m_value != tmp->m_scalarString)
|
||||||
|
{
|
||||||
|
cvar->unlock();
|
||||||
|
cvar->fromLiteralToType(tmp->m_scalarString, true);
|
||||||
|
cvar->m_wasDeserialized = true;
|
||||||
|
cvar->lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,16 +147,6 @@ void CVarManager::deserialize(CVar* cvar)
|
|||||||
|
|
||||||
void CVarManager::serialize()
|
void CVarManager::serialize()
|
||||||
{
|
{
|
||||||
CVarContainer container;
|
|
||||||
for (const std::pair<std::string, CVar*>& pair : m_cvars)
|
|
||||||
if (pair.second->isArchive() || (pair.second->isInternalArchivable() && pair.second->wasDeserialized() && !pair.second->hasDefaultValue()))
|
|
||||||
{
|
|
||||||
CVar tmp = *pair.second;
|
|
||||||
container.cvars.push_back(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
container.cvarCount = atUint32(container.cvars.size());
|
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + com_configfile->toWideLiteral();
|
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + com_configfile->toWideLiteral();
|
||||||
#else
|
#else
|
||||||
@@ -143,6 +155,13 @@ void CVarManager::serialize()
|
|||||||
|
|
||||||
if (m_useBinary)
|
if (m_useBinary)
|
||||||
{
|
{
|
||||||
|
CVarContainer container;
|
||||||
|
for (const std::pair<std::string, CVar*>& pair : m_cvars)
|
||||||
|
if (pair.second->isArchive() || (pair.second->isInternalArchivable() &&
|
||||||
|
pair.second->wasDeserialized() && !pair.second->hasDefaultValue()))
|
||||||
|
container.cvars.push_back(*pair.second);
|
||||||
|
container.cvarCount = atUint32(container.cvars.size());
|
||||||
|
|
||||||
filename += _S(".bin");
|
filename += _S(".bin");
|
||||||
athena::io::FileWriter writer(filename);
|
athena::io::FileWriter writer(filename);
|
||||||
if (writer.isOpen())
|
if (writer.isOpen())
|
||||||
@@ -151,9 +170,20 @@ void CVarManager::serialize()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
filename += _S(".yaml");
|
filename += _S(".yaml");
|
||||||
athena::io::FileWriter writer(filename);
|
|
||||||
if (writer.isOpen())
|
athena::io::FileReader r(filename);
|
||||||
container.toYAMLStream(writer);
|
athena::io::YAMLDocWriter docWriter(nullptr, r.isOpen() ? &r : nullptr);
|
||||||
|
r.close();
|
||||||
|
|
||||||
|
docWriter.setStyle(athena::io::YAMLNodeStyle::Block);
|
||||||
|
for (const std::pair<std::string, CVar*>& pair : m_cvars)
|
||||||
|
if (pair.second->isArchive() || (pair.second->isInternalArchivable() &&
|
||||||
|
pair.second->wasDeserialized() && !pair.second->hasDefaultValue()))
|
||||||
|
docWriter.writeString(pair.second->name().data(), pair.second->toLiteral());
|
||||||
|
|
||||||
|
athena::io::FileWriter w(filename);
|
||||||
|
if (w.isOpen())
|
||||||
|
docWriter.finish(&w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user