mirror of
https://github.com/aseprite/aseprite.git
synced 2024-12-28 06:21:25 +00:00
Update the way vectors are serialized to support mixed elements types
This commit is contained in:
parent
8b547adfb7
commit
47a1c407c3
@ -1570,10 +1570,14 @@ static void ase_file_write_property_value(FILE* f,
|
||||
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
||||
auto& v = *std::get_if<UserData::Vector>(&value);
|
||||
fputl(v.size(), f);
|
||||
const uint16_t type = (v.empty() ? 0 : v.front().type());
|
||||
const uint16_t type = doc::all_elements_of_same_type(v);
|
||||
fputw(type, f);
|
||||
for (const auto& elem : v) {
|
||||
ASSERT(type == elem.type()); // Check that all elements have the same type
|
||||
// Check that all elements have the same type when mode == 0. Or just that mode == 1
|
||||
ASSERT(type != 0 && type == elem.type() || type == 0);
|
||||
if (type == 0) {
|
||||
fputw(elem.type(), f);
|
||||
}
|
||||
ase_file_write_property_value(f, elem);
|
||||
}
|
||||
break;
|
||||
|
@ -413,8 +413,6 @@ doc::UserData::Variant get_value_from_lua(lua_State* L, int index)
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, index) != 0) {
|
||||
if (lua_isinteger(L, -2)) {
|
||||
// TODO we should check that all values are of the same type
|
||||
// to create the vector
|
||||
if (++i != lua_tointeger(L, -2)) {
|
||||
isArray = false;
|
||||
lua_pop(L, 2); // Pop value and key
|
||||
@ -509,7 +507,6 @@ doc::UserData::Vector get_value_from_lua(lua_State* L, int index)
|
||||
--index;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, index) != 0) {
|
||||
// TODO we should check that all variants are of the same type
|
||||
v.push_back(get_value_from_lua<doc::UserData::Variant>(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
@ -1375,9 +1375,13 @@ const doc::UserData::Variant AsepriteDecoder::readPropertyValue(uint16_t type)
|
||||
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
||||
auto numElems = read32();
|
||||
auto elemsType = read16();
|
||||
auto elemType = elemsType;
|
||||
std::vector<doc::UserData::Variant> value;
|
||||
for (int k=0; k<numElems;++k) {
|
||||
value.push_back(readPropertyValue(elemsType));
|
||||
if (elemsType == 0) {
|
||||
elemType = read16();
|
||||
}
|
||||
value.push_back(readPropertyValue(elemType));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -149,6 +149,10 @@ namespace doc {
|
||||
|
||||
size_t count_nonempty_properties_maps(const UserData::PropertiesMaps& propertiesMaps);
|
||||
|
||||
// If all the vector elements are of the same type returns such type.
|
||||
// Otherwise it returns -1.
|
||||
int all_elements_of_same_type(const UserData::Vector& vector);
|
||||
|
||||
} // namespace doc
|
||||
|
||||
#endif
|
||||
|
@ -55,6 +55,17 @@ size_t count_nonempty_properties_maps(const UserData::PropertiesMaps& properties
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int all_elements_of_same_type(const UserData::Vector& vector) {
|
||||
int type = vector.empty() ? 0 : vector.front().type();
|
||||
for (auto value : vector) {
|
||||
if (type != value.type()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
void write_point(std::ostream& os, const gfx::Point& point)
|
||||
{
|
||||
write32(os, point.x);
|
||||
@ -125,9 +136,8 @@ void write_property_value(std::ostream& os, const UserData::Variant& variant)
|
||||
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
||||
const std::vector<UserData::Variant>& vector = get_value<std::vector<UserData::Variant>>(variant);
|
||||
write32(os, vector.size());
|
||||
const uint16_t type = vector.size() == 0 ? 0 : vector.front().type();
|
||||
write16(os, type);
|
||||
for (auto elem : vector) {
|
||||
write16(os, elem.type());
|
||||
write_property_value(os, elem);
|
||||
}
|
||||
break;
|
||||
@ -237,10 +247,10 @@ UserData::Variant read_property_value(std::istream& is, uint16_t type)
|
||||
}
|
||||
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
||||
auto numElems = read32(is);
|
||||
auto elemsType = read16(is);
|
||||
std::vector<doc::UserData::Variant> value;
|
||||
for (int k=0; k<numElems;++k) {
|
||||
value.push_back(read_property_value(is, elemsType));
|
||||
auto elemType = read16(is);
|
||||
value.push_back(read_property_value(is, elemType));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -130,3 +130,23 @@ do
|
||||
assert(#spr.layers[2].properties("ext") == 1)
|
||||
assert(spr.layers[2].properties("ext").b == 32)
|
||||
end
|
||||
|
||||
-- Test save vector with different types inside
|
||||
do
|
||||
local spr = Sprite(32, 32)
|
||||
spr.properties.a = { 3, "hi", {4, 5, 6}, {a="bye", b=10} }
|
||||
|
||||
spr:saveAs("_test_userdata_codec_3.aseprite")
|
||||
spr:close()
|
||||
|
||||
spr = Sprite{ fromFile="_test_userdata_codec_3.aseprite" }
|
||||
assert(#spr.properties.a == 4)
|
||||
assert(spr.properties.a[1] == 3)
|
||||
assert(spr.properties.a[2] == "hi")
|
||||
assert(#spr.properties.a[3] == 3)
|
||||
assert(spr.properties.a[3][1] == 4)
|
||||
assert(spr.properties.a[3][2] == 5)
|
||||
assert(spr.properties.a[3][3] == 6)
|
||||
assert(spr.properties.a[4].a == "bye")
|
||||
assert(spr.properties.a[4].b == 10)
|
||||
end
|
Loading…
Reference in New Issue
Block a user