compiler error while adding an array variable. serializing `std::vector`
michtarxd opened this issue · 4 comments
By adding C_ADD_VARIABLE_ARRAY(float, 10, flAimbotFov, 1.f);
to variables, I get errors about I guess Q_ARRAYSIZE
inside AddVariableArray as without it the errors disappear. Am I using the macro incorrectly or is it an issue inside the base?
Also I've got a question, why did we switch from std::vector to fixed size array? I'm not that experienced with them hence that's why I am asking. Other than that great work on the v2!
let me know is it working for you now.
regarding to the question, std::vector
was used wastefully for a such case. yeah it makes it slightly more annoying to explicitly specify variable's size but on other hand keeps it cheap.
It is indeed working, thank you for your response!
I've been trying to implement storing std::vector
for the future use in features like grenade helper etc. where you would need to resize the vector, well I've succeeded in halfway cause I relied on GetStorage
and just specified to get vector float data and my question is - would there be an easier or better way to save/load any std::vector
and maybe even one that could contain any of our UserType like it is done with keybinds with this config serialization system?
unfortunately there's no ability to add dynamic size user types such as std::vector
at the moment, but it's planned. for now everything i can suggest is manual adding this type to your preffered formatter code. e.g. for the binary:
// WriteBuffer
case FNV1A::HashConst("std::vector<TwoIntObject_t>"):
{
const std::vector<TwoIntObject_t>& vecTwoIntObjects = *variable.Get<std::vector<TwoIntObject_t>>();
// write count
*reinterpret_cast<std::size_t*>(pBufferCurrent) = vecTwoIntObjects .size();
pBufferCurrent += sizeof(std::size_t);
for (std::size_t i = 0U; i < vecTwoIntObjects.size(); i++)
{
const TwoIntObject_t& twoIntValue = vecTwoIntObjects[i];
*reinterpret_cast<int*>(pBufferCurrent) = twoIntValue.iFirst;
pBufferCurrent += sizeof(int);
*reinterpret_cast<int*>(pBufferCurrent) = twoIntValue.iSecond;
pBufferCurrent += sizeof(int);
}
break;
}
// ReadBuffer
case FNV1A::HashConst("std::vector<TwoIntObject_t>"):
{
std::vector<TwoIntObject_t>& vecTwoIntValue = *variable.Get<std::vector<TwoIntObject_t>>();
// read count
const std::size_t nTwoIntObjectCount = *reinterpret_cast<std::size_t*>(pBufferCurrent);
pBufferCurrent += sizeof(std::size_t);
for (std::size_t i = 0U; i < nTwoIntObjectCount; i++)
{
TwoIntObject_t twoIntObject;
twoIntObject.iFirst = *reinterpret_cast<const int*>(pBufferCurrent);
pBufferCurrent += sizeof(int);
twoIntObject.iSecond = *reinterpret_cast<const int*>(pBufferCurrent);
pBufferCurrent += sizeof(int);
vecTwoIntValue.push_back(CRT::Move(twoIntObject));
}
break;
}
note that you also should add a case for it inside VariableObject_t::GetSerializationSize
the other way i thought about, is defining user type, e.g. TwoIntObject_t
and then add it as single variable with C::AddVariable
, but there's still not implemented the way to remove it (C::RemoveVariable
), iterating through those would require to iterate all variables and check their type against needed, what is not sounds good tho.