mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-30 04:20:23 +00:00
[lua] Add support to set/get tables (arrays/maps) into user properties
This commit is contained in:
parent
11dbb22efa
commit
9138592e98
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2022 Igara Studio S.A.
|
||||
// Copyright (C) 2022-2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -79,8 +79,7 @@ int Properties_newindex(lua_State* L)
|
||||
switch (lua_type(L, 3)) {
|
||||
|
||||
case LUA_TNONE:
|
||||
case LUA_TNIL:
|
||||
default: {
|
||||
case LUA_TNIL: {
|
||||
// Just erase the property
|
||||
auto it = properties.find(field);
|
||||
if (it != properties.end())
|
||||
@ -88,32 +87,9 @@ int Properties_newindex(lua_State* L)
|
||||
break;
|
||||
}
|
||||
|
||||
case LUA_TBOOLEAN:
|
||||
properties[field] = (lua_toboolean(L, 3) ? true: false);
|
||||
default:
|
||||
properties[field] = get_value_from_lua<doc::UserData::Variant>(L, 3);
|
||||
break;
|
||||
|
||||
case LUA_TNUMBER:
|
||||
if (lua_isinteger(L, 3))
|
||||
properties[field] = lua_tointeger(L, 3);
|
||||
else {
|
||||
properties[field] = doc::UserData::Fixed{
|
||||
fixmath::ftofix(lua_tonumber(L, 3))
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case LUA_TSTRING:
|
||||
properties[field] = std::string(lua_tostring(L, 3));
|
||||
break;
|
||||
|
||||
case LUA_TTABLE:
|
||||
// TODO convert a full table into properties recursively
|
||||
break;
|
||||
|
||||
case LUA_TUSERDATA:
|
||||
// TODO convert table-like objects (Size, Point, Rectangle, etc.)
|
||||
break;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -275,20 +275,21 @@ FOR_ENUM(filters::TiledMode)
|
||||
FOR_ENUM(render::OnionskinPosition)
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// UserData::Properties / VariantStruct
|
||||
// UserData::Properties / Variant
|
||||
|
||||
template<>
|
||||
void push_value_to_lua(lua_State* L, const doc::UserData::Properties& value) {
|
||||
// TODO convert a Properties map into a Lua table
|
||||
}
|
||||
void push_value_to_lua(lua_State* L, const doc::UserData::Properties& value);
|
||||
template<>
|
||||
void push_value_to_lua(lua_State* L, const doc::UserData::Vector& value);
|
||||
|
||||
template<>
|
||||
void push_value_to_lua(lua_State* L, const doc::UserData::Vector& value) {
|
||||
// TODO convert a Vector into a Lua table
|
||||
}
|
||||
doc::UserData::Properties get_value_from_lua(lua_State* L, int index);
|
||||
template<>
|
||||
doc::UserData::Vector get_value_from_lua(lua_State* L, int index);
|
||||
|
||||
template<>
|
||||
void push_value_to_lua(lua_State* L, const doc::UserData::Variant& value) {
|
||||
void push_value_to_lua(lua_State* L, const doc::UserData::Variant& value)
|
||||
{
|
||||
#if 1 // We are targetting macOS 10.9, so we don't have the std::visit() available
|
||||
switch (value.type()) {
|
||||
case USER_DATA_PROPERTY_TYPE_BOOL:
|
||||
@ -345,5 +346,147 @@ void push_value_to_lua(lua_State* L, const doc::UserData::Variant& value) {
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
doc::UserData::Variant get_value_from_lua(lua_State* L, int index)
|
||||
{
|
||||
doc::UserData::Variant v;
|
||||
|
||||
switch (lua_type(L, index)) {
|
||||
|
||||
case LUA_TNONE:
|
||||
case LUA_TNIL:
|
||||
// TODO should we add nullptr_t in Variant?
|
||||
break;
|
||||
|
||||
case LUA_TBOOLEAN:
|
||||
v = (lua_toboolean(L, index) ? true: false);
|
||||
break;
|
||||
|
||||
case LUA_TNUMBER:
|
||||
if (lua_isinteger(L, index))
|
||||
v = lua_tointeger(L, index);
|
||||
else {
|
||||
v = doc::UserData::Fixed{
|
||||
fixmath::ftofix(lua_tonumber(L, index))
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case LUA_TSTRING:
|
||||
v = std::string(lua_tostring(L, index));
|
||||
break;
|
||||
|
||||
case LUA_TTABLE: {
|
||||
int i = 0;
|
||||
bool isArray = true;
|
||||
if (index < 0)
|
||||
--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
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
isArray = false;
|
||||
lua_pop(L, 2);
|
||||
break;
|
||||
}
|
||||
lua_pop(L, 1); // Pop the value, leave the key for lua_next()
|
||||
}
|
||||
if (index < 0)
|
||||
++index;
|
||||
if (isArray) {
|
||||
v = get_value_from_lua<doc::UserData::Vector>(L, index);
|
||||
}
|
||||
else {
|
||||
v = get_value_from_lua<doc::UserData::Properties>(L, index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LUA_TUSERDATA: {
|
||||
if (auto rect = may_get_obj<gfx::Rect>(L, index)) {
|
||||
v = *rect;
|
||||
}
|
||||
else if (auto pt = may_get_obj<gfx::Point>(L, index)) {
|
||||
v = *pt;
|
||||
}
|
||||
else if (auto sz = may_get_obj<gfx::Size>(L, index)) {
|
||||
v = *sz;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
template<>
|
||||
void push_value_to_lua(lua_State* L, const doc::UserData::Properties& value)
|
||||
{
|
||||
lua_newtable(L);
|
||||
for (const auto& kv : value) {
|
||||
push_value_to_lua(L, kv.second);
|
||||
lua_setfield(L, -2, kv.first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void push_value_to_lua(lua_State* L, const doc::UserData::Vector& value)
|
||||
{
|
||||
int i = 0;
|
||||
lua_newtable(L);
|
||||
for (const auto& kv : value) {
|
||||
push_value_to_lua(L, kv);
|
||||
lua_seti(L, -2, ++i);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
doc::UserData::Properties get_value_from_lua(lua_State* L, int index)
|
||||
{
|
||||
doc::UserData::Properties m;
|
||||
|
||||
if (index < 0)
|
||||
--index;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, index) != 0) {
|
||||
if (auto k = lua_tostring(L, -2))
|
||||
m[k] = get_value_from_lua<doc::UserData::Variant>(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
template<>
|
||||
doc::UserData::Vector get_value_from_lua(lua_State* L, int index)
|
||||
{
|
||||
doc::UserData::Vector v;
|
||||
|
||||
lua_len(L, index);
|
||||
int len = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
if (len > 0)
|
||||
v.reserve(len);
|
||||
|
||||
if (index < 0)
|
||||
--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);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
} // namespace script
|
||||
} // namespace app
|
||||
|
@ -1,4 +1,4 @@
|
||||
-- Copyright (C) 2022 Igara Studio S.A.
|
||||
-- Copyright (C) 2022-2023 Igara Studio S.A.
|
||||
--
|
||||
-- This file is released under the terms of the MIT license.
|
||||
-- Read LICENSE.txt for more information.
|
||||
@ -32,4 +32,44 @@ do
|
||||
|
||||
spr.properties.b = nil
|
||||
assert(spr.properties.b == nil)
|
||||
assert(#spr.properties == 3)
|
||||
|
||||
spr.properties.v = { 10, 20, 30 }
|
||||
assert(#spr.properties.v == 3)
|
||||
assert(spr.properties.v[1] == 10)
|
||||
assert(spr.properties.v[2] == 20)
|
||||
assert(spr.properties.v[3] == 30)
|
||||
|
||||
spr.properties.u = spr.properties.v -- Copy a property
|
||||
assert(#spr.properties.u == 3)
|
||||
assert(spr.properties.u[1] == 10)
|
||||
assert(spr.properties.u[2] == 20)
|
||||
assert(spr.properties.u[3] == 30)
|
||||
|
||||
spr.properties.m = { a=10,
|
||||
b="bye",
|
||||
c={ "a", "b", "c" },
|
||||
d={ a=1, b="d", c={ x=2, y=0.5, z=0 } },
|
||||
e=Point(32, 20),
|
||||
f=Size(40, 80),
|
||||
g=Rectangle(2, 4, 6, 8) }
|
||||
local m = spr.properties.m
|
||||
assert(m.a == 10)
|
||||
assert(m.b == "bye")
|
||||
assert(m.c[1] == "a")
|
||||
assert(m.c[2] == "b")
|
||||
assert(m.c[3] == "c")
|
||||
assert(m.d.a == 1)
|
||||
assert(m.d.b == "d")
|
||||
assert(m.d.c.x == 2)
|
||||
assert(m.d.c.y == 0.5)
|
||||
assert(m.d.c.z == 0)
|
||||
assert(m.e.x == 32)
|
||||
assert(m.e.y == 20)
|
||||
assert(m.f.width == 40)
|
||||
assert(m.f.height == 80)
|
||||
assert(m.g.x == 2)
|
||||
assert(m.g.y == 4)
|
||||
assert(m.g.width == 6)
|
||||
assert(m.g.height == 8)
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user