Implements handling of userdata collection items
Some checks reported errors
continuous-integration/drone/push Build was killed
Some checks reported errors
continuous-integration/drone/push Build was killed
This commit is contained in:
1
src/UserData/UserDataCollectionType.cpp
Normal file
1
src/UserData/UserDataCollectionType.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "UserDataCollectionType.hpp"
|
||||
61
src/UserData/UserDataCollectionType.hpp
Normal file
61
src/UserData/UserDataCollectionType.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef PORYGONLANG_USERDATACOLLECTIONTYPE_HPP
|
||||
#define PORYGONLANG_USERDATACOLLECTIONTYPE_HPP
|
||||
|
||||
#include <utility>
|
||||
#include "../ScriptTypes/ScriptType.hpp"
|
||||
|
||||
namespace Porygon::UserData {
|
||||
class UserDataCollectionType : public ScriptType {
|
||||
shared_ptr<const ScriptType> _keyType;
|
||||
shared_ptr<const ScriptType> _valueType;
|
||||
const bool _indexable;
|
||||
const bool _iterable;
|
||||
public:
|
||||
UserDataCollectionType(shared_ptr<const ScriptType> keyType, shared_ptr<const ScriptType> valueType,
|
||||
bool indexable, bool iterable)
|
||||
: ScriptType(TypeClass::Table),
|
||||
_keyType(std::move(keyType)),
|
||||
_valueType(std::move(valueType)),
|
||||
_indexable(indexable),
|
||||
_iterable(iterable)
|
||||
{}
|
||||
|
||||
static shared_ptr<UserDataCollectionType> CreateIndexable(const shared_ptr<const ScriptType>& keyType, const shared_ptr<const ScriptType>& valueType){
|
||||
return make_shared<UserDataCollectionType>(keyType, valueType, true, true);
|
||||
}
|
||||
|
||||
static UserDataCollectionType* CreateIndexable(const ScriptType* keyType, const ScriptType* valueType){
|
||||
return new UserDataCollectionType(shared_ptr<const ScriptType>(keyType),
|
||||
shared_ptr<const ScriptType>(valueType), true, true);
|
||||
}
|
||||
|
||||
static shared_ptr<UserDataCollectionType> CreateIterable(const shared_ptr<const ScriptType>& valueType){
|
||||
return make_shared<UserDataCollectionType>(nullptr, valueType, false, true);
|
||||
}
|
||||
|
||||
bool CanBeIndexedWith(const ScriptType* indexer) const final{
|
||||
if (!_indexable){
|
||||
return false;
|
||||
}
|
||||
return indexer->operator==(_keyType.get());
|
||||
}
|
||||
|
||||
[[nodiscard]] shared_ptr<const ScriptType> GetIndexedType(const ScriptType* indexer) const final{
|
||||
return _valueType;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool CanBeIterated() const final{
|
||||
return _iterable;
|
||||
}
|
||||
|
||||
[[nodiscard]] shared_ptr<const ScriptType> GetIteratorKeyType() const final{
|
||||
if (_indexable){
|
||||
return _keyType;
|
||||
} else{
|
||||
return _valueType;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PORYGONLANG_USERDATACOLLECTIONTYPE_HPP
|
||||
1
src/UserData/UserDataCollectionValue.cpp
Normal file
1
src/UserData/UserDataCollectionValue.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "UserDataCollectionValue.hpp"
|
||||
75
src/UserData/UserDataCollectionValue.hpp
Normal file
75
src/UserData/UserDataCollectionValue.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef PORYGONLANG_USERDATACOLLECTIONVALUE_HPP
|
||||
#define PORYGONLANG_USERDATACOLLECTIONVALUE_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "UserDataCollectionType.hpp"
|
||||
#include "../Evaluator/EvalValues/EvalValue.hpp"
|
||||
#include "../Utilities/Random.hpp"
|
||||
|
||||
namespace Porygon::UserData {
|
||||
class UserDataCollectionHelper{
|
||||
void* _parentObject;
|
||||
const EvalValue* (*_get)(void*, const EvalValue*);
|
||||
void (*_set)(void*, const EvalValue* , const EvalValue*);
|
||||
|
||||
public:
|
||||
UserDataCollectionHelper(void* parentObject,
|
||||
const EvalValue* (*get)(void*, const EvalValue*),
|
||||
void (*set)(void*, const EvalValue*, const EvalValue*))
|
||||
: _parentObject(parentObject), _get(get), _set(set){}
|
||||
|
||||
const EvalValue* Get(const EvalValue* key) const{
|
||||
return _get(_parentObject, key);
|
||||
}
|
||||
|
||||
void Set(const EvalValue* key, const EvalValue* value) const{
|
||||
_set(_parentObject, key, value);
|
||||
}
|
||||
};
|
||||
|
||||
class UserDataCollectionValue : public Evaluation::EvalValue{
|
||||
shared_ptr<UserDataCollectionType> _type;
|
||||
shared_ptr<const UserDataCollectionHelper> _helper;
|
||||
const size_t _hash;
|
||||
UserDataCollectionValue(shared_ptr<UserDataCollectionType> type,
|
||||
shared_ptr<const UserDataCollectionHelper> helper, size_t hash)
|
||||
: _type(std::move(type)), _helper(std::move(helper)), _hash(hash)
|
||||
{
|
||||
}
|
||||
public:
|
||||
|
||||
UserDataCollectionValue(ScriptType* type, const UserDataCollectionHelper* helper)
|
||||
: _type((UserDataCollectionType*)type), _helper(helper), _hash(Utilities::Random::Get())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
[[nodiscard]] TypeClass GetTypeClass() const final{
|
||||
return TypeClass ::Table;
|
||||
}
|
||||
|
||||
bool operator==(const EvalValue *b) const final{
|
||||
return b->GetHashCode() == _hash;
|
||||
}
|
||||
|
||||
[[nodiscard]] EvalValue* Clone() const final{
|
||||
return new UserDataCollectionValue(_type, _helper, _hash);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t GetHashCode() const final{
|
||||
return _hash;
|
||||
}
|
||||
|
||||
const EvalValue* IndexValue(const EvalValue *val) const final{
|
||||
return _helper->Get(val);
|
||||
}
|
||||
|
||||
void SetIndexValue(const EvalValue *key, const EvalValue* value) const final{
|
||||
_helper->Set(key, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PORYGONLANG_USERDATACOLLECTIONVALUE_HPP
|
||||
@@ -28,6 +28,8 @@
|
||||
#define PORYGON_INTEGER_TYPE ((Porygon::ScriptType*)new Porygon::NumericScriptType(true, false))
|
||||
#define PORYGON_FLOAT_TYPE ((Porygon::ScriptType*)new Porygon::NumericScriptType(true, true))
|
||||
#define PORYGON_STRING_TYPE ((Porygon::ScriptType*)new Porygon::StringScriptType(false, 0))
|
||||
#define PORYGON_INDEXABLE_TYPE(keyType, valueType) \
|
||||
((Porygon::ScriptType*)Porygon::UserData::UserDataCollectionType::CreateIndexable(keyType, valueType))
|
||||
|
||||
#define PORYGON_FIELD(fieldName, fieldType, getterHelper, setterHelper) \
|
||||
{ \
|
||||
@@ -42,7 +44,7 @@
|
||||
{ \
|
||||
Porygon::Utilities::HashedString::ConstHash(#fieldName), \
|
||||
new Porygon::UserData::UserDataField(fieldType, \
|
||||
[](void* obj) -> Porygon::Evaluation::EvalValue* { return new getterHelper;}, \
|
||||
[](void* obj) -> const Porygon::Evaluation::EvalValue* { return new getterHelper;}, \
|
||||
nullptr \
|
||||
) \
|
||||
}, \
|
||||
@@ -63,6 +65,30 @@
|
||||
PORYGON_READONLY_FIELD(fieldName, PORYGON_FLOAT_TYPE, \
|
||||
Porygon::EvaluationFloatEvalValue(((T_USERDATA*)obj)->fieldName))
|
||||
|
||||
/*
|
||||
#define PORYGON_INDEXABLE_FIELD(fieldName, keyType, valueType) \
|
||||
PORYGON_FIELD(fieldName, PORYGON_INDEXABLE_TYPE(keyType, valueType), \
|
||||
const Porygon::Evaluation::IntegerEvalValue(((T_USERDATA*)obj)->fieldName), val->EvaluateInteger())
|
||||
*/
|
||||
|
||||
#define PORYGON_READONLY_VECTOR_FIELD(fieldName, valueType) \
|
||||
PORYGON_READONLY_FIELD(fieldName, PORYGON_INDEXABLE_TYPE(PORYGON_INTEGER_TYPE, valueType), \
|
||||
Porygon::UserData::UserDataCollectionValue( \
|
||||
PORYGON_INDEXABLE_TYPE(PORYGON_INTEGER_TYPE, valueType), \
|
||||
new UserDataCollectionHelper( \
|
||||
obj, \
|
||||
[](void* obj, const EvalValue* v) -> const EvalValue*{ \
|
||||
auto index = v->EvaluateInteger() - 1; \
|
||||
auto val = ((T_USERDATA*)obj)->fieldName;\
|
||||
return EvalValueHelper::Create(val[index]); \
|
||||
} \
|
||||
, [](void* obj, const EvalValue* key, const EvalValue* value){ \
|
||||
auto index = key->EvaluateInteger() - 1;\
|
||||
((T_USERDATA*)obj)->fieldName[index] = value->EvaluateInteger(); \
|
||||
}) \
|
||||
) \
|
||||
)
|
||||
|
||||
|
||||
#define PORYGON_FUNCTION(fieldName, returnType, ...) \
|
||||
{ \
|
||||
@@ -73,7 +99,8 @@
|
||||
\
|
||||
\
|
||||
[](void* obj) -> const Porygon::Evaluation::EvalValue* { \
|
||||
auto t = new Porygon::Evaluation::GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), rand()); \
|
||||
auto t = new Porygon::Evaluation::GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), \
|
||||
Porygon::Utilities::Random::Get()); \
|
||||
t->RegisterOption(new Porygon::UserData::UserDataFunction( \
|
||||
[](void* obj, const Porygon::Evaluation::EvalValue* par[], int parameterCount) \
|
||||
-> const Porygon::Evaluation::EvalValue*{return ((const T_USERDATA*)obj)->invoke__##fieldName(obj, par, parameterCount);}, \
|
||||
|
||||
Reference in New Issue
Block a user