#ifndef PORYGONLANG_USERDATA_HPP #define PORYGONLANG_USERDATA_HPP #include #include #include #include "UserDataField.hpp" #include "UserDataOperation.hpp" namespace Porygon::UserData { class UserData { Utilities::HashedString* _hashedString; std::unordered_map> _fields; std::mutex _mutex; // Binary operations UserDataBinaryOperation* _addition = nullptr; UserDataBinaryOperation* _subtraction = nullptr; UserDataBinaryOperation* _multiplication = nullptr; UserDataBinaryOperation* _division = nullptr; UserDataBinaryOperation* _equality = nullptr; UserDataBinaryOperation* _inequality = nullptr; UserDataBinaryOperation* _lessThen = nullptr; UserDataBinaryOperation* _lessThenEqual = nullptr; UserDataBinaryOperation* _greaterThen = nullptr; UserDataBinaryOperation* _greaterThenEqual = nullptr; UserDataBinaryOperation* _logicalAnd = nullptr; UserDataBinaryOperation* _logicalOr = nullptr; UserDataBinaryOperation* _concatenation = nullptr; bool (*_isCastable)(const ScriptType* type, bool explicitCast); Evaluation::EvalValue* (*_cast)(void* obj, const ScriptType* castType); public: explicit UserData(Utilities::HashedString* hashedString, const std::unordered_map& fields) : _hashedString(hashedString), _isCastable(nullptr), _cast(nullptr) { for (auto f: fields){ _fields.insert({f.first, unique_ptr(f.second)}); } } ~UserData(){ _fields.clear(); delete _addition; delete _subtraction; delete _multiplication; delete _division; delete _equality; delete _inequality; delete _lessThen; delete _lessThenEqual; delete _greaterThen; delete _greaterThenEqual; delete _logicalAnd; delete _logicalOr; delete _concatenation; delete _hashedString; } Utilities::HashedString* GetIdentifier(){ return _hashedString; } [[nodiscard]] inline bool ContainsField(uint32_t fieldId) const{ return _fields.find(fieldId) != _fields.end(); } [[nodiscard]] inline UserDataField *GetField(uint32_t fieldId) const { return _fields.at(fieldId).get(); } inline void CreateField(uint32_t fieldId, UserDataField *field) { std::lock_guard guard(_mutex); _fields.insert({fieldId, unique_ptr(field)}); } [[nodiscard]] inline int32_t GetFieldCount() const{ return _fields.size(); } void SetIsCastable(bool (*cast)(const ScriptType* type, bool explicitCast)){ _isCastable = cast; } bool IsCastable(const shared_ptr& castType, bool explicitCast) const{ if (_isCastable == nullptr) return false; return _isCastable(castType.get(), explicitCast); } void SetCastFunc(Evaluation::EvalValue* (*cast)(void* obj, const ScriptType* castType)){ _cast = cast; } Evaluation::EvalValue* Cast(void* obj, const ScriptType* castType) const{ return _cast(obj, castType); } [[nodiscard]] UserDataBinaryOperation* GetBinaryOperation(Binder::BoundBinaryOperation op){ switch (op){ case Binder::BoundBinaryOperation::Addition: return _addition; case Binder::BoundBinaryOperation::Subtraction: return _subtraction; case Binder::BoundBinaryOperation::Multiplication: return _multiplication; case Binder::BoundBinaryOperation::Division: return _division; case Binder::BoundBinaryOperation::Equality: return _equality; case Binder::BoundBinaryOperation::Inequality: return _inequality; case Binder::BoundBinaryOperation::LessThan: return _lessThen; case Binder::BoundBinaryOperation::LessThanEquals: return _lessThenEqual; case Binder::BoundBinaryOperation::GreaterThan: return _greaterThen; case Binder::BoundBinaryOperation::GreaterThanEquals: return _greaterThenEqual; case Binder::BoundBinaryOperation::LogicalAnd: return _logicalAnd; case Binder::BoundBinaryOperation::LogicalOr: return _logicalOr; case Binder::BoundBinaryOperation::Concatenation: return _concatenation; } } }; } #endif //PORYGONLANG_USERDATA_HPP