mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-06 06:50:07 +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: {
|
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
||||||
auto& v = *std::get_if<UserData::Vector>(&value);
|
auto& v = *std::get_if<UserData::Vector>(&value);
|
||||||
fputl(v.size(), f);
|
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);
|
fputw(type, f);
|
||||||
for (const auto& elem : v) {
|
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);
|
ase_file_write_property_value(f, elem);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -413,8 +413,6 @@ doc::UserData::Variant get_value_from_lua(lua_State* L, int index)
|
|||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, index) != 0) {
|
while (lua_next(L, index) != 0) {
|
||||||
if (lua_isinteger(L, -2)) {
|
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)) {
|
if (++i != lua_tointeger(L, -2)) {
|
||||||
isArray = false;
|
isArray = false;
|
||||||
lua_pop(L, 2); // Pop value and key
|
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;
|
--index;
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, index) != 0) {
|
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));
|
v.push_back(get_value_from_lua<doc::UserData::Variant>(L, -1));
|
||||||
lua_pop(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: {
|
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
||||||
auto numElems = read32();
|
auto numElems = read32();
|
||||||
auto elemsType = read16();
|
auto elemsType = read16();
|
||||||
|
auto elemType = elemsType;
|
||||||
std::vector<doc::UserData::Variant> value;
|
std::vector<doc::UserData::Variant> value;
|
||||||
for (int k=0; k<numElems;++k) {
|
for (int k=0; k<numElems;++k) {
|
||||||
value.push_back(readPropertyValue(elemsType));
|
if (elemsType == 0) {
|
||||||
|
elemType = read16();
|
||||||
|
}
|
||||||
|
value.push_back(readPropertyValue(elemType));
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,10 @@ namespace doc {
|
|||||||
|
|
||||||
size_t count_nonempty_properties_maps(const UserData::PropertiesMaps& propertiesMaps);
|
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
|
} // namespace doc
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -55,6 +55,17 @@ size_t count_nonempty_properties_maps(const UserData::PropertiesMaps& properties
|
|||||||
return i;
|
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)
|
void write_point(std::ostream& os, const gfx::Point& point)
|
||||||
{
|
{
|
||||||
write32(os, point.x);
|
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: {
|
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
||||||
const std::vector<UserData::Variant>& vector = get_value<std::vector<UserData::Variant>>(variant);
|
const std::vector<UserData::Variant>& vector = get_value<std::vector<UserData::Variant>>(variant);
|
||||||
write32(os, vector.size());
|
write32(os, vector.size());
|
||||||
const uint16_t type = vector.size() == 0 ? 0 : vector.front().type();
|
|
||||||
write16(os, type);
|
|
||||||
for (auto elem : vector) {
|
for (auto elem : vector) {
|
||||||
|
write16(os, elem.type());
|
||||||
write_property_value(os, elem);
|
write_property_value(os, elem);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -237,10 +247,10 @@ UserData::Variant read_property_value(std::istream& is, uint16_t type)
|
|||||||
}
|
}
|
||||||
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
||||||
auto numElems = read32(is);
|
auto numElems = read32(is);
|
||||||
auto elemsType = read16(is);
|
|
||||||
std::vector<doc::UserData::Variant> value;
|
std::vector<doc::UserData::Variant> value;
|
||||||
for (int k=0; k<numElems;++k) {
|
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;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -130,3 +130,23 @@ do
|
|||||||
assert(#spr.layers[2].properties("ext") == 1)
|
assert(#spr.layers[2].properties("ext") == 1)
|
||||||
assert(spr.layers[2].properties("ext").b == 32)
|
assert(spr.layers[2].properties("ext").b == 32)
|
||||||
end
|
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