Prepare script lifecycle and data layer
This commit is contained in:
125
engine/src/Scripting/ScriptFieldStorage.cpp
Normal file
125
engine/src/Scripting/ScriptFieldStorage.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user