You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
7.6 KiB
C++
249 lines
7.6 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUMIMPL_H
|
|
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUMIMPL_H
|
|
#pragma once
|
|
|
|
#pragma once
|
|
#include "IArchive.h"
|
|
#include "STL.h"
|
|
#include "Enum.h"
|
|
#include "StringList.h"
|
|
#ifndef SERIALIZATION_STANDALONE
|
|
#include <ISystem.h>
|
|
#endif
|
|
|
|
namespace Serialization {
|
|
inline void CEnumDescription::add(int value, const char* name, const char* label)
|
|
{
|
|
YASLI_ESCAPE(name && label, return );
|
|
// Filter for dupes in case enum description included in a shared header
|
|
NameToValue::iterator nameIt = nameToValue_.find(name);
|
|
if (nameIt != nameToValue_.end() && nameIt->second == value)
|
|
{ LabelToValue::iterator labelIt = labelToValue_.find(label);
|
|
if (labelIt != labelToValue_.end() && labelIt->second == value)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
nameToValue_[name] = value;
|
|
labelToValue_[label] = value;
|
|
valueToName_[value] = name;
|
|
valueToLabel_[value] = label;
|
|
valueToIndex_[value] = int(names_.size());
|
|
names_.push_back(name);
|
|
labels_.push_back(label);
|
|
values_.push_back(value);
|
|
}
|
|
|
|
inline bool CEnumDescription::Serialize(IArchive& ar, int& value, const char* name, const char* label) const
|
|
{
|
|
lazyRegister();
|
|
if (!ar.IsInPlace())
|
|
{
|
|
if (count() == 0)
|
|
{
|
|
#ifdef SERIALIZATION_STANDALONE
|
|
assert(0 && "Attempt to serialize enum type that is not registered with SERIALIZATION_ENUM macro");
|
|
#else
|
|
CryFatalError("Attempt to serialize enum type that is not registered with SERIALIZATION_ENUM macro: %s", type().name());
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
int index = StringListStatic::npos;
|
|
if (ar.IsOutput())
|
|
{
|
|
index = indexByValue(value);
|
|
}
|
|
StringListStaticValue stringListValue(ar.IsEdit() ? labels() : names(), index, &value, type());
|
|
ar(stringListValue, name, label);
|
|
if (ar.IsInput())
|
|
{
|
|
if (stringListValue.index() == StringListStatic::npos)
|
|
{
|
|
return false;
|
|
}
|
|
value = ar.IsEdit() ? valueByLabel(stringListValue.c_str()) : this->value(stringListValue.c_str());
|
|
}
|
|
else if (index == StringListStatic::npos)
|
|
{
|
|
ar.Error(&value, type(), "Unregistered or uninitialized enumeration value.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return ar(value, name, label);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
inline bool CEnumDescription::serializeBitVector(IArchive& ar, int& value, const char* name, const char* label) const
|
|
{
|
|
lazyRegister();
|
|
if (ar.IsOutput())
|
|
{
|
|
StringListStatic names = nameCombination(value);
|
|
string str;
|
|
joinStringList(&str, names, '|');
|
|
return ar(str, name, label);
|
|
}
|
|
else
|
|
{
|
|
string str;
|
|
if (!ar(str, name, label))
|
|
{
|
|
return false;
|
|
}
|
|
StringList values;
|
|
splitStringList(&values, str.c_str(), '|');
|
|
StringList::iterator it;
|
|
value = 0;
|
|
for (it = values.begin(); it != values.end(); ++it)
|
|
{
|
|
if (!it->empty())
|
|
{
|
|
value |= this->value(it->c_str());
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
inline const char* CEnumDescription::name(int value) const
|
|
{
|
|
lazyRegister();
|
|
ValueToName::const_iterator it = valueToName_.find(value);
|
|
YASLI_ESCAPE(it != valueToName_.end(), return "");
|
|
return it->second;
|
|
}
|
|
inline const char* CEnumDescription::label(int value) const
|
|
{
|
|
lazyRegister();
|
|
ValueToLabel::const_iterator it = valueToLabel_.find(value);
|
|
YASLI_ESCAPE(it != valueToLabel_.end(), return "");
|
|
return it->second;
|
|
}
|
|
|
|
inline StringListStatic CEnumDescription::nameCombination(int bitVector) const
|
|
{
|
|
lazyRegister();
|
|
StringListStatic strings;
|
|
for (ValueToName::const_iterator i = valueToName_.begin(); i != valueToName_.end(); ++i)
|
|
{
|
|
if ((bitVector & i->first) == i->first)
|
|
{
|
|
bitVector &= ~i->first;
|
|
strings.push_back(i->second);
|
|
}
|
|
}
|
|
YASLI_ASSERT(!bitVector && "Unregistered enum value");
|
|
return strings;
|
|
}
|
|
|
|
inline StringListStatic CEnumDescription::labelCombination(int bitVector) const
|
|
{
|
|
lazyRegister();
|
|
StringListStatic strings;
|
|
for (ValueToLabel::const_iterator i = valueToLabel_.begin(); i != valueToLabel_.end(); ++i)
|
|
{
|
|
if (i->second && (bitVector & i->first) == i->first)
|
|
{
|
|
bitVector &= ~i->first;
|
|
strings.push_back(i->second);
|
|
}
|
|
}
|
|
YASLI_ASSERT(!bitVector && "Unregistered enum value");
|
|
return strings;
|
|
}
|
|
|
|
|
|
inline int CEnumDescription::indexByValue(int value) const
|
|
{
|
|
lazyRegister();
|
|
ValueToIndex::const_iterator it = valueToIndex_.find(value);
|
|
if (it == valueToIndex_.end())
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
return it->second;
|
|
}
|
|
}
|
|
|
|
inline int CEnumDescription::valueByIndex(int index) const
|
|
{
|
|
lazyRegister();
|
|
if (size_t(index) < values_.size())
|
|
{
|
|
return values_[index];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline const char* CEnumDescription::nameByIndex(int index) const
|
|
{
|
|
lazyRegister();
|
|
if (size_t(index) < size_t(names_.size()))
|
|
{
|
|
return names_[size_t(index)];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline const char* CEnumDescription::labelByIndex(int index) const
|
|
{
|
|
lazyRegister();
|
|
if (size_t(index) < size_t(labels_.size()))
|
|
{
|
|
return labels_[size_t(index)];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline int CEnumDescription::value(const char* name) const
|
|
{
|
|
lazyRegister();
|
|
NameToValue::const_iterator it = nameToValue_.find(name);
|
|
YASLI_ESCAPE(it != nameToValue_.end(), return 0);
|
|
return it->second;
|
|
}
|
|
inline int CEnumDescription::valueByLabel(const char* label) const
|
|
{
|
|
lazyRegister();
|
|
LabelToValue::const_iterator it = labelToValue_.find(label);
|
|
YASLI_ESCAPE(it != labelToValue_.end(), return 0);
|
|
return it->second;
|
|
}
|
|
|
|
inline void CEnumDescription::lazyRegister() const
|
|
{
|
|
if (m_regListHead)
|
|
{
|
|
NameValue* val = m_regListHead;
|
|
while (val)
|
|
{
|
|
const_cast<CEnumDescription*>(this)->add(val->m_value, val->m_name, val->m_label);
|
|
val = val->m_next;
|
|
}
|
|
const_cast<CEnumDescription*>(this)->m_regListHead = nullptr;
|
|
}
|
|
}
|
|
}
|
|
// vim:ts=4 sw=4:
|
|
|
|
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUMIMPL_H
|