Files
XCEngine/engine/src/Scripting/ScriptFieldStorage.cpp

126 lines
3.7 KiB
C++

#include "Scripting/ScriptFieldStorage.h"
#include <algorithm>
#include <sstream>
namespace XCEngine {
namespace Scripting {
bool ScriptFieldStorage::SetFieldValue(const std::string& fieldName, ScriptFieldType type, const ScriptFieldValue& value) {
if (fieldName.empty() || !IsScriptFieldValueCompatible(type, value)) {
return false;
}
m_fields[fieldName] = StoredScriptField{type, value};
return true;
}
const StoredScriptField* ScriptFieldStorage::FindField(const std::string& fieldName) const {
const auto it = m_fields.find(fieldName);
return it != m_fields.end() ? &it->second : nullptr;
}
StoredScriptField* ScriptFieldStorage::FindField(const std::string& fieldName) {
const auto it = m_fields.find(fieldName);
return it != m_fields.end() ? &it->second : nullptr;
}
bool ScriptFieldStorage::Contains(const std::string& fieldName) const {
return m_fields.find(fieldName) != m_fields.end();
}
bool ScriptFieldStorage::Remove(const std::string& fieldName) {
return m_fields.erase(fieldName) > 0;
}
void ScriptFieldStorage::Clear() {
m_fields.clear();
}
std::vector<std::string> ScriptFieldStorage::GetFieldNames() const {
std::vector<std::string> names;
names.reserve(m_fields.size());
for (const auto& entry : m_fields) {
names.push_back(entry.first);
}
std::sort(names.begin(), names.end());
return names;
}
std::string ScriptFieldStorage::SerializeToString() const {
std::ostringstream os;
const std::vector<std::string> fieldNames = GetFieldNames();
for (const std::string& fieldName : fieldNames) {
const StoredScriptField* field = FindField(fieldName);
if (!field) {
continue;
}
os << "field="
<< EscapeScriptString(fieldName)
<< "|"
<< ScriptFieldTypeToString(field->type)
<< "|"
<< SerializeScriptFieldValue(field->type, field->value)
<< "\n";
}
return os.str();
}
void ScriptFieldStorage::DeserializeFromString(const std::string& data) {
m_fields.clear();
std::istringstream input(data);
std::string line;
while (std::getline(input, line)) {
if (line.empty()) {
continue;
}
static constexpr const char* fieldPrefix = "field=";
if (line.rfind(fieldPrefix, 0) != 0) {
continue;
}
const std::string payload = line.substr(6);
const size_t firstSeparator = payload.find('|');
const size_t secondSeparator = payload.find('|', firstSeparator == std::string::npos ? firstSeparator : firstSeparator + 1);
if (firstSeparator == std::string::npos || secondSeparator == std::string::npos) {
continue;
}
const std::string fieldName = UnescapeScriptString(payload.substr(0, firstSeparator));
const std::string typeName = payload.substr(firstSeparator + 1, secondSeparator - firstSeparator - 1);
const std::string serializedValue = payload.substr(secondSeparator + 1);
ScriptFieldType type = ScriptFieldType::None;
if (!TryParseScriptFieldType(typeName, type)) {
continue;
}
ScriptFieldValue value = CreateDefaultScriptFieldValue(type);
if (!TryDeserializeScriptFieldValue(type, serializedValue, value)) {
continue;
}
m_fields[fieldName] = StoredScriptField{type, value};
}
}
void ScriptFieldStorage::Serialize(std::ostream& os) const {
os << SerializeToString();
}
void ScriptFieldStorage::Deserialize(std::istream& is) {
std::ostringstream buffer;
buffer << is.rdbuf();
DeserializeFromString(buffer.str());
}
} // namespace Scripting
} // namespace XCEngine