Add UUID type to user properties (fix #3810)

This commit is contained in:
Martín Capello 2023-04-17 14:48:27 -03:00 committed by David Capello
parent 948bf98b86
commit da80192d0f
8 changed files with 72 additions and 4 deletions

View File

@ -43,6 +43,7 @@ ASE files use Intel (little-endian) byte order.
* `TILE`: **Tilemaps**: Each tile can be a 8-bit (`BYTE`), 16-bit
(`WORD`), or 32-bit (`DWORD`) value and there are masks related to
the meaning of each bit.
* `UUID`: A Universally Unique Identifier stored as `BYTE[16]`.
## Introduction
@ -446,6 +447,8 @@ The data of this chunk is as follows:
DWORD Number of properties
BYTE[] Nested properties data
Structure is the same as indicated in this loop
+ If type==0x0013
UUID
### Slice Chunk (0x2022)

View File

@ -1610,6 +1610,13 @@ static void ase_file_write_property_value(FILE* f,
}
break;
}
case USER_DATA_PROPERTY_TYPE_UUID: {
auto& uuid = *std::get_if<base::Uuid>(&value);
for (int i=0; i<16; ++i) {
fputc(uuid[i], f);
}
break;
}
}
}

View File

@ -108,6 +108,7 @@ TEST(File, CustomProperties)
{"weight", doc::UserData::Fixed{fixmath::ftofix(50.34)}},
{"big_number", int64_t(9223372036854775807)},
{"unsigned_big_number", uint64_t(18446744073709551615ULL)},
{"my_uuid", base::Uuid::Generate()},
}
}
},
@ -121,6 +122,8 @@ TEST(File, CustomProperties)
ASSERT_EQ(doc::get_value<doc::UserData::Fixed>(sprite->userData().properties()["weight"]).value, fixmath::ftofix(50.34));
ASSERT_EQ(doc::get_value<int64_t>(sprite->userData().properties()["big_number"]), 9223372036854775807);
ASSERT_EQ(doc::get_value<uint64_t>(sprite->userData().properties()["unsigned_big_number"]), 18446744073709551615ULL);
ASSERT_EQ(doc::get_value<base::Uuid>(sprite->userData().properties()["my_uuid"]),
doc::get_value<base::Uuid>(test.propertiesMaps.at("").at("my_uuid")));
}
},
{ // Test sprite's userData extension's simple properties
@ -130,7 +133,8 @@ TEST(File, CustomProperties)
{"number", int32_t(160304)},
{"is_solid", bool(false)},
{"label", std::string("Smoke")},
{"weight", doc::UserData::Fixed{fixmath::ftofix(0.14)}}
{"weight", doc::UserData::Fixed{fixmath::ftofix(0.14)}},
{"my_uuid", base::Uuid::Generate()},
}
}
},
@ -142,6 +146,8 @@ TEST(File, CustomProperties)
ASSERT_EQ(doc::get_value<bool>(sprite->userData().properties("extensionIdentification")["is_solid"]), false);
ASSERT_EQ(doc::get_value<std::string>(sprite->userData().properties("extensionIdentification")["label"]), "Smoke");
ASSERT_EQ(doc::get_value<doc::UserData::Fixed>(sprite->userData().properties("extensionIdentification")["weight"]).value, fixmath::ftofix(0.14));
ASSERT_EQ(doc::get_value<base::Uuid>(sprite->userData().properties("extensionIdentification")["my_uuid"]),
doc::get_value<base::Uuid>(test.propertiesMaps.at("extensionIdentification").at("my_uuid")));
}
},
{ // Test sprite's userData custom + extension's simple properties
@ -151,14 +157,16 @@ TEST(File, CustomProperties)
{"number", int32_t(560304)},
{"is_solid", bool(true)},
{"label", std::string("Rock")},
{"weight", doc::UserData::Fixed{fixmath::ftofix(50.34)}}
{"weight", doc::UserData::Fixed{fixmath::ftofix(50.34)}},
{"my_uuid", base::Uuid::Generate()},
}
},
{"extensionIdentification", {
{"number", int32_t(160304)},
{"is_solid", bool(false)},
{"label", std::string("Smoke")},
{"weight", doc::UserData::Fixed{fixmath::ftofix(0.14)}}
{"weight", doc::UserData::Fixed{fixmath::ftofix(0.14)}},
{"my_uuid2", base::Uuid::Generate()},
}
}
},
@ -170,11 +178,15 @@ TEST(File, CustomProperties)
ASSERT_EQ(doc::get_value<bool>(sprite->userData().properties()["is_solid"]), true);
ASSERT_EQ(doc::get_value<std::string>(sprite->userData().properties()["label"]), "Rock");
ASSERT_EQ(doc::get_value<doc::UserData::Fixed>(sprite->userData().properties()["weight"]).value, fixmath::ftofix(50.34));
ASSERT_EQ(doc::get_value<base::Uuid>(sprite->userData().properties("")["my_uuid"]),
doc::get_value<base::Uuid>(test.propertiesMaps.at("").at("my_uuid")));
ASSERT_EQ(doc::get_value<int32_t>(sprite->userData().properties("extensionIdentification")["number"]), 160304);
ASSERT_EQ(doc::get_value<bool>(sprite->userData().properties("extensionIdentification")["is_solid"]), false);
ASSERT_EQ(doc::get_value<std::string>(sprite->userData().properties("extensionIdentification")["label"]), "Smoke");
ASSERT_EQ(doc::get_value<doc::UserData::Fixed>(sprite->userData().properties("extensionIdentification")["weight"]).value, fixmath::ftofix(0.14));
ASSERT_EQ(doc::get_value<base::Uuid>(sprite->userData().properties("extensionIdentification")["my_uuid2"]),
doc::get_value<base::Uuid>(test.propertiesMaps.at("extensionIdentification").at("my_uuid2")));
}
},
{ // Test sprite's userData complex properties

View File

@ -16,6 +16,7 @@
#include "app/color.h"
#include "app/commands/params.h"
#include "app/extensions.h"
#include "base/uuid.h"
#include "doc/brush.h"
#include "doc/frame.h"
#include "doc/object_ids.h"
@ -182,6 +183,7 @@ namespace app {
app::Color convert_args_into_color(lua_State* L, int index);
doc::color_t convert_args_into_pixel_color(lua_State* L, int index,
const doc::PixelFormat pixelFormat);
base::Uuid convert_args_into_uuid(lua_State* L, int index);
doc::Palette* get_palette_from_arg(lua_State* L, int index);
doc::Image* may_get_image_from_arg(lua_State* L, int index);
doc::Image* get_image_from_arg(lua_State* L, int index);

View File

@ -217,6 +217,19 @@ gfx::Rect get_value_from_lua(lua_State* L, int index) {
return convert_args_into_rect(L, index);
}
// ----------------------------------------------------------------------
// Uuid
template<>
void push_value_to_lua(lua_State* L, const base::Uuid& value) {
push_obj(L, value);
}
template<>
base::Uuid get_value_from_lua(lua_State* L, int index) {
return convert_args_into_uuid(L, index);
}
// ----------------------------------------------------------------------
// tools::InkType
@ -372,6 +385,9 @@ void push_value_to_lua(lua_State* L, const doc::UserData::Variant& value)
case USER_DATA_PROPERTY_TYPE_PROPERTIES:
push_value_to_lua(L, *std::get_if<doc::UserData::Properties>(&value));
break;
case USER_DATA_PROPERTY_TYPE_UUID:
push_value_to_lua(L, *std::get_if<base::Uuid>(&value));
break;
}
#else // TODO enable this in the future
std::visit([L](auto&& v){ push_value_to_lua(L, v); }, value);
@ -461,6 +477,9 @@ doc::UserData::Variant get_value_from_lua(lua_State* L, int index)
else if (auto sz = may_get_obj<gfx::Size>(L, index)) {
v = *sz;
}
else if (auto uuid = may_get_obj<base::Uuid>(L, index)) {
v = *uuid;
}
break;
}
}

View File

@ -1412,6 +1412,14 @@ const doc::UserData::Variant AsepriteDecoder::readPropertyValue(uint16_t type)
}
return value;
}
case USER_DATA_PROPERTY_TYPE_UUID: {
base::Uuid value;
uint8_t* bytes = value.bytes();
for (int i=0; i<16; ++i) {
bytes[i] = read8();
}
return value;
}
}
return doc::UserData::Variant{};

View File

@ -9,6 +9,7 @@
#define DOC_USER_DATA_H_INCLUDED
#pragma once
#include "base/uuid.h"
#include "doc/color.h"
#include "fixmath/fixmath.h"
#include "gfx/point.h"
@ -42,6 +43,7 @@
#define USER_DATA_PROPERTY_TYPE_RECT 0x0010
#define USER_DATA_PROPERTY_TYPE_VECTOR 0x0011
#define USER_DATA_PROPERTY_TYPE_PROPERTIES 0x0012
#define USER_DATA_PROPERTY_TYPE_UUID 0x0013
namespace doc {
@ -71,7 +73,8 @@ namespace doc {
gfx::Size,
gfx::Rect,
Vector,
Properties>;
Properties,
base::Uuid>;
struct Variant : public VariantBase {
Variant() = default;

View File

@ -112,6 +112,12 @@ static void write_property_value(std::ostream& os, const UserData::Variant& vari
}
break;
}
case USER_DATA_PROPERTY_TYPE_UUID: {
auto uuid = get_value<base::Uuid>(variant);
for (int i=0; i<16; ++i) {
write8(os, uuid[i]);
}
}
}
}
@ -227,6 +233,14 @@ static UserData::Variant read_property_value(std::istream& is, uint16_t type)
}
return value;
}
case USER_DATA_PROPERTY_TYPE_UUID: {
base::Uuid value;
uint8_t* bytes = value.bytes();
for (int i; i<16;++i) {
bytes[i] = read8(is);
}
return value;
}
}
return doc::UserData::Variant{};