Implements iterator for user data collection
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Deukhoofd 2019-08-15 11:43:08 +02:00
parent 5387cd15ff
commit 471dbac3b9
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
15 changed files with 151 additions and 14 deletions

Binary file not shown.

Binary file not shown.

View File

@ -10,7 +10,7 @@ using namespace std;
namespace Porygon::Evaluation{ namespace Porygon::Evaluation{
class Iterator { class Iterator {
public: public:
virtual EvalValue* GetCurrent() = 0; virtual const EvalValue* GetCurrent() = 0;
virtual bool MoveNext() = 0; virtual bool MoveNext() = 0;
virtual void Reset() = 0; virtual void Reset() = 0;
virtual ~Iterator(){} virtual ~Iterator(){}

View File

@ -16,7 +16,7 @@ namespace Porygon::Evaluation{
explicit NumericalKeyIterator(const NumericalTableEvalValue* table) explicit NumericalKeyIterator(const NumericalTableEvalValue* table)
: _vec(table->GetTable()), _size(_vec->size() + 1){} : _vec(table->GetTable()), _size(_vec->size() + 1){}
inline EvalValue* GetCurrent() final{ inline const EvalValue* GetCurrent() final{
return new IntegerEvalValue(_position); return new IntegerEvalValue(_position);
} }

View File

@ -15,7 +15,7 @@ namespace Porygon::Evaluation{
explicit TableKeyIterator(const TableEvalValue* table) explicit TableKeyIterator(const TableEvalValue* table)
: _iterator(table->GetTableIterator()), _end(table->GetTableIteratorEnd()){} : _iterator(table->GetTableIterator()), _end(table->GetTableIteratorEnd()){}
inline EvalValue* GetCurrent() final{ inline const EvalValue* GetCurrent() final{
return new StringEvalValue(*_iterator->first.GetString()); return new StringEvalValue(*_iterator->first.GetString());
} }

View File

@ -0,0 +1 @@
#include "UserDataCollectionIterator.hpp"

View File

@ -0,0 +1,33 @@
#ifndef PORYGONLANG_USERDATACOLLECTIONITERATOR_HPP
#define PORYGONLANG_USERDATACOLLECTIONITERATOR_HPP
#include "../../Evaluator/Iterator/Iterator.hpp"
namespace Porygon::UserData{
class UserDataCollectionIterator : public Evaluation::Iterator{
const Evaluation::EvalValue* (*_getCurrent)();
const Evaluation::EvalValue* (*_moveNext)();
const Evaluation::EvalValue* (*_reset)();
public:
UserDataCollectionIterator(const Evaluation::EvalValue* (*getCurrent)(),
const Evaluation::EvalValue* (*moveNext)(),
const Evaluation::EvalValue* (*reset)()){
_getCurrent = getCurrent;
_moveNext = moveNext;
_reset = reset;
}
const Evaluation::EvalValue* GetCurrent() final{
return _getCurrent();
}
bool MoveNext() final{
_moveNext();
}
void Reset() final{
_reset();
}
};
}
#endif //PORYGONLANG_USERDATACOLLECTIONITERATOR_HPP

View File

@ -0,0 +1 @@
#include "UserDataCollectionRangeIterator.hpp"

View File

@ -0,0 +1,33 @@
#ifndef PORYGONLANG_USERDATACOLLECTIONRANGEITERATOR_HPP
#define PORYGONLANG_USERDATACOLLECTIONRANGEITERATOR_HPP
#include "../../Evaluator/Iterator/Iterator.hpp"
#include "../../Evaluator/EvalValues/NumericEvalValue.hpp"
namespace Porygon::UserData{
class UserDataCollectionRangeIterator : public Evaluation::Iterator{
size_t _start;
size_t _end;
size_t _current;
public:
UserDataCollectionRangeIterator(size_t start, size_t end){
_start = start;
_end = end;
_current = start;
}
const Evaluation::EvalValue* GetCurrent() final{
return new Evaluation::IntegerEvalValue(_current);
}
bool MoveNext() final{
_current ++;
return _current <= _end;
}
void Reset() final{
_current = _start;
}
};
}
#endif //PORYGONLANG_USERDATACOLLECTIONRANGEITERATOR_HPP

View File

@ -2,7 +2,7 @@
#define PORYGONLANG_USERDATACOLLECTIONTYPE_HPP #define PORYGONLANG_USERDATACOLLECTIONTYPE_HPP
#include <utility> #include <utility>
#include "../ScriptTypes/ScriptType.hpp" #include "../../ScriptTypes/ScriptType.hpp"
namespace Porygon::UserData { namespace Porygon::UserData {
class UserDataCollectionType : public ScriptType { class UserDataCollectionType : public ScriptType {

View File

@ -4,8 +4,8 @@
#include <utility> #include <utility>
#include "UserDataCollectionType.hpp" #include "UserDataCollectionType.hpp"
#include "../Evaluator/EvalValues/EvalValue.hpp" #include "../../Evaluator/EvalValues/EvalValue.hpp"
#include "../Utilities/Random.hpp" #include "../../Utilities/Random.hpp"
using namespace Porygon::Evaluation; using namespace Porygon::Evaluation;
@ -14,12 +14,13 @@ namespace Porygon::UserData {
void* _parentObject; void* _parentObject;
const EvalValue* (*_get)(void*, const EvalValue*); const EvalValue* (*_get)(void*, const EvalValue*);
void (*_set)(void*, const EvalValue* , const EvalValue*); void (*_set)(void*, const EvalValue* , const EvalValue*);
Iterator* (*_getIterator)(void*);
public: public:
UserDataCollectionHelper(void* parentObject, UserDataCollectionHelper(void* parentObject,
const EvalValue* (*get)(void*, const EvalValue*), const EvalValue* (*get)(void*, const EvalValue*),
void (*set)(void*, const EvalValue*, const EvalValue*)) void (*set)(void*, const EvalValue*, const EvalValue*),
: _parentObject(parentObject), _get(get), _set(set){} Iterator* (*getIterator)(void*))
: _parentObject(parentObject), _get(get), _set(set), _getIterator(getIterator){}
const EvalValue* Get(const EvalValue* key) const{ const EvalValue* Get(const EvalValue* key) const{
return _get(_parentObject, key); return _get(_parentObject, key);
@ -28,6 +29,10 @@ namespace Porygon::UserData {
void Set(const EvalValue* key, const EvalValue* value) const{ void Set(const EvalValue* key, const EvalValue* value) const{
_set(_parentObject, key, value); _set(_parentObject, key, value);
} }
[[nodiscard]] Iterator* GetIterator() const{
return _getIterator(_parentObject);
}
}; };
class UserDataCollectionValue : public Evaluation::EvalValue{ class UserDataCollectionValue : public Evaluation::EvalValue{
@ -42,7 +47,7 @@ namespace Porygon::UserData {
public: public:
UserDataCollectionValue(ScriptType* type, const UserDataCollectionHelper* helper) UserDataCollectionValue(ScriptType* type, const UserDataCollectionHelper* helper)
: _type((UserDataCollectionType*)type), _helper(helper), _hash(Utilities::Random::Get()) : _type(dynamic_cast<UserDataCollectionType*>(type)), _helper(helper), _hash(Utilities::Random::Get())
{ {
} }
@ -67,6 +72,11 @@ namespace Porygon::UserData {
return _helper->Get(val); return _helper->Get(val);
} }
[[nodiscard]]
Iterator * GetKeyIterator() const final{
return _helper->GetIterator();
}
void SetIndexValue(const EvalValue *key, const EvalValue* value) const final{ void SetIndexValue(const EvalValue *key, const EvalValue* value) const final{
_helper->Set(key, value); _helper->Set(key, value);
delete value; delete value;

View File

@ -85,7 +85,13 @@
, [](void* obj, const EvalValue* key, const EvalValue* value){ \ , [](void* obj, const EvalValue* key, const EvalValue* value){ \
auto index = key->EvaluateInteger() - 1;\ auto index = key->EvaluateInteger() - 1;\
((T_USERDATA*)obj)->fieldName[index] = value->EvaluateInteger(); \ ((T_USERDATA*)obj)->fieldName[index] = value->EvaluateInteger(); \
}) \ } \
, [](void* obj) -> Porygon::Evaluation::Iterator* {\
auto val = ((T_USERDATA*)obj)->fieldName; \
auto size = val.size(); \
return new Porygon::UserData::UserDataCollectionRangeIterator(0, size); \
} \
) \
) \ ) \
) )

View File

@ -8,10 +8,10 @@
#include "../../src/UserData/UserDataFunction.hpp" #include "../../src/UserData/UserDataFunction.hpp"
#include "../../src/UserData/UserDataFunctionType.hpp" #include "../../src/UserData/UserDataFunctionType.hpp"
#include "../../src/UserData/UserDataTemplates.hpp" #include "../../src/UserData/UserDataTemplates.hpp"
#include "../../src/UserData/UserDataCollectionType.hpp" #include "../../src/UserData/UserDataCollections/UserDataCollectionType.hpp"
#include "../../src/UserData/UserDataCollectionValue.hpp" #include "../../src/UserData/UserDataCollections/UserDataCollectionValue.hpp"
#include "../../src/UserData/UserDataCollections/UserDataCollectionRangeIterator.hpp"
#include "../../src/Evaluator/EvalValues/EvalValueHelper.hpp" #include "../../src/Evaluator/EvalValues/EvalValueHelper.hpp"
#include "../../src/Utilities/Random.hpp"
using namespace Porygon; using namespace Porygon;
using namespace Porygon::UserData; using namespace Porygon::UserData;
@ -173,5 +173,58 @@ end
UserDataStorage::ClearTypes(); UserDataStorage::ClearTypes();
} }
TEST_CASE( "Iterate over userdata vector keys", "[integration]" ) {
UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData());
Script* script = Script::Create(R"(
function testFunc(testObject obj)
local val = 0
for i in obj.fooVector do
val = val + i
end
return val
end
)");
REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate();
auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc");
auto funcType = func -> GetType();
auto obj = new UserDataTestObject();
auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj);
auto result = script->CallFunction(u"testFunc", {parameter});
REQUIRE(result->EvaluateInteger() == 6);
delete obj;
delete parameter;
delete script;
delete func;
delete result;
UserDataStorage::ClearTypes();
}
TEST_CASE( "Iterate over userdata vector values", "[integration]" ) {
UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData());
Script* script = Script::Create(R"(
function testFunc(testObject obj)
local val = 0
for i, v in obj.fooVector do
val = val + v
end
return val
end
)");
REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate();
auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc");
auto funcType = func -> GetType();
auto obj = new UserDataTestObject();
auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj);
auto result = script->CallFunction(u"testFunc", {parameter});
REQUIRE(result->EvaluateInteger() == 55);
delete obj;
delete parameter;
delete script;
delete func;
delete result;
UserDataStorage::ClearTypes();
}
#endif #endif