#ifndef PORYGONLANG_USERDATAVALUE_HPP #define PORYGONLANG_USERDATAVALUE_HPP #include #include "../Evaluator/EvalValues/EvalValue.hpp" #include "UserData.hpp" #include "UserDataStorage.hpp" namespace Porygon::UserData { class UserDataValue : public Evaluation::EvalValue { RetrievedUserData* _userData; void *_obj; public: UserDataValue(UserData* userData, void *obj) : _userData(new RetrievedUserData(userData)) { _obj = obj; } UserDataValue(uint32_t userDataId, void *obj) : _userData(UserDataStorage::GetUserDataType(userDataId)) { _obj = obj; } ~UserDataValue() final{ delete _userData; } [[nodiscard]] inline TypeClass GetTypeClass() const final { return TypeClass::UserData; } bool operator==(const EvalValue *b) const final { if (b->GetTypeClass() != TypeClass::UserData) return false; return _obj == ((UserDataValue *) b)->_obj; } bool operator!=(const EvalValue *b) const override { return !operator==(b); } [[nodiscard]] inline Evaluation::EvalValue* Clone() const final { auto ud = _userData->Get(); if (ud == nullptr){ return new UserDataValue(_userData->GetKey(), _obj); } return new UserDataValue(ud, _obj); } [[nodiscard]] inline std::size_t GetHashCode() const final { return reinterpret_cast(_obj); } const Evaluation::EvalValue* IndexValue(const EvalValue *val) const final { auto fieldId = val->GetHashCode(); auto field = _userData->Get()->GetField(fieldId); return field->Get(_obj); } [[nodiscard]] inline const EvalValue* IndexValue(const Utilities::HashedString* hash) const final { auto field = _userData->Get()->GetField(hash->GetHash()); return field->Get(_obj); } void SetIndexValue(const EvalValue *key, const EvalValue* value) const final { auto fieldId = key->GetHashCode(); auto field = _userData->Get()->GetField(fieldId); field->Set(_obj, value); delete value; } [[nodiscard]] inline void* GetObjectPointer() const{ return _obj; } [[nodiscard]] EvalValue* Cast(shared_ptr castType) const final{ return _userData->Get()->Cast(_obj, castType.get()); } }; } #endif //PORYGONLANG_USERDATAVALUE_HPP