Support for setting userdata casting handling

This commit is contained in:
Deukhoofd 2019-09-01 13:35:13 +02:00
parent b2ee008ba2
commit 79873d9d6a
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
6 changed files with 55 additions and 1 deletions

View File

@ -36,6 +36,10 @@ namespace Porygon{
type->RegisterFunctionOption(option); type->RegisterFunctionOption(option);
return type; return type;
} }
TypeClass GetTypeClass(ScriptType* t){
return t->GetClass();
}
} }
} }

View File

@ -18,5 +18,15 @@ namespace Porygon::UserData {
auto ud = UserDataStorage::GetUserDataType(typeId); auto ud = UserDataStorage::GetUserDataType(typeId);
return ud->Get()->GetFieldCount(); return ud->Get()->GetFieldCount();
} }
void SetIsCastableFunc(uint32_t typeId, bool (*cast)(const ScriptType*, bool)){
auto ud = UserDataStorage::GetUserDataType(typeId);
ud->Get()->SetIsCastable(cast);
}
void SetCastFunc(uint32_t typeId, Evaluation::EvalValue* (*cast)(void*, const ScriptType*)){
auto ud = UserDataStorage::GetUserDataType(typeId);
ud->Get()->SetCastFunc(cast);
}
} }
} }

View File

@ -27,8 +27,11 @@ namespace Porygon::UserData {
UserDataBinaryOperation* _logicalOr = nullptr; UserDataBinaryOperation* _logicalOr = nullptr;
UserDataBinaryOperation* _concatenation = nullptr; UserDataBinaryOperation* _concatenation = nullptr;
bool (*_isCastable)(const ScriptType* type, bool explicitCast);
Evaluation::EvalValue* (*_cast)(void* obj, const ScriptType* castType);
public: public:
explicit UserData(std::unordered_map<uint32_t, UserDataField *> fields) explicit UserData(const std::unordered_map<uint32_t, UserDataField *>& fields)
{ {
for (auto f: fields){ for (auto f: fields){
_fields.insert({f.first, unique_ptr<UserDataField>(f.second)}); _fields.insert({f.first, unique_ptr<UserDataField>(f.second)});
@ -73,6 +76,23 @@ namespace Porygon::UserData {
return _fields.size(); return _fields.size();
} }
void SetIsCastable(bool (*cast)(const ScriptType* type, bool explicitCast)){
_isCastable = cast;
}
bool IsCastable(const shared_ptr<const ScriptType>& 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]] [[nodiscard]]
UserDataBinaryOperation* GetBinaryOperation(Binder::BoundBinaryOperation op){ UserDataBinaryOperation* GetBinaryOperation(Binder::BoundBinaryOperation op){
switch (op){ switch (op){

View File

@ -6,5 +6,9 @@ extern "C"{
UserDataScriptType* CreateUserDataType(uint32_t id){ UserDataScriptType* CreateUserDataType(uint32_t id){
return new UserDataScriptType(id); return new UserDataScriptType(id);
} }
uint32_t GetScriptTypeUserData(UserDataScriptType* t){
return t->GetUserData()->GetKey();
}
} }
} }

View File

@ -25,6 +25,10 @@ namespace Porygon::UserData {
delete _userData; delete _userData;
} }
RetrievedUserData* GetUserData() const{
return _userData;
}
bool CanBeIndexedWith(const ScriptType *indexer) const final { bool CanBeIndexedWith(const ScriptType *indexer) const final {
if (indexer->GetClass() != TypeClass::String) { if (indexer->GetClass() != TypeClass::String) {
return false; return false;
@ -54,6 +58,13 @@ namespace Porygon::UserData {
[[nodiscard]] inline shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const final { [[nodiscard]] inline shared_ptr<const ScriptType> GetIndexedType(uint32_t hash) const final {
return _userData->Get()->GetField(hash)->GetType(); return _userData->Get()->GetField(hash)->GetType();
} }
[[nodiscard]] CastResult CastableTo(const shared_ptr<const ScriptType>& castType, bool explicitCast) const final{
if (_userData->Get()->IsCastable(castType, explicitCast)){
return CastResult::ValidCast;
}
return CastResult ::InvalidCast;
}
}; };
} }

View File

@ -73,6 +73,11 @@ namespace Porygon::UserData {
inline void* GetObjectPointer(){ inline void* GetObjectPointer(){
return _obj; return _obj;
} }
[[nodiscard]]
EvalValue* Cast(shared_ptr<const ScriptType> castType) const final{
return _userData->Get()->Cast(_obj, castType.get());
}
}; };
} }