2019-06-28 15:02:38 +00:00
|
|
|
#ifndef PORYGONLANG_USERDATATEMPLATES_HPP
|
|
|
|
#define PORYGONLANG_USERDATATEMPLATES_HPP
|
|
|
|
|
2019-09-07 13:22:24 +00:00
|
|
|
static std::wstring_convert<std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::little_endian>, char16_t> to_16;
|
|
|
|
Porygon::Utilities::HashedString* Convert(const char* k){
|
|
|
|
auto conv = new u16string(to_16.from_bytes(k));
|
|
|
|
return new Porygon::Utilities::HashedString(conv);
|
|
|
|
}
|
2019-06-28 15:53:37 +00:00
|
|
|
/*!
|
|
|
|
\brief Begins creating an invokable function. Make sure to call PORYGON_USERDATA_END after this.
|
|
|
|
\returns The start of an invokable function with the name __createUserData. This can be called to return a userdata object.
|
|
|
|
*/
|
2019-09-07 13:22:24 +00:00
|
|
|
#define PORYGON_USERDATA_START(key, type) \
|
2019-06-28 21:38:47 +00:00
|
|
|
using T_USERDATA = type; \
|
2019-06-28 15:02:38 +00:00
|
|
|
static Porygon::UserData::UserData* __createUserData(){ \
|
2019-09-07 13:22:24 +00:00
|
|
|
return new Porygon::UserData::UserData( \
|
|
|
|
Convert(#key), { \
|
2019-06-28 15:02:38 +00:00
|
|
|
|
2019-06-28 15:53:37 +00:00
|
|
|
/*!
|
|
|
|
\brief Ends creation of invokable function to create userdata.
|
|
|
|
*/
|
2019-06-28 15:02:38 +00:00
|
|
|
#define PORYGON_USERDATA_END() });};
|
|
|
|
|
2019-06-28 15:53:37 +00:00
|
|
|
/*!
|
|
|
|
\brief Creates an invokable static function with the name __createUserData. This can be called to generate a userdata object.
|
|
|
|
\param fields The fields of the object.
|
|
|
|
\returns an invokable static function with the name __createUserData. This can be called to generate a userdata object.
|
|
|
|
*/
|
2019-09-07 13:22:24 +00:00
|
|
|
#define PORYGON_USERDATA(key, type, fields) \
|
|
|
|
PORYGON_USERDATA_START(key, type) \
|
2019-06-28 15:53:37 +00:00
|
|
|
fields \
|
|
|
|
PORYGON_USERDATA_END()
|
|
|
|
|
2019-09-01 13:35:45 +00:00
|
|
|
#define PORYGON_INTEGER_TYPE (NumericScriptType::AwareInt)
|
|
|
|
#define PORYGON_FLOAT_TYPE (NumericScriptType::AwareFloat)
|
2019-06-28 15:02:38 +00:00
|
|
|
#define PORYGON_STRING_TYPE ((Porygon::ScriptType*)new Porygon::StringScriptType(false, 0))
|
2019-07-28 17:01:07 +00:00
|
|
|
#define PORYGON_INDEXABLE_TYPE(keyType, valueType) \
|
2019-09-01 13:35:45 +00:00
|
|
|
(Porygon::UserData::UserDataCollectionType::CreateIndexable(keyType, valueType))
|
2019-06-28 15:02:38 +00:00
|
|
|
|
2019-06-28 21:38:47 +00:00
|
|
|
#define PORYGON_FIELD(fieldName, fieldType, getterHelper, setterHelper) \
|
2019-06-28 15:02:38 +00:00
|
|
|
{ \
|
|
|
|
Porygon::Utilities::HashedString::ConstHash(#fieldName), \
|
|
|
|
new Porygon::UserData::UserDataField(fieldType, \
|
2019-07-25 15:23:54 +00:00
|
|
|
[](void* obj) -> const Porygon::Evaluation::EvalValue* { return new getterHelper;}, \
|
|
|
|
[](void* obj, const Porygon::Evaluation::EvalValue* val) { ((T_USERDATA*)obj)->fieldName = setterHelper;} \
|
2019-06-28 15:02:38 +00:00
|
|
|
) \
|
|
|
|
}, \
|
|
|
|
|
2019-06-28 21:38:47 +00:00
|
|
|
#define PORYGON_READONLY_FIELD(fieldName, fieldType, getterHelper) \
|
2019-06-28 15:02:38 +00:00
|
|
|
{ \
|
|
|
|
Porygon::Utilities::HashedString::ConstHash(#fieldName), \
|
|
|
|
new Porygon::UserData::UserDataField(fieldType, \
|
2019-07-28 17:01:07 +00:00
|
|
|
[](void* obj) -> const Porygon::Evaluation::EvalValue* { return new getterHelper;}, \
|
2019-06-28 15:02:38 +00:00
|
|
|
nullptr \
|
|
|
|
) \
|
|
|
|
}, \
|
|
|
|
|
2019-06-28 21:38:47 +00:00
|
|
|
#define PORYGON_INTEGER_FIELD(fieldName) \
|
|
|
|
PORYGON_FIELD(fieldName, PORYGON_INTEGER_TYPE, \
|
2019-09-07 08:57:09 +00:00
|
|
|
const Porygon::Evaluation::NumericEvalValue(((T_USERDATA*)obj)->fieldName), val->EvaluateInteger())
|
2019-06-28 15:02:38 +00:00
|
|
|
|
2019-06-28 21:38:47 +00:00
|
|
|
#define PORYGON_READONLY_INTEGER_FIELD(fieldName) \
|
|
|
|
PORYGON_READONLY_FIELD(fieldName, PORYGON_INTEGER_TYPE, \
|
2019-09-07 08:57:09 +00:00
|
|
|
Porygon::Evaluation::NumericEvalValue(((T_USERDATA*)obj)->fieldName))
|
2019-06-28 15:02:38 +00:00
|
|
|
|
2019-06-28 21:38:47 +00:00
|
|
|
#define PORYGON_FLOAT_FIELD(fieldName) \
|
|
|
|
PORYGON_FIELD(fieldName, PORYGON_FLOAT_TYPE, \
|
|
|
|
Porygon::EvaluationFloatEvalValue(((T_USERDATA*)obj)->fieldName), val->EvaluateFloat())
|
2019-06-28 15:02:38 +00:00
|
|
|
|
2019-06-28 21:38:47 +00:00
|
|
|
#define PORYGON_READONLY_FLOAT_FIELD(fieldName) \
|
|
|
|
PORYGON_READONLY_FIELD(fieldName, PORYGON_FLOAT_TYPE, \
|
|
|
|
Porygon::EvaluationFloatEvalValue(((T_USERDATA*)obj)->fieldName))
|
2019-06-28 15:02:38 +00:00
|
|
|
|
2019-07-28 17:01:07 +00:00
|
|
|
/*
|
|
|
|
#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(); \
|
2019-08-15 09:43:08 +00:00
|
|
|
} \
|
|
|
|
, [](void* obj) -> Porygon::Evaluation::Iterator* {\
|
|
|
|
auto val = ((T_USERDATA*)obj)->fieldName; \
|
|
|
|
auto size = val.size(); \
|
|
|
|
return new Porygon::UserData::UserDataCollectionRangeIterator(0, size); \
|
2019-09-12 16:19:06 +00:00
|
|
|
}, [](void* obj) -> size_t{ \
|
|
|
|
return ((T_USERDATA*)obj)->fieldName.size(); \
|
2019-08-15 09:43:08 +00:00
|
|
|
} \
|
|
|
|
) \
|
2019-07-28 17:01:07 +00:00
|
|
|
) \
|
|
|
|
)
|
|
|
|
|
2019-06-28 15:02:38 +00:00
|
|
|
|
2019-06-28 21:38:47 +00:00
|
|
|
#define PORYGON_FUNCTION(fieldName, returnType, ...) \
|
2019-06-28 15:02:38 +00:00
|
|
|
{ \
|
|
|
|
Porygon::Utilities::HashedString::ConstHash(#fieldName), \
|
2019-06-29 17:59:42 +00:00
|
|
|
new Porygon::UserData::UserDataField( \
|
|
|
|
new Porygon::GenericFunctionScriptType( \
|
2019-09-01 13:35:45 +00:00
|
|
|
new Porygon::UserData::UserDataFunctionOption(returnType, {__VA_ARGS__} )), \
|
2019-06-28 15:02:38 +00:00
|
|
|
\
|
|
|
|
\
|
2019-07-25 15:23:54 +00:00
|
|
|
[](void* obj) -> const Porygon::Evaluation::EvalValue* { \
|
2019-07-28 17:01:07 +00:00
|
|
|
auto t = new Porygon::Evaluation::GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), \
|
|
|
|
Porygon::Utilities::Random::Get()); \
|
2019-06-29 17:59:42 +00:00
|
|
|
t->RegisterOption(new Porygon::UserData::UserDataFunction( \
|
2019-08-10 09:55:45 +00:00
|
|
|
[](void* obj, const ScriptOptions* opts, const Porygon::Evaluation::EvalValue* par[], int parameterCount) \
|
2019-09-28 11:08:32 +00:00
|
|
|
-> const Porygon::UserData::UserDataReturnValue*{ \
|
|
|
|
return new Porygon::UserData::UserDataReturnValue (((const T_USERDATA*)obj)->invoke__##fieldName(obj, opts, par, parameterCount));}, \
|
2019-06-29 17:59:42 +00:00
|
|
|
obj)); \
|
|
|
|
return t;}, \
|
2019-06-28 15:02:38 +00:00
|
|
|
nullptr) \
|
|
|
|
},
|
|
|
|
|
2019-06-28 15:53:37 +00:00
|
|
|
|
2019-06-28 21:38:47 +00:00
|
|
|
#define PORYGON_INTEGER_FUNCTION(fieldName, ...) \
|
2019-09-01 13:35:45 +00:00
|
|
|
PORYGON_FUNCTION(fieldName, Porygon::NumericScriptType::AwareInt, __VA_ARGS__ )
|
2019-06-28 15:02:38 +00:00
|
|
|
|
|
|
|
|
2019-06-28 15:53:37 +00:00
|
|
|
/*!
|
|
|
|
\brief Creates an invokable function that resolves EvalValues into actual parameters and vice versa for its return type.
|
|
|
|
\param userDataTypeName The type name of the UserData its created for.
|
|
|
|
\param fieldName The field name of the original function.
|
|
|
|
\param returnType The type for which the constructor gets called.
|
|
|
|
\param ... How to resolve the calling parameters into actual values.
|
|
|
|
\returns An invokable function.
|
|
|
|
*/
|
2019-06-28 15:02:38 +00:00
|
|
|
#define PORYGON_PREPARE_FUNCTION(userDataTypeName, fieldName, returnType, ...) \
|
2019-08-10 09:55:45 +00:00
|
|
|
static const Porygon::Evaluation::EvalValue* invoke__##fieldName(void* obj, const ScriptOptions* opts, \
|
|
|
|
const Porygon::Evaluation::EvalValue* par[], int parameterCount){ \
|
2019-06-28 16:31:24 +00:00
|
|
|
return Porygon::Evaluation::EvalValueHelper::Create(((userDataTypeName*)obj)->fieldName( \
|
2019-06-28 15:02:38 +00:00
|
|
|
__VA_ARGS__ \
|
|
|
|
));}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif //PORYGONLANG_USERDATATEMPLATES_HPP
|