Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
graphite/engine/utility/interdata.hpp
2024-01-03 16:05:02 -05:00

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;
};