Refactored enum serialization/deserialization
This commit is contained in:
parent
44d18d00f8
commit
8d2d100376
|
@ -97,7 +97,7 @@ set(SOURCE_FILES
|
|||
src/Phone.cpp src/Phone.h
|
||||
src/Shape.cpp src/Shape.h
|
||||
src/centiseconds.cpp src/centiseconds.h
|
||||
src/enumTools.h
|
||||
src/EnumConverter.h
|
||||
src/mouthAnimation.cpp src/mouthAnimation.h
|
||||
src/phoneExtraction.cpp src/phoneExtraction.h
|
||||
src/platformTools.cpp src/platformTools.h
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <format.h>
|
||||
|
||||
template<typename TEnum>
|
||||
class EnumConverter {
|
||||
public:
|
||||
EnumConverter() :
|
||||
initialized(false)
|
||||
{}
|
||||
|
||||
virtual ~EnumConverter() = default;
|
||||
|
||||
virtual boost::optional<std::string> tryToString(TEnum value) {
|
||||
initialize();
|
||||
auto it = valueToNameMap.find(value);
|
||||
return it != valueToNameMap.end()
|
||||
? it->second
|
||||
: boost::optional<std::string>();
|
||||
}
|
||||
|
||||
std::string toString(TEnum value) {
|
||||
initialize();
|
||||
auto result = tryToString(value);
|
||||
if (!result) {
|
||||
auto numericValue = static_cast<typename std::underlying_type<TEnum>::type>(value);
|
||||
throw std::invalid_argument(fmt::format("{} is not a valid {} value.", numericValue, typeName));
|
||||
}
|
||||
|
||||
return result.value();
|
||||
}
|
||||
|
||||
virtual boost::optional<TEnum> tryParse(const std::string& s) {
|
||||
initialize();
|
||||
auto it = lowerCaseNameToValueMap.find(boost::algorithm::to_lower_copy(s));
|
||||
return it != lowerCaseNameToValueMap.end()
|
||||
? it->second
|
||||
: boost::optional<TEnum>();
|
||||
}
|
||||
|
||||
TEnum parse(const std::string& s) {
|
||||
initialize();
|
||||
auto result = tryParse(s);
|
||||
if (!result) {
|
||||
throw std::invalid_argument(fmt::format("{} is not a valid {} value.", s, typeName));
|
||||
}
|
||||
|
||||
return result.value();
|
||||
}
|
||||
|
||||
std::ostream& write(std::ostream& stream, TEnum value) {
|
||||
return stream << toString(value);
|
||||
}
|
||||
|
||||
std::istream& read(std::istream& stream, TEnum& value) {
|
||||
std::string name;
|
||||
stream >> name;
|
||||
value = parse(name);
|
||||
return stream;
|
||||
}
|
||||
|
||||
const std::vector<TEnum>& getValues() {
|
||||
initialize();
|
||||
return values;
|
||||
}
|
||||
|
||||
protected:
|
||||
using member_data = std::vector<std::pair<TEnum, std::string>>;
|
||||
|
||||
virtual std::string getTypeName() = 0;
|
||||
virtual member_data getMemberData() = 0;
|
||||
|
||||
private:
|
||||
void initialize() {
|
||||
if (initialized) return;
|
||||
|
||||
typeName = getTypeName();
|
||||
for (const auto& pair : getMemberData()) {
|
||||
TEnum value = pair.first;
|
||||
std::string name = pair.second;
|
||||
lowerCaseNameToValueMap[boost::algorithm::to_lower_copy(name)] = value;
|
||||
valueToNameMap[value] = name;
|
||||
values.push_back(value);
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
bool initialized;
|
||||
std::string typeName;
|
||||
std::map<std::string, TEnum> lowerCaseNameToValueMap;
|
||||
std::map<TEnum, std::string> valueToNameMap;
|
||||
std::vector<TEnum> values;
|
||||
};
|
|
@ -1,41 +1,35 @@
|
|||
#include "Exporter.h"
|
||||
#include <logging.h>
|
||||
#include <vector>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
#include <tools.h>
|
||||
|
||||
using std::string;
|
||||
using boost::property_tree::ptree;
|
||||
using std::vector;
|
||||
using std::tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
template <>
|
||||
const string& getEnumTypeName<ExportFormat>() {
|
||||
static const string name = "ExportFormat";
|
||||
return name;
|
||||
ExportFormatConverter& ExportFormatConverter::get() {
|
||||
static ExportFormatConverter converter;
|
||||
return converter;
|
||||
}
|
||||
|
||||
template <>
|
||||
const vector<tuple<ExportFormat, string>>& getEnumMembers<ExportFormat>() {
|
||||
static const vector<tuple<ExportFormat, string>> values = {
|
||||
make_tuple(ExportFormat::TSV, "TSV"),
|
||||
make_tuple(ExportFormat::XML, "XML"),
|
||||
make_tuple(ExportFormat::JSON, "JSON")
|
||||
string ExportFormatConverter::getTypeName() {
|
||||
return "ExportFormat";
|
||||
}
|
||||
|
||||
EnumConverter<ExportFormat>::member_data ExportFormatConverter::getMemberData() {
|
||||
return member_data{
|
||||
{ ExportFormat::TSV, "TSV" },
|
||||
{ ExportFormat::XML, "XML" },
|
||||
{ ExportFormat::JSON, "JSON" }
|
||||
};
|
||||
return values;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, ExportFormat value) {
|
||||
return stream << enumToString(value);
|
||||
return ExportFormatConverter::get().write(stream, value);
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& stream, ExportFormat& value) {
|
||||
string name;
|
||||
stream >> name;
|
||||
value = parseEnum<ExportFormat>(name);
|
||||
return stream;
|
||||
return ExportFormatConverter::get().read(stream, value);
|
||||
}
|
||||
|
||||
// Makes sure there is at least one mouth shape
|
||||
|
|
|
@ -11,11 +11,13 @@ enum class ExportFormat {
|
|||
JSON
|
||||
};
|
||||
|
||||
template<>
|
||||
const std::string& getEnumTypeName<ExportFormat>();
|
||||
|
||||
template<>
|
||||
const std::vector<std::tuple<ExportFormat, std::string>>& getEnumMembers<ExportFormat>();
|
||||
class ExportFormatConverter : public EnumConverter<ExportFormat> {
|
||||
public:
|
||||
static ExportFormatConverter& get();
|
||||
protected:
|
||||
std::string getTypeName() override;
|
||||
member_data getMemberData() override;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, ExportFormat value);
|
||||
|
||||
|
|
116
src/Phone.cpp
116
src/Phone.cpp
|
@ -2,78 +2,72 @@
|
|||
#include "Phone.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
template <>
|
||||
const string& getEnumTypeName<Phone>() {
|
||||
static const string name = "Shape";
|
||||
return name;
|
||||
PhoneConverter& PhoneConverter::get() {
|
||||
static PhoneConverter converter;
|
||||
return converter;
|
||||
}
|
||||
|
||||
template <>
|
||||
const vector<tuple<Phone, string>>& getEnumMembers<Phone>() {
|
||||
static const vector<tuple<Phone, string>> values = {
|
||||
make_tuple(Phone::None, "None"),
|
||||
make_tuple(Phone::Unknown, "Unknown"),
|
||||
make_tuple(Phone::AO, "AO"),
|
||||
make_tuple(Phone::AA, "AA"),
|
||||
make_tuple(Phone::IY, "IY"),
|
||||
make_tuple(Phone::UW, "UW"),
|
||||
make_tuple(Phone::EH, "EH"),
|
||||
make_tuple(Phone::IH, "IH"),
|
||||
make_tuple(Phone::UH, "UH"),
|
||||
make_tuple(Phone::AH, "AH"),
|
||||
make_tuple(Phone::AE, "AE"),
|
||||
make_tuple(Phone::EY, "EY"),
|
||||
make_tuple(Phone::AY, "AY"),
|
||||
make_tuple(Phone::OW, "OW"),
|
||||
make_tuple(Phone::AW, "AW"),
|
||||
make_tuple(Phone::OY, "OY"),
|
||||
make_tuple(Phone::ER, "ER"),
|
||||
make_tuple(Phone::P, "P"),
|
||||
make_tuple(Phone::B, "B"),
|
||||
make_tuple(Phone::T, "T"),
|
||||
make_tuple(Phone::D, "D"),
|
||||
make_tuple(Phone::K, "K"),
|
||||
make_tuple(Phone::G, "G"),
|
||||
make_tuple(Phone::CH, "CH"),
|
||||
make_tuple(Phone::JH, "JH"),
|
||||
make_tuple(Phone::F, "F"),
|
||||
make_tuple(Phone::V, "V"),
|
||||
make_tuple(Phone::TH, "TH"),
|
||||
make_tuple(Phone::DH, "DH"),
|
||||
make_tuple(Phone::S, "S"),
|
||||
make_tuple(Phone::Z, "Z"),
|
||||
make_tuple(Phone::SH, "SH"),
|
||||
make_tuple(Phone::ZH, "ZH"),
|
||||
make_tuple(Phone::HH, "HH"),
|
||||
make_tuple(Phone::M, "M"),
|
||||
make_tuple(Phone::N, "N"),
|
||||
make_tuple(Phone::NG, "NG"),
|
||||
make_tuple(Phone::L, "L"),
|
||||
make_tuple(Phone::R, "R"),
|
||||
make_tuple(Phone::Y, "Y"),
|
||||
make_tuple(Phone::W, "W")
|
||||
string PhoneConverter::getTypeName() {
|
||||
return "Phone";
|
||||
}
|
||||
|
||||
EnumConverter<Phone>::member_data PhoneConverter::getMemberData() {
|
||||
return member_data{
|
||||
{ Phone::None, "None" },
|
||||
{ Phone::Unknown, "Unknown" },
|
||||
{ Phone::AO, "AO" },
|
||||
{ Phone::AA, "AA" },
|
||||
{ Phone::IY, "IY" },
|
||||
{ Phone::UW, "UW" },
|
||||
{ Phone::EH, "EH" },
|
||||
{ Phone::IH, "IH" },
|
||||
{ Phone::UH, "UH" },
|
||||
{ Phone::AH, "AH" },
|
||||
{ Phone::AE, "AE" },
|
||||
{ Phone::EY, "EY" },
|
||||
{ Phone::AY, "AY" },
|
||||
{ Phone::OW, "OW" },
|
||||
{ Phone::AW, "AW" },
|
||||
{ Phone::OY, "OY" },
|
||||
{ Phone::ER, "ER" },
|
||||
{ Phone::P, "P" },
|
||||
{ Phone::B, "B" },
|
||||
{ Phone::T, "T" },
|
||||
{ Phone::D, "D" },
|
||||
{ Phone::K, "K" },
|
||||
{ Phone::G, "G" },
|
||||
{ Phone::CH, "CH" },
|
||||
{ Phone::JH, "JH" },
|
||||
{ Phone::F, "F" },
|
||||
{ Phone::V, "V" },
|
||||
{ Phone::TH, "TH" },
|
||||
{ Phone::DH, "DH" },
|
||||
{ Phone::S, "S" },
|
||||
{ Phone::Z, "Z" },
|
||||
{ Phone::SH, "SH" },
|
||||
{ Phone::ZH, "ZH" },
|
||||
{ Phone::HH, "HH" },
|
||||
{ Phone::M, "M" },
|
||||
{ Phone::N, "N" },
|
||||
{ Phone::NG, "NG" },
|
||||
{ Phone::L, "L" },
|
||||
{ Phone::R, "R" },
|
||||
{ Phone::Y, "Y" },
|
||||
{ Phone::W, "W" }
|
||||
};
|
||||
return values;
|
||||
}
|
||||
|
||||
template<>
|
||||
Phone parseEnum(const string& s) {
|
||||
boost::optional<Phone> PhoneConverter::tryParse(const string& s) {
|
||||
if (s == "SIL") return Phone::None;
|
||||
Phone result;
|
||||
return tryParseEnum(s, result) ? result : Phone::Unknown;
|
||||
auto result = EnumConverter<Phone>::tryParse(s);
|
||||
return result ? result : Phone::Unknown;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, Phone value) {
|
||||
return stream << enumToString(value);
|
||||
return PhoneConverter::get().write(stream, value);
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& stream, Phone& value) {
|
||||
string name;
|
||||
stream >> name;
|
||||
value = parseEnum<Phone>(name);
|
||||
return stream;
|
||||
return PhoneConverter::get().read(stream, value);
|
||||
}
|
||||
|
|
19
src/Phone.h
19
src/Phone.h
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "enumTools.h"
|
||||
#include "EnumConverter.h"
|
||||
|
||||
// Defines a subset of the Arpabet
|
||||
enum class Phone {
|
||||
|
@ -71,14 +71,15 @@ enum class Phone {
|
|||
W // [w] as in [w]ay
|
||||
};
|
||||
|
||||
template<>
|
||||
const std::string& getEnumTypeName<Phone>();
|
||||
|
||||
template<>
|
||||
const std::vector<std::tuple<Phone, std::string>>& getEnumMembers<Phone>();
|
||||
|
||||
template<>
|
||||
Phone parseEnum(const std::string& s);
|
||||
class PhoneConverter : public EnumConverter<Phone> {
|
||||
public:
|
||||
static PhoneConverter& get();
|
||||
protected:
|
||||
std::string getTypeName() override;
|
||||
member_data getMemberData() override;
|
||||
public:
|
||||
boost::optional<Phone> tryParse(const std::string& s) override;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, Phone value);
|
||||
|
||||
|
|
|
@ -1,40 +1,33 @@
|
|||
#include "Shape.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
template <>
|
||||
const string& getEnumTypeName<Shape>() {
|
||||
static const string name = "Shape";
|
||||
return name;
|
||||
ShapeConverter& ShapeConverter::get() {
|
||||
static ShapeConverter converter;
|
||||
return converter;
|
||||
}
|
||||
|
||||
template <>
|
||||
const vector<tuple<Shape, string>>& getEnumMembers<Shape>() {
|
||||
static const vector<tuple<Shape, string>> values = {
|
||||
make_tuple(Shape::A, "A"),
|
||||
make_tuple(Shape::B, "B"),
|
||||
make_tuple(Shape::C, "C"),
|
||||
make_tuple(Shape::D, "D"),
|
||||
make_tuple(Shape::E, "E"),
|
||||
make_tuple(Shape::F, "F"),
|
||||
make_tuple(Shape::G, "G"),
|
||||
make_tuple(Shape::H, "H")
|
||||
string ShapeConverter::getTypeName() {
|
||||
return "Shape";
|
||||
}
|
||||
|
||||
EnumConverter<Shape>::member_data ShapeConverter::getMemberData() {
|
||||
return member_data{
|
||||
{ Shape::A, "A" },
|
||||
{ Shape::B, "B" },
|
||||
{ Shape::C, "C" },
|
||||
{ Shape::D, "D" },
|
||||
{ Shape::E, "E" },
|
||||
{ Shape::F, "F" },
|
||||
{ Shape::G, "G" },
|
||||
{ Shape::H, "H" }
|
||||
};
|
||||
return values;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, Shape value) {
|
||||
return stream << enumToString(value);
|
||||
return ShapeConverter::get().write(stream, value);
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& stream, Shape& value) {
|
||||
string name;
|
||||
stream >> name;
|
||||
value = parseEnum<Shape>(name);
|
||||
return stream;
|
||||
return ShapeConverter::get().read(stream, value);
|
||||
}
|
||||
|
|
15
src/Shape.h
15
src/Shape.h
|
@ -1,8 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "enumTools.h"
|
||||
#include "EnumConverter.h"
|
||||
|
||||
// The classic Hanna-Barbera mouth shapes A-F phus the common supplements G-H
|
||||
// For reference, see http://sunewatts.dk/lipsync/lipsync/article_02.php
|
||||
|
@ -19,11 +18,13 @@ enum class Shape {
|
|||
H // L
|
||||
};
|
||||
|
||||
template<>
|
||||
const std::string& getEnumTypeName<Shape>();
|
||||
|
||||
template<>
|
||||
const std::vector<std::tuple<Shape, std::string>>& getEnumMembers<Shape>();
|
||||
class ShapeConverter : public EnumConverter<Shape> {
|
||||
public:
|
||||
static ShapeConverter& get();
|
||||
protected:
|
||||
std::string getTypeName() override;
|
||||
member_data getMemberData() override;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, Shape value);
|
||||
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <map>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <exception>
|
||||
#include <format.h>
|
||||
|
||||
template<typename T>
|
||||
const std::string& getEnumTypeName();
|
||||
|
||||
template<typename T>
|
||||
const std::vector<std::tuple<T, std::string>>& getEnumMembers();
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
std::map<std::string, T> createLowerCaseNameToValueMap() {
|
||||
std::map<std::string, T> map;
|
||||
for (const auto& pair : getEnumMembers<T>()) {
|
||||
map[boost::algorithm::to_lower_copy(std::get<std::string>(pair))] = std::get<T>(pair);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::map<T, std::string> createValueToNameMap() {
|
||||
std::map<T, std::string> map;
|
||||
for (const auto& pair : getEnumMembers<T>()) {
|
||||
map[std::get<T>(pair)] = std::get<std::string>(pair);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> getEnumValues() {
|
||||
std::vector<T> result;
|
||||
for (const auto& pair : getEnumMembers<T>()) {
|
||||
result.push_back(std::get<T>(pair));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool tryParseEnum(const std::string& s, T& result) {
|
||||
static const std::map<std::string, T> lookup = detail::createLowerCaseNameToValueMap<T>();
|
||||
auto it = lookup.find(boost::algorithm::to_lower_copy(s));
|
||||
if (it == lookup.end()) return false;
|
||||
|
||||
result = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T parseEnum(const std::string& s) {
|
||||
T result;
|
||||
if (!tryParseEnum(s, result)) {
|
||||
throw std::invalid_argument(fmt::format("{} is not a valid {} value.", s, getEnumTypeName<T>()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool tryEnumToString(T value, std::string& result) {
|
||||
static const std::map<T, std::string> lookup = detail::createValueToNameMap<T>();
|
||||
auto it = lookup.find(value);
|
||||
if (it == lookup.end()) return false;
|
||||
|
||||
result = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string enumToString(T value) {
|
||||
std::string result;
|
||||
if (!tryEnumToString(value, result)) {
|
||||
throw std::invalid_argument(fmt::format(
|
||||
"{} is not a valid {} value.",
|
||||
static_cast<typename std::underlying_type<T>::type>(value),
|
||||
getEnumTypeName<T>()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const std::vector<T>& getEnumValues() {
|
||||
static const auto result = detail::getEnumValues<T>();
|
||||
return result;
|
||||
}
|
|
@ -5,39 +5,35 @@
|
|||
using namespace logging;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::tuple;
|
||||
using std::make_tuple;
|
||||
using std::shared_ptr;
|
||||
using std::lock_guard;
|
||||
|
||||
template <>
|
||||
const string& getEnumTypeName<Level>() {
|
||||
static const string name = "LogLevel";
|
||||
return name;
|
||||
LevelConverter& LevelConverter::get() {
|
||||
static LevelConverter converter;
|
||||
return converter;
|
||||
}
|
||||
|
||||
template <>
|
||||
const vector<tuple<Level, string>>& getEnumMembers<Level>() {
|
||||
static const vector<tuple<Level, string>> values = {
|
||||
make_tuple(Level::Trace, "Trace"),
|
||||
make_tuple(Level::Debug, "Debug"),
|
||||
make_tuple(Level::Info, "Info"),
|
||||
make_tuple(Level::Warn, "Warn"),
|
||||
make_tuple(Level::Error, "Error"),
|
||||
make_tuple(Level::Fatal, "Fatal")
|
||||
string LevelConverter::getTypeName() {
|
||||
return "Level";
|
||||
}
|
||||
|
||||
EnumConverter<Level>::member_data LevelConverter::getMemberData() {
|
||||
return member_data {
|
||||
{ Level::Trace, "Trace" },
|
||||
{ Level::Debug, "Debug" },
|
||||
{ Level::Info, "Info" },
|
||||
{ Level::Warn, "Warn" },
|
||||
{ Level::Error, "Error" },
|
||||
{ Level::Fatal, "Fatal" }
|
||||
};
|
||||
return values;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, Level value) {
|
||||
return stream << enumToString(value);
|
||||
std::ostream& logging::operator<<(std::ostream& stream, Level value) {
|
||||
return LevelConverter::get().write(stream, value);
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& stream, Level& value) {
|
||||
string name;
|
||||
stream >> name;
|
||||
value = parseEnum<Level>(name);
|
||||
return stream;
|
||||
std::istream& logging::operator>>(std::istream& stream, Level& value) {
|
||||
return LevelConverter::get().read(stream, value);
|
||||
}
|
||||
|
||||
Entry::Entry(Level level, const string& message) :
|
||||
|
@ -77,7 +73,7 @@ void StreamSink::receive(const Entry& entry) {
|
|||
}
|
||||
|
||||
StdErrSink::StdErrSink(shared_ptr<Formatter> formatter) :
|
||||
StreamSink(std::shared_ptr<std::ostream>(&std::cerr, [](void*){}), formatter)
|
||||
StreamSink(std::shared_ptr<std::ostream>(&std::cerr, [](void*) {}), formatter)
|
||||
{}
|
||||
|
||||
PausableSink::PausableSink(shared_ptr<Sink> innerSink) :
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <tuple>
|
||||
#include "enumTools.h"
|
||||
#include "tools.h"
|
||||
#include "Timed.h"
|
||||
#include "EnumConverter.h"
|
||||
|
||||
namespace logging {
|
||||
|
||||
|
@ -20,19 +19,17 @@ namespace logging {
|
|||
EndSentinel
|
||||
};
|
||||
|
||||
}
|
||||
class LevelConverter : public EnumConverter<Level> {
|
||||
public:
|
||||
static LevelConverter& get();
|
||||
protected:
|
||||
std::string getTypeName() override;
|
||||
member_data getMemberData() override;
|
||||
};
|
||||
|
||||
template<>
|
||||
const std::string& getEnumTypeName<logging::Level>();
|
||||
std::ostream& operator<<(std::ostream& stream, Level value);
|
||||
|
||||
template<>
|
||||
const std::vector<std::tuple<logging::Level, std::string>>& getEnumMembers<logging::Level>();
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, logging::Level value);
|
||||
|
||||
std::istream& operator>>(std::istream& stream, logging::Level& value);
|
||||
|
||||
namespace logging {
|
||||
std::istream& operator>>(std::istream& stream, Level& value);
|
||||
|
||||
struct Entry {
|
||||
Entry(Level level, const std::string& message);
|
||||
|
|
|
@ -84,12 +84,12 @@ int main(int argc, char *argv[]) {
|
|||
tclap::CmdLine cmd(appName, argumentValueSeparator, appVersion);
|
||||
cmd.setExceptionHandling(false);
|
||||
cmd.setOutput(new NiceCmdLineOutput());
|
||||
auto logLevels = vector<logging::Level>(getEnumValues<logging::Level>());
|
||||
auto logLevels = vector<logging::Level>(logging::LevelConverter::get().getValues());
|
||||
tclap::ValuesConstraint<logging::Level> logLevelConstraint(logLevels);
|
||||
tclap::ValueArg<logging::Level> logLevel("", "logLevel", "The minimum log level to log", false, logging::Level::Debug, &logLevelConstraint, cmd);
|
||||
tclap::ValueArg<string> logFileName("", "logFile", "The log file path.", false, string(), "string", cmd);
|
||||
tclap::ValueArg<string> dialog("d", "dialog", "The text of the dialog.", false, string(), "string", cmd);
|
||||
auto exportFormats = vector<ExportFormat>(getEnumValues<ExportFormat>());
|
||||
auto exportFormats = vector<ExportFormat>(ExportFormatConverter::get().getValues());
|
||||
tclap::ValuesConstraint<ExportFormat> exportFormatConstraint(exportFormats);
|
||||
tclap::ValueArg<ExportFormat> exportFormat("f", "exportFormat", "The export format.", false, ExportFormat::TSV, &exportFormatConstraint, cmd);
|
||||
tclap::UnlabeledValueArg<string> inputFileName("inputFile", "The input file. Must be a sound file in WAVE format.", true, "", "string", cmd);
|
||||
|
|
|
@ -275,7 +275,7 @@ Timeline<Phone> getPhoneAlignment(const vector<s3wid_t>& wordIds, unique_ptr<Aud
|
|||
// Add entry
|
||||
centiseconds start(phoneEntry->start);
|
||||
centiseconds duration(phoneEntry->duration);
|
||||
Timed<Phone> timedPhone(start, start + duration, parseEnum<Phone>(phoneName));
|
||||
Timed<Phone> timedPhone(start, start + duration, PhoneConverter::get().parse(phoneName));
|
||||
result.set(timedPhone);
|
||||
|
||||
logging::logTimedEvent("phone", timedPhone);
|
||||
|
|
Loading…
Reference in New Issue