#include "Scripting/ScriptFieldStorage.h" #include #include 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 ScriptFieldStorage::GetFieldNames() const { std::vector 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 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