class ISerializable
{
public:
virtual ~ISerializable() = default;
virtual void Serialize(const std::filesystem::path& path,
const std::any& data) const = 0;
virtual std::any Deserialize(const std::filesystem::path& path) const = 0;
};
struct SerializationData {};
class ISerializable
{
public:
virtual ~ISerializable() = default;
virtual void Serialize(const std::filesystem::path& path,
const SerializationData* data) const = 0;
virtual std::unique_ptr<SerializationData> Deserialize(
const std::filesystem::path& path) const = 0;
};
struct SettingsData: SerializationData
{
size_t WindowWidth = 400;
size_t WindowHeight = 800;
size_t ActiveResolutionIndex = 1;
size_t SoundEffectVolume = 100;
size_t MusicVolume = 100;
std::string ToString() const;
void Convert(const std::vector<std::string>& values);
};
class SettinsDataSerializer: public ISerializable
{
public:
static constexpr char Delimetr = '\n';
public:
std::filesystem::path GetDefaultFilePath() const;
std::filesystem::path GetFileExtension() const;
void Serialize(const std::filesystem::path& path,
const SerializationData* data) const override;
void Serialize(const SerializationData* data) const;
std::unique_ptr<SerializationData> Deserialize(
const std::filesystem::path& path) const override;
std::unique_ptr<SerializationData> Deserialize() const;
private:
bool IsPathRelevant(const std::filesystem::path& path) const;
};
std::any
используешь не по назначению. SerializationData
- это костыль как есть и назван отвратно. Какой шаблон проектирования применяешь - тебе и самому не ясно. А применяешь ты его не по месту и полностью неправильно.class IStringConvertable
{
public:
virtual ~IStringConvertable() = default;
virtual std::string Convert() const = 0;
virtual void ConvertBack(const std::string& data) = 0;
};
class ISerializer
{
public:
virtual ~ISerializer() = default;
virtual void Serialize(const std::filesystem::path& path,
const IStringConvertable& data) const = 0;
virtual void Deserialize(const std::filesystem::path& path,
IStringConvertable& data) const = 0;
};
class Serializer: public ISerializer
{
public:
void Serialize(const std::filesystem::path& path,
const IStringConvertable& data) const override;
void Deserialize(const std::filesystem::path& path,
IStringConvertable& data) const override;
template<typename T> requires std::derived_from<T, IStringConvertable>
T Deserialize(const std::filesystem::path& path) const
{
T data = {};
Deserialize(path, data);
return data;
}
};
void Serializer::Serialize(const std::filesystem::path& path,
const IStringConvertable& data) const
{
if(std::ofstream stream(path); stream.is_open())
{
stream << data.Convert();
}
}
void Serializer::Deserialize(const std::filesystem::path& path,
IStringConvertable& data) const
{
if(std::ifstream stream(path); stream.is_open())
{
std::string buffer;
stream >> buffer;
data.ConvertBack(buffer);
}
}
class IRangeSerializer
{
public:
virtual ~IRangeSerializer() = default;
virtual void Serialize(const std::filesystem::path& path,
const std::span<IStringConvertable*> range,
const std::string& delimetr) const = 0;
virtual void Deserialize(const std::filesystem::path& path,
std::span<IStringConvertable*> range,
const std::string& delimetr) const = 0;
};
const std::string& delimetr
- зачем эту сугубо приватную тонкость формата знать внешнему коду?