Union with shared_ptr caused a memory leak. Prevent this using std::variant
This commit is contained in:
parent
458274f370
commit
6c6d977000
|
@ -16,14 +16,25 @@ namespace Porygon{
|
||||||
Dictionary
|
Dictionary
|
||||||
};
|
};
|
||||||
|
|
||||||
bool _isContentAware;
|
using ContentTypes = unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>>*;
|
||||||
|
using KeyValueType = std::pair<shared_ptr<const ScriptType>, shared_ptr<const ScriptType>>;
|
||||||
|
|
||||||
|
bool _isContentAware = false;
|
||||||
TableType _tableType;
|
TableType _tableType;
|
||||||
|
|
||||||
union{
|
std::variant<
|
||||||
shared_ptr<const ScriptType> _valueType; // numerical
|
shared_ptr<const ScriptType>,
|
||||||
unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>>* _contentTypes = nullptr; // string keyed
|
ContentTypes,
|
||||||
std::pair<shared_ptr<const ScriptType>, shared_ptr<const ScriptType>> _keyValueType; // dictionary
|
KeyValueType
|
||||||
};
|
> _valueType, _contentTypes, _keyValueType;
|
||||||
|
|
||||||
|
[[nodiscard]] inline shared_ptr<const ScriptType> GetValueType() const{
|
||||||
|
return std::get<shared_ptr<const ScriptType>>(_valueType);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline KeyValueType GetKeyValueTypes() const{
|
||||||
|
return std::get<KeyValueType>(_keyValueType);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TableScriptType()
|
explicit TableScriptType()
|
||||||
|
@ -41,7 +52,7 @@ namespace Porygon{
|
||||||
|
|
||||||
~TableScriptType() override {
|
~TableScriptType() override {
|
||||||
if (_tableType == TableType::StringKeyed)
|
if (_tableType == TableType::StringKeyed)
|
||||||
delete _contentTypes;
|
delete GetContentTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool CanBeIterated() const final {
|
[[nodiscard]] bool CanBeIterated() const final {
|
||||||
|
@ -71,7 +82,7 @@ namespace Porygon{
|
||||||
return indexer->GetClass() == TypeClass::Number;
|
return indexer->GetClass() == TypeClass::Number;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
auto keyType = _keyValueType.first;
|
auto keyType = GetKeyValueTypes().first;
|
||||||
return indexer->CastableTo(keyType, false) != CastResult ::InvalidCast;
|
return indexer->CastableTo(keyType, false) != CastResult ::InvalidCast;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,25 +100,25 @@ namespace Porygon{
|
||||||
auto stringType = dynamic_pointer_cast<const StringScriptType>(indexer);
|
auto stringType = dynamic_pointer_cast<const StringScriptType>(indexer);
|
||||||
if (stringType->IsKnownAtBind() && _isContentAware){
|
if (stringType->IsKnownAtBind() && _isContentAware){
|
||||||
auto h = stringType->GetHashValue();
|
auto h = stringType->GetHashValue();
|
||||||
return _contentTypes->at(h);
|
return GetContentTypes()->at(h);
|
||||||
}
|
}
|
||||||
return ScriptType::AnyType;
|
return ScriptType::AnyType;
|
||||||
}
|
}
|
||||||
else if (_tableType == TableType::Numerical){
|
else if (_tableType == TableType::Numerical){
|
||||||
return _valueType;
|
return GetValueType();
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return _keyValueType.second;
|
return GetKeyValueTypes().second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const override {
|
[[nodiscard]] shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const override {
|
||||||
auto lookup = Utilities::HashedString::CreateLookup(hash);
|
auto lookup = Utilities::HashedString::CreateLookup(hash);
|
||||||
return _contentTypes->at(lookup);
|
return GetContentTypes()->at(lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>>* GetContentTypes() const{
|
[[nodiscard]] inline ContentTypes GetContentTypes() const{
|
||||||
return _contentTypes;
|
return std::get<ContentTypes>(_contentTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
@ -117,12 +128,12 @@ namespace Porygon{
|
||||||
case Unknown: return true;
|
case Unknown: return true;
|
||||||
case Numerical:
|
case Numerical:
|
||||||
return indexer->GetClass() == TypeClass ::Number &&
|
return indexer->GetClass() == TypeClass ::Number &&
|
||||||
val->CastableTo(_valueType, false) != CastResult ::InvalidCast;
|
val->CastableTo(GetValueType(), false) != CastResult ::InvalidCast;
|
||||||
case StringKeyed:
|
case StringKeyed:
|
||||||
return indexer->GetClass() == TypeClass ::String;
|
return indexer->GetClass() == TypeClass ::String;
|
||||||
case Dictionary:
|
case Dictionary:
|
||||||
return indexer->CastableTo(_keyValueType.first, false) != CastResult ::InvalidCast &&
|
return indexer->CastableTo(GetKeyValueTypes().first, false) != CastResult ::InvalidCast &&
|
||||||
val->CastableTo(_keyValueType.second, false) != CastResult ::InvalidCast;
|
val->CastableTo(GetKeyValueTypes().second, false) != CastResult ::InvalidCast;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,14 +155,14 @@ namespace Porygon{
|
||||||
auto s = dynamic_pointer_cast<const StringScriptType>(indexer);
|
auto s = dynamic_pointer_cast<const StringScriptType>(indexer);
|
||||||
if (s->IsKnownAtBind()){
|
if (s->IsKnownAtBind()){
|
||||||
auto key = s->GetHashValue();
|
auto key = s->GetHashValue();
|
||||||
_contentTypes->insert({key, val});
|
GetContentTypes()->insert({key, val});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIndexValue(Utilities::HashedString indexer, shared_ptr<const ScriptType> val) const override {
|
void SetIndexValue(Utilities::HashedString indexer, shared_ptr<const ScriptType> val) const override {
|
||||||
if (_tableType == TableType::StringKeyed){
|
if (_tableType == TableType::StringKeyed){
|
||||||
_contentTypes->insert({indexer, val});
|
GetContentTypes()->insert({indexer, val});
|
||||||
}
|
}
|
||||||
else if (_tableType == TableType::Unknown){
|
else if (_tableType == TableType::Unknown){
|
||||||
auto t = const_cast<TableScriptType*>(this);
|
auto t = const_cast<TableScriptType*>(this);
|
||||||
|
|
Loading…
Reference in New Issue