2018-07-14 06:06:33 +00:00
|
|
|
#include "amuse/Common.hpp"
|
|
|
|
#include "logvisor/logvisor.hpp"
|
|
|
|
|
2018-08-07 07:09:23 +00:00
|
|
|
using namespace std::literals;
|
|
|
|
|
2018-07-14 06:06:33 +00:00
|
|
|
namespace amuse
|
|
|
|
{
|
|
|
|
static logvisor::Module Log("amuse");
|
|
|
|
|
2018-08-25 08:34:04 +00:00
|
|
|
bool Copy(const SystemChar* from, const SystemChar* to)
|
|
|
|
{
|
|
|
|
#if _WIN32
|
|
|
|
return CopyFileW(from, to, FALSE) != 0;
|
|
|
|
#else
|
|
|
|
FILE* fi = fopen(from, "rb");
|
|
|
|
if (!fi)
|
|
|
|
return false;
|
|
|
|
FILE* fo = fopen(to, "wb");
|
|
|
|
if (!fo)
|
|
|
|
{
|
|
|
|
fclose(fi);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
std::unique_ptr<uint8_t[]> buf(new uint8_t[65536]);
|
|
|
|
size_t readSz = 0;
|
|
|
|
while ((readSz = fread(buf.get(), 1, 65536, fi)))
|
|
|
|
fwrite(buf.get(), 1, readSz, fo);
|
|
|
|
fclose(fi);
|
|
|
|
fclose(fo);
|
|
|
|
struct stat theStat;
|
|
|
|
if (::stat(from, &theStat))
|
|
|
|
return true;
|
2018-08-28 03:48:53 +00:00
|
|
|
#if __APPLE__
|
|
|
|
struct timespec times[] = { theStat.st_atimespec, theStat.st_mtimespec };
|
|
|
|
#else
|
2018-08-25 08:34:04 +00:00
|
|
|
struct timespec times[] = { theStat.st_atim, theStat.st_mtim };
|
2018-08-28 03:48:53 +00:00
|
|
|
#endif
|
2018-08-25 08:34:04 +00:00
|
|
|
utimensat(AT_FDCWD, to, times, 0);
|
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-07-15 06:10:50 +00:00
|
|
|
#define DEFINE_ID_TYPE(type, typeName) \
|
|
|
|
thread_local NameDB* type::CurNameDB = nullptr; \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Little>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) \
|
|
|
|
{ \
|
|
|
|
id = reader.readUint16Little(); \
|
|
|
|
} \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Little>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) \
|
|
|
|
{ \
|
|
|
|
writer.writeUint16Little(id); \
|
|
|
|
} \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Little>::Enumerate<BigDNA::BinarySize>(size_t& sz) \
|
|
|
|
{ \
|
|
|
|
sz += 2; \
|
|
|
|
} \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Little>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) \
|
|
|
|
{ \
|
|
|
|
_read(reader); \
|
|
|
|
} \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Little>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) \
|
|
|
|
{ \
|
|
|
|
_write(writer); \
|
|
|
|
} \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Big>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) \
|
|
|
|
{ \
|
|
|
|
id = reader.readUint16Big(); \
|
|
|
|
} \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Big>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) \
|
|
|
|
{ \
|
|
|
|
writer.writeUint16Big(id); \
|
|
|
|
} \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Big>::Enumerate<BigDNA::BinarySize>(size_t& sz) \
|
|
|
|
{ \
|
|
|
|
sz += 2; \
|
|
|
|
} \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Big>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) \
|
|
|
|
{ \
|
|
|
|
_read(reader); \
|
|
|
|
} \
|
|
|
|
template<> template<> \
|
|
|
|
void type##DNA<athena::Big>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) \
|
|
|
|
{ \
|
|
|
|
_write(writer); \
|
|
|
|
} \
|
|
|
|
template <athena::Endian DNAE> \
|
|
|
|
void type##DNA<DNAE>::_read(athena::io::YAMLDocReader& r) \
|
|
|
|
{ \
|
|
|
|
std::string name = r.readString(nullptr); \
|
|
|
|
if (!type::CurNameDB) \
|
|
|
|
Log.report(logvisor::Fatal, "Unable to resolve " typeName " name %s, no database present", name.c_str()); \
|
|
|
|
if (name.empty()) \
|
|
|
|
{ \
|
|
|
|
id.id = 0xffff; \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
id = type::CurNameDB->resolveIdFromName(name); \
|
|
|
|
} \
|
|
|
|
template <athena::Endian DNAE> \
|
|
|
|
void type##DNA<DNAE>::_write(athena::io::YAMLDocWriter& w) \
|
|
|
|
{ \
|
|
|
|
if (!type::CurNameDB) \
|
|
|
|
Log.report(logvisor::Fatal, "Unable to resolve " typeName " ID %d, no database present", id.id); \
|
|
|
|
if (id.id == 0xffff) \
|
|
|
|
return; \
|
|
|
|
std::string_view name = type::CurNameDB->resolveNameFromId(id); \
|
2018-08-16 06:26:44 +00:00
|
|
|
if (!name.empty()) \
|
|
|
|
w.writeString(nullptr, name); \
|
2018-07-15 06:10:50 +00:00
|
|
|
} \
|
|
|
|
template <athena::Endian DNAE> \
|
|
|
|
const char* type##DNA<DNAE>::DNAType() \
|
|
|
|
{ \
|
|
|
|
return "amuse::" #type "DNA"; \
|
|
|
|
} \
|
|
|
|
template struct type##DNA<athena::Big>; \
|
|
|
|
template struct type##DNA<athena::Little>;
|
|
|
|
|
|
|
|
DEFINE_ID_TYPE(ObjectId, "object")
|
|
|
|
DEFINE_ID_TYPE(SoundMacroId, "SoundMacro")
|
|
|
|
DEFINE_ID_TYPE(SampleId, "sample")
|
|
|
|
DEFINE_ID_TYPE(TableId, "table")
|
|
|
|
DEFINE_ID_TYPE(KeymapId, "keymap")
|
|
|
|
DEFINE_ID_TYPE(LayersId, "layers")
|
|
|
|
DEFINE_ID_TYPE(SongId, "song")
|
|
|
|
DEFINE_ID_TYPE(SFXId, "sfx")
|
2018-07-17 04:48:38 +00:00
|
|
|
DEFINE_ID_TYPE(GroupId, "group")
|
2018-07-15 06:10:50 +00:00
|
|
|
|
|
|
|
template<> template<>
|
|
|
|
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
id = reader.readUint16Little();
|
|
|
|
}
|
|
|
|
template<> template<>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
writer.writeUint16Little(id);
|
|
|
|
}
|
|
|
|
template<> template<>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::BinarySize>(size_t& sz)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
sz += 2;
|
|
|
|
}
|
|
|
|
template<> template<>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
_read(reader);
|
|
|
|
}
|
|
|
|
template<> template<>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
_write(writer);
|
|
|
|
}
|
|
|
|
template<> template<>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
id = reader.readUint16Big();
|
|
|
|
}
|
|
|
|
template<> template<>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
writer.writeUint16Big(id);
|
|
|
|
}
|
|
|
|
template<> template<>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::BinarySize>(size_t& sz)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
sz += 2;
|
|
|
|
}
|
|
|
|
template<> template<>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
_read(reader);
|
|
|
|
}
|
|
|
|
template<> template<>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
_write(writer);
|
|
|
|
}
|
|
|
|
template <athena::Endian DNAE>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<DNAE>::_read(athena::io::YAMLDocReader& r)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
std::string name = r.readString(nullptr);
|
2018-07-15 06:10:50 +00:00
|
|
|
if (!KeymapId::CurNameDB || !LayersId::CurNameDB)
|
|
|
|
Log.report(logvisor::Fatal, "Unable to resolve keymap or layers name %s, no database present", name.c_str());
|
|
|
|
if (name.empty())
|
|
|
|
{
|
|
|
|
id.id = 0xffff;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto search = KeymapId::CurNameDB->m_stringToId.find(name);
|
|
|
|
if (search == KeymapId::CurNameDB->m_stringToId.cend())
|
|
|
|
{
|
|
|
|
search = LayersId::CurNameDB->m_stringToId.find(name);
|
|
|
|
if (search == LayersId::CurNameDB->m_stringToId.cend())
|
2018-08-09 07:42:17 +00:00
|
|
|
{
|
|
|
|
search = SoundMacroId::CurNameDB->m_stringToId.find(name);
|
|
|
|
if (search == SoundMacroId::CurNameDB->m_stringToId.cend())
|
|
|
|
{
|
|
|
|
Log.report(logvisor::Error, "Unable to resolve name %s", name.c_str());
|
|
|
|
id.id = 0xffff;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2018-07-15 06:10:50 +00:00
|
|
|
}
|
|
|
|
id = search->second;
|
2018-07-14 06:06:33 +00:00
|
|
|
}
|
|
|
|
template <athena::Endian DNAE>
|
2018-07-15 06:10:50 +00:00
|
|
|
void PageObjectIdDNA<DNAE>::_write(athena::io::YAMLDocWriter& w)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
2018-07-15 06:10:50 +00:00
|
|
|
if (!KeymapId::CurNameDB || !LayersId::CurNameDB)
|
|
|
|
Log.report(logvisor::Fatal, "Unable to resolve keymap or layers ID %d, no database present", id.id);
|
|
|
|
if (id.id == 0xffff)
|
|
|
|
return;
|
|
|
|
if (id.id & 0x8000)
|
|
|
|
{
|
|
|
|
std::string_view name = LayersId::CurNameDB->resolveNameFromId(id);
|
2018-08-16 06:26:44 +00:00
|
|
|
if (!name.empty())
|
|
|
|
w.writeString(nullptr, name);
|
2018-07-15 06:10:50 +00:00
|
|
|
}
|
2018-08-07 07:09:23 +00:00
|
|
|
else if (id.id & 0x4000)
|
2018-07-15 06:10:50 +00:00
|
|
|
{
|
|
|
|
std::string_view name = KeymapId::CurNameDB->resolveNameFromId(id);
|
2018-08-16 06:26:44 +00:00
|
|
|
if (!name.empty())
|
|
|
|
w.writeString(nullptr, name);
|
2018-07-15 06:10:50 +00:00
|
|
|
}
|
2018-08-07 07:09:23 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
std::string_view name = SoundMacroId::CurNameDB->resolveNameFromId(id);
|
2018-08-16 06:26:44 +00:00
|
|
|
if (!name.empty())
|
|
|
|
w.writeString(nullptr, name);
|
2018-08-07 07:09:23 +00:00
|
|
|
}
|
2018-07-14 06:06:33 +00:00
|
|
|
}
|
|
|
|
template <athena::Endian DNAE>
|
2018-07-15 06:10:50 +00:00
|
|
|
const char* PageObjectIdDNA<DNAE>::DNAType()
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
2018-07-15 06:10:50 +00:00
|
|
|
return "amuse::PageObjectIdDNA";
|
2018-07-14 06:06:33 +00:00
|
|
|
}
|
2018-07-15 06:10:50 +00:00
|
|
|
template struct PageObjectIdDNA<athena::Big>;
|
|
|
|
template struct PageObjectIdDNA<athena::Little>;
|
2018-07-14 06:06:33 +00:00
|
|
|
|
2018-07-28 04:34:29 +00:00
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
|
|
|
|
{
|
|
|
|
step = reader.readUint16Little();
|
|
|
|
}
|
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
|
|
|
|
{
|
|
|
|
writer.writeUint16Little(step);
|
|
|
|
}
|
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::BinarySize>(size_t& sz)
|
|
|
|
{
|
|
|
|
sz += 2;
|
|
|
|
}
|
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader)
|
|
|
|
{
|
|
|
|
step = reader.readUint16(nullptr);
|
|
|
|
}
|
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer)
|
|
|
|
{
|
|
|
|
writer.writeUint16(nullptr, step);
|
|
|
|
}
|
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
|
|
|
|
{
|
|
|
|
step = reader.readUint16Big();
|
|
|
|
}
|
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
|
|
|
|
{
|
|
|
|
writer.writeUint16Big(step);
|
|
|
|
}
|
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::BinarySize>(size_t& sz)
|
|
|
|
{
|
|
|
|
sz += 2;
|
|
|
|
}
|
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader)
|
|
|
|
{
|
|
|
|
step = reader.readUint16(nullptr);
|
|
|
|
}
|
|
|
|
template<> template<>
|
|
|
|
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer)
|
|
|
|
{
|
|
|
|
writer.writeUint16(nullptr, step);
|
|
|
|
}
|
|
|
|
template <athena::Endian DNAE>
|
|
|
|
const char* SoundMacroStepDNA<DNAE>::DNAType()
|
|
|
|
{
|
|
|
|
return "amuse::SoundMacroStepDNA";
|
|
|
|
}
|
|
|
|
template struct SoundMacroStepDNA<athena::Big>;
|
|
|
|
template struct SoundMacroStepDNA<athena::Little>;
|
|
|
|
|
2018-07-16 07:41:15 +00:00
|
|
|
ObjectId NameDB::generateId(Type tp) const
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
2018-08-09 07:42:17 +00:00
|
|
|
uint16_t maxMatch = 0;
|
|
|
|
if (tp == Type::Layer)
|
|
|
|
maxMatch = 0x8000;
|
|
|
|
else if (tp == Type::Keymap)
|
|
|
|
maxMatch = 0x4000;
|
2018-07-14 06:06:33 +00:00
|
|
|
for (const auto& p : m_idToString)
|
2018-07-15 06:10:50 +00:00
|
|
|
if (p.first >= maxMatch)
|
|
|
|
maxMatch = p.first + 1;
|
|
|
|
return maxMatch;
|
2018-07-14 06:06:33 +00:00
|
|
|
}
|
|
|
|
|
2018-07-15 06:10:50 +00:00
|
|
|
std::string NameDB::generateName(ObjectId id, Type tp)
|
2018-07-14 06:06:33 +00:00
|
|
|
{
|
|
|
|
char name[32];
|
|
|
|
switch (tp)
|
|
|
|
{
|
|
|
|
case Type::SoundMacro:
|
2018-07-15 06:10:50 +00:00
|
|
|
snprintf(name, 32, "macro%04X", id.id);
|
2018-07-14 06:06:33 +00:00
|
|
|
break;
|
|
|
|
case Type::Table:
|
2018-07-15 06:10:50 +00:00
|
|
|
snprintf(name, 32, "table%04X", id.id);
|
2018-07-14 06:06:33 +00:00
|
|
|
break;
|
|
|
|
case Type::Keymap:
|
2018-07-15 06:10:50 +00:00
|
|
|
snprintf(name, 32, "keymap%04X", id.id);
|
2018-07-14 06:06:33 +00:00
|
|
|
break;
|
|
|
|
case Type::Layer:
|
2018-07-15 06:10:50 +00:00
|
|
|
snprintf(name, 32, "layers%04X", id.id);
|
|
|
|
break;
|
|
|
|
case Type::Song:
|
|
|
|
snprintf(name, 32, "song%04X", id.id);
|
|
|
|
break;
|
|
|
|
case Type::SFX:
|
|
|
|
snprintf(name, 32, "sfx%04X", id.id);
|
|
|
|
break;
|
2018-07-17 04:48:38 +00:00
|
|
|
case Type::Group:
|
|
|
|
snprintf(name, 32, "group%04X", id.id);
|
|
|
|
break;
|
2018-07-15 06:10:50 +00:00
|
|
|
case Type::Sample:
|
|
|
|
snprintf(name, 32, "sample%04X", id.id);
|
2018-07-14 06:06:33 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
snprintf(name, 32, "obj%04X", id.id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2018-08-10 06:19:23 +00:00
|
|
|
std::string NameDB::generateDefaultName(Type tp) const
|
|
|
|
{
|
|
|
|
return generateName(generateId(tp), tp);
|
|
|
|
}
|
|
|
|
|
2018-07-14 06:06:33 +00:00
|
|
|
std::string_view NameDB::registerPair(std::string_view str, ObjectId id)
|
|
|
|
{
|
|
|
|
m_stringToId[std::string(str)] = id;
|
|
|
|
return m_idToString.insert(std::make_pair(id, str)).first->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string_view NameDB::resolveNameFromId(ObjectId id) const
|
|
|
|
{
|
|
|
|
auto search = m_idToString.find(id);
|
|
|
|
if (search == m_idToString.cend())
|
2018-08-07 07:09:23 +00:00
|
|
|
{
|
|
|
|
Log.report(logvisor::Error, "Unable to resolve ID 0x%04X", id.id);
|
|
|
|
return ""sv;
|
|
|
|
}
|
2018-07-14 06:06:33 +00:00
|
|
|
return search->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjectId NameDB::resolveIdFromName(std::string_view str) const
|
|
|
|
{
|
|
|
|
auto search = m_stringToId.find(std::string(str));
|
|
|
|
if (search == m_stringToId.cend())
|
2018-08-07 07:09:23 +00:00
|
|
|
{
|
|
|
|
Log.report(logvisor::Error, "Unable to resolve name %s", str.data());
|
|
|
|
return {};
|
|
|
|
}
|
2018-07-14 06:06:33 +00:00
|
|
|
return search->second;
|
|
|
|
}
|
|
|
|
|
2018-08-09 07:42:17 +00:00
|
|
|
void NameDB::remove(ObjectId id)
|
|
|
|
{
|
|
|
|
auto search = m_idToString.find(id);
|
|
|
|
if (search == m_idToString.cend())
|
|
|
|
return;
|
|
|
|
auto search2 = m_stringToId.find(search->second);
|
|
|
|
if (search2 == m_stringToId.cend())
|
|
|
|
return;
|
|
|
|
m_idToString.erase(search);
|
|
|
|
m_stringToId.erase(search2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void NameDB::rename(ObjectId id, std::string_view str)
|
|
|
|
{
|
|
|
|
auto search = m_idToString.find(id);
|
|
|
|
if (search == m_idToString.cend())
|
|
|
|
return;
|
2018-08-28 03:48:53 +00:00
|
|
|
if (search->second == str)
|
|
|
|
return;
|
2018-08-09 07:42:17 +00:00
|
|
|
auto search2 = m_stringToId.find(search->second);
|
|
|
|
if (search2 == m_stringToId.cend())
|
|
|
|
return;
|
2018-08-28 03:48:53 +00:00
|
|
|
#if __APPLE__
|
|
|
|
std::swap(m_stringToId[std::string(str)], search2->second);
|
|
|
|
m_stringToId.erase(search2);
|
|
|
|
#else
|
2018-08-09 07:42:17 +00:00
|
|
|
auto nh = m_stringToId.extract(search2);
|
|
|
|
nh.key() = str;
|
|
|
|
m_stringToId.insert(std::move(nh));
|
2018-08-28 03:48:53 +00:00
|
|
|
#endif
|
|
|
|
search->second = str;
|
2018-08-09 07:42:17 +00:00
|
|
|
}
|
|
|
|
|
2018-07-14 06:06:33 +00:00
|
|
|
template<>
|
|
|
|
void LittleUInt24::Enumerate<LittleDNA::Read>(athena::io::IStreamReader& reader)
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
atUint32 val;
|
|
|
|
char bytes[4];
|
|
|
|
} data = {};
|
|
|
|
reader.readBytesToBuf(data.bytes, 3);
|
|
|
|
val = SLittle(data.val);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void LittleUInt24::Enumerate<LittleDNA::Write>(athena::io::IStreamWriter& writer)
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
atUint32 val;
|
|
|
|
char bytes[4];
|
|
|
|
} data;
|
|
|
|
data.val = SLittle(val);
|
|
|
|
writer.writeBytes(data.bytes, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void LittleUInt24::Enumerate<LittleDNA::BinarySize>(size_t& sz)
|
|
|
|
{
|
|
|
|
sz += 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void LittleUInt24::Enumerate<LittleDNA::ReadYaml>(athena::io::YAMLDocReader& reader)
|
|
|
|
{
|
|
|
|
val = reader.readUint32(nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void LittleUInt24::Enumerate<LittleDNA::WriteYaml>(athena::io::YAMLDocWriter& writer)
|
|
|
|
{
|
|
|
|
writer.writeUint32(nullptr, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* LittleUInt24::DNAType()
|
|
|
|
{
|
|
|
|
return "amuse::LittleUInt24";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|