Files
XCEngine/engine/include/XCEngine/Scripting/ScriptFieldStorage.h

130 lines
3.5 KiB
C
Raw Normal View History

#pragma once
#include <XCEngine/Scripting/ScriptField.h>
#include <istream>
#include <ostream>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <vector>
namespace XCEngine {
namespace Scripting {
struct StoredScriptField {
ScriptFieldType type = ScriptFieldType::None;
ScriptFieldValue value = std::monostate{};
};
template<typename T>
struct ScriptFieldTypeResolver;
template<>
struct ScriptFieldTypeResolver<float> {
static constexpr ScriptFieldType value = ScriptFieldType::Float;
};
template<>
struct ScriptFieldTypeResolver<double> {
static constexpr ScriptFieldType value = ScriptFieldType::Double;
};
template<>
struct ScriptFieldTypeResolver<bool> {
static constexpr ScriptFieldType value = ScriptFieldType::Bool;
};
template<>
struct ScriptFieldTypeResolver<int32_t> {
static constexpr ScriptFieldType value = ScriptFieldType::Int32;
};
template<>
struct ScriptFieldTypeResolver<uint64_t> {
static constexpr ScriptFieldType value = ScriptFieldType::UInt64;
};
template<>
struct ScriptFieldTypeResolver<std::string> {
static constexpr ScriptFieldType value = ScriptFieldType::String;
};
template<>
struct ScriptFieldTypeResolver<Math::Vector2> {
static constexpr ScriptFieldType value = ScriptFieldType::Vector2;
};
template<>
struct ScriptFieldTypeResolver<Math::Vector3> {
static constexpr ScriptFieldType value = ScriptFieldType::Vector3;
};
template<>
struct ScriptFieldTypeResolver<Math::Vector4> {
static constexpr ScriptFieldType value = ScriptFieldType::Vector4;
};
template<>
struct ScriptFieldTypeResolver<GameObjectReference> {
static constexpr ScriptFieldType value = ScriptFieldType::GameObject;
};
template<>
struct ScriptFieldTypeResolver<ComponentReference> {
static constexpr ScriptFieldType value = ScriptFieldType::Component;
};
class ScriptFieldStorage {
public:
template<typename T>
bool SetFieldValue(const std::string& fieldName, const T& value) {
using ValueType = std::decay_t<T>;
return SetFieldValue(fieldName, ScriptFieldTypeResolver<ValueType>::value, ScriptFieldValue(ValueType(value)));
}
bool SetFieldValue(const std::string& fieldName, const char* value) {
return SetFieldValue<std::string>(fieldName, value ? std::string(value) : std::string());
}
bool SetFieldValue(const std::string& fieldName, ScriptFieldType type, const ScriptFieldValue& value);
template<typename T>
bool TryGetFieldValue(const std::string& fieldName, T& outValue) const {
const StoredScriptField* field = FindField(fieldName);
if (!field) {
return false;
}
const auto* storedValue = std::get_if<std::decay_t<T>>(&field->value);
if (!storedValue) {
return false;
}
outValue = *storedValue;
return true;
}
const StoredScriptField* FindField(const std::string& fieldName) const;
StoredScriptField* FindField(const std::string& fieldName);
bool Contains(const std::string& fieldName) const;
bool Remove(const std::string& fieldName);
void Clear();
size_t GetFieldCount() const { return m_fields.size(); }
std::vector<std::string> GetFieldNames() const;
std::string SerializeToString() const;
void DeserializeFromString(const std::string& data);
void Serialize(std::ostream& os) const;
void Deserialize(std::istream& is);
private:
std::unordered_map<std::string, StoredScriptField> m_fields;
};
} // namespace Scripting
} // namespace XCEngine