2026-03-26 20:14:58 +08:00
|
|
|
#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;
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-03 16:51:42 +08:00
|
|
|
template<>
|
|
|
|
|
struct ScriptFieldTypeResolver<ComponentReference> {
|
|
|
|
|
static constexpr ScriptFieldType value = ScriptFieldType::Component;
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-26 20:14:58 +08:00
|
|
|
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
|