283 lines
No EOL
6.2 KiB
C++
283 lines
No EOL
6.2 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <map>
|
|
#include <json.hpp>
|
|
#include <glm/glm.hpp>
|
|
|
|
#include "utility.hpp"
|
|
|
|
/*
|
|
* Our own intermediate data solution (used for saving/loading, etc)
|
|
*/
|
|
|
|
class IntermediateType
|
|
{
|
|
public:
|
|
enum Type
|
|
{
|
|
String,
|
|
SignedInteger,
|
|
UnsignedInteger,
|
|
Float,
|
|
Vec3,
|
|
Vec2,
|
|
Quat,
|
|
Bool
|
|
};
|
|
|
|
struct Data
|
|
{
|
|
std::string m_string;
|
|
signed int m_integer;
|
|
unsigned int m_unsignedInteger;
|
|
float m_float;
|
|
glm::vec3 m_vec3;
|
|
glm::vec2 m_vec2;
|
|
glm::quat m_quat;
|
|
bool m_bool;
|
|
};
|
|
|
|
IntermediateType() {}
|
|
~IntermediateType() {}
|
|
|
|
IntermediateType(const IntermediateType& copy)
|
|
{
|
|
m_data = copy.m_data;
|
|
m_type = copy.m_type;
|
|
}
|
|
|
|
IntermediateType(const std::string& value)
|
|
{
|
|
m_data.m_string = value;
|
|
m_type = String;
|
|
}
|
|
|
|
IntermediateType(signed int value)
|
|
{
|
|
m_data.m_integer = value;
|
|
m_type = SignedInteger;
|
|
}
|
|
|
|
IntermediateType(unsigned int value)
|
|
{
|
|
m_data.m_unsignedInteger = value;
|
|
m_type = UnsignedInteger;
|
|
}
|
|
|
|
IntermediateType(float value)
|
|
{
|
|
m_data.m_float = value;
|
|
m_type = Float;
|
|
}
|
|
|
|
IntermediateType(glm::vec3 value)
|
|
{
|
|
m_data.m_vec3 = value;
|
|
m_type = Vec3;
|
|
}
|
|
|
|
IntermediateType(glm::vec2 value)
|
|
{
|
|
m_data.m_vec2 = value;
|
|
m_type = Vec2;
|
|
}
|
|
|
|
IntermediateType(glm::quat value)
|
|
{
|
|
m_data.m_quat = value;
|
|
m_type = Quat;
|
|
}
|
|
|
|
IntermediateType(bool value)
|
|
{
|
|
m_data.m_bool = value;
|
|
m_type = Bool;
|
|
}
|
|
|
|
IntermediateType& operator=(const IntermediateType& rhs)
|
|
{
|
|
m_data = rhs.m_data;
|
|
m_type = rhs.m_type;
|
|
|
|
return *this;
|
|
}
|
|
|
|
operator std::string&()
|
|
{
|
|
return m_data.m_string;
|
|
}
|
|
|
|
operator signed int&()
|
|
{
|
|
return m_data.m_integer;
|
|
}
|
|
|
|
operator unsigned int&()
|
|
{
|
|
return m_data.m_unsignedInteger;
|
|
}
|
|
|
|
operator float&()
|
|
{
|
|
//workaround:
|
|
//our json library does NOT guarantee floats will be stored as floats
|
|
if(m_type == SignedInteger)
|
|
{
|
|
m_data.m_float = static_cast<float>(m_data.m_integer);
|
|
}
|
|
else if(m_type == UnsignedInteger)
|
|
{
|
|
m_data.m_float = static_cast<float>(m_data.m_unsignedInteger);
|
|
}
|
|
|
|
return m_data.m_float;
|
|
}
|
|
|
|
operator glm::vec3&()
|
|
{
|
|
return m_data.m_vec3;
|
|
}
|
|
|
|
operator glm::vec2&()
|
|
{
|
|
return m_data.m_vec2;
|
|
}
|
|
|
|
operator glm::quat&()
|
|
{
|
|
return m_data.m_quat;
|
|
}
|
|
|
|
operator bool&()
|
|
{
|
|
return m_data.m_bool;
|
|
}
|
|
|
|
Type GetType() const
|
|
{
|
|
return m_type;
|
|
}
|
|
|
|
Data GetData() const
|
|
{
|
|
return m_data;
|
|
}
|
|
|
|
private:
|
|
Data m_data;
|
|
Type m_type;
|
|
};
|
|
|
|
class IntermediateData
|
|
{
|
|
public:
|
|
IntermediateData() {}
|
|
~IntermediateData() {}
|
|
|
|
IntermediateData(const IntermediateData& inData)
|
|
{
|
|
data = inData.data;
|
|
}
|
|
|
|
IntermediateData(nlohmann::json json)
|
|
{
|
|
for(auto it = json.begin(); it != json.end(); it++)
|
|
{
|
|
std::string key = it.key();
|
|
|
|
if(it.value().is_number_integer())
|
|
{
|
|
int val = it.value();
|
|
data[key] = val;
|
|
}
|
|
|
|
if(it.value().is_boolean())
|
|
{
|
|
bool val = it.value();
|
|
data[key] = val;
|
|
}
|
|
|
|
//crappy detection of vectors (since they are technically stored in strings)
|
|
if(it.value().is_string())
|
|
{
|
|
std::string s = it.value();
|
|
|
|
size_t n = std::count(s.begin(), s.end(), ',');
|
|
switch(n)
|
|
{
|
|
case 1:
|
|
data[key] = Utility::StringToVec2(s.c_str()); //vec2
|
|
break;
|
|
case 2:
|
|
data[key] = Utility::StringToVec3(s); //vec3
|
|
break;
|
|
case 3:
|
|
data[key] = Utility::StringToQuat(s.c_str()); //quat
|
|
break;
|
|
default:
|
|
{
|
|
if(Utility::IsFloat(s))
|
|
{
|
|
data[key] = stof(s);
|
|
}
|
|
else
|
|
{
|
|
data[key] = s; //if its actually a string
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
nlohmann::json GetJSON()
|
|
{
|
|
nlohmann::json tmp;
|
|
for(auto itr : data)
|
|
{
|
|
switch(itr.second.GetType())
|
|
{
|
|
case IntermediateType::String:
|
|
tmp[itr.first] = itr.second.GetData().m_string;
|
|
break;
|
|
case IntermediateType::SignedInteger:
|
|
tmp[itr.first] = itr.second.GetData().m_integer;
|
|
break;
|
|
case IntermediateType::UnsignedInteger:
|
|
tmp[itr.first] = itr.second.GetData().m_unsignedInteger;
|
|
break;
|
|
case IntermediateType::Float:
|
|
tmp[itr.first] = itr.second.GetData().m_float;
|
|
break;
|
|
case IntermediateType::Vec3:
|
|
tmp[itr.first] = Utility::Vec3ToString(itr.second);
|
|
break;
|
|
case IntermediateType::Vec2:
|
|
tmp[itr.first] = Utility::Vec2ToString(itr.second);
|
|
break;
|
|
case IntermediateType::Quat:
|
|
tmp[itr.first] = Utility::QuatToString(itr.second);
|
|
break;
|
|
case IntermediateType::Bool:
|
|
tmp[itr.first] = itr.second.GetData().m_bool;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
|
|
auto& operator[](const std::string& key)
|
|
{
|
|
return data[key];
|
|
}
|
|
|
|
bool operator!=(IntermediateData& b)
|
|
{
|
|
return GetJSON() == b.GetJSON();
|
|
}
|
|
|
|
std::map<std::string, IntermediateType> data;
|
|
}; |