1// Aseprite
2// Copyright (C) 2019-2022 Igara Studio S.A.
3//
4// This program is distributed under the terms of
5// the End-User License Agreement for Aseprite.
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include "app/script/values.h"
12
13#include "app/pref/preferences.h"
14#include "app/script/engine.h"
15#include "app/script/luacpp.h"
16
17#include <any>
18
19namespace app {
20namespace script {
21
22// TODO this is similar to app::Param<> specializations::fromLua() specializations
23
24// ----------------------------------------------------------------------
25// bool
26
27template<>
28void push_value_to_lua(lua_State* L, const bool& value) {
29 lua_pushboolean(L, value);
30}
31
32template<>
33bool get_value_from_lua(lua_State* L, int index) {
34 return lua_toboolean(L, index);
35}
36
37// ----------------------------------------------------------------------
38// int
39
40template<>
41void push_value_to_lua(lua_State* L, const int& value) {
42 lua_pushinteger(L, value);
43}
44
45template<>
46int get_value_from_lua(lua_State* L, int index) {
47 return lua_tointeger(L, index);
48}
49
50// ----------------------------------------------------------------------
51// double
52
53template<>
54void push_value_to_lua(lua_State* L, const double& value) {
55 lua_pushnumber(L, value);
56}
57
58template<>
59double get_value_from_lua(lua_State* L, int index) {
60 return lua_tonumber(L, index);
61}
62
63// ----------------------------------------------------------------------
64// std::string
65
66template<>
67void push_value_to_lua(lua_State* L, const std::string& value) {
68 lua_pushstring(L, value.c_str());
69}
70
71template<>
72std::string get_value_from_lua(lua_State* L, int index) {
73 if (const char* v = lua_tostring(L, index))
74 return std::string(v);
75 else
76 return std::string();
77}
78
79// ----------------------------------------------------------------------
80// std::any
81
82template<>
83void push_value_to_lua(lua_State* L, const std::any& value) {
84 if (!value.has_value())
85 lua_pushnil(L);
86 else if (const bool* v = std::any_cast<bool>(&value))
87 push_value_to_lua(L, *v);
88 else if (const int* v = std::any_cast<int>(&value))
89 push_value_to_lua(L, *v);
90 else if (const std::string* v = std::any_cast<std::string>(&value))
91 push_value_to_lua(L, *v);
92 else {
93 ASSERT(false);
94 throw std::runtime_error("Cannot convert type inside std::any");
95 }
96}
97
98// ----------------------------------------------------------------------
99// Color
100
101template<>
102void push_value_to_lua(lua_State* L, const app::Color& value) {
103 push_obj(L, value);
104}
105
106template<>
107app::Color get_value_from_lua(lua_State* L, int index) {
108 return convert_args_into_color(L, index);
109}
110
111// ----------------------------------------------------------------------
112// Point
113
114template<>
115void push_value_to_lua(lua_State* L, const gfx::Point& value) {
116 push_obj(L, value);
117}
118
119template<>
120gfx::Point get_value_from_lua(lua_State* L, int index) {
121 return convert_args_into_point(L, index);
122}
123
124// ----------------------------------------------------------------------
125// Size
126
127template<>
128void push_value_to_lua(lua_State* L, const gfx::Size& value) {
129 push_obj(L, value);
130}
131
132template<>
133gfx::Size get_value_from_lua(lua_State* L, int index) {
134 return convert_args_into_size(L, index);
135}
136
137// ----------------------------------------------------------------------
138// Rect
139
140template<>
141void push_value_to_lua(lua_State* L, const gfx::Rect& value) {
142 push_obj(L, value);
143}
144
145template<>
146gfx::Rect get_value_from_lua(lua_State* L, int index) {
147 return convert_args_into_rect(L, index);
148}
149
150// ----------------------------------------------------------------------
151// tools::InkType
152
153template<>
154void push_value_to_lua(lua_State* L, const app::tools::InkType& inkType) {
155 lua_pushinteger(L, (int)inkType);
156}
157
158template<>
159app::tools::InkType get_value_from_lua(lua_State* L, int index) {
160 if (lua_type(L, index) == LUA_TSTRING) {
161 if (const char* s = lua_tostring(L, index))
162 return app::tools::string_id_to_ink_type(s);
163 }
164 return (app::tools::InkType)lua_tointeger(L, index);
165}
166
167// ----------------------------------------------------------------------
168// doc::tile_t
169
170template<>
171void push_value_to_lua(lua_State* L, const doc::tile_t& value) {
172 lua_pushinteger(L, value);
173}
174
175template<>
176doc::tile_t get_value_from_lua(lua_State* L, int index) {
177 return lua_tointeger(L, index);
178}
179
180// ----------------------------------------------------------------------
181// enums
182
183#define FOR_ENUM(T) \
184 template<> \
185 void push_value_to_lua(lua_State* L, const T& value) { \
186 lua_pushinteger(L, static_cast<int>(value)); \
187 } \
188 \
189 template<> \
190 T get_value_from_lua(lua_State* L, int index) { \
191 return static_cast<T>(lua_tointeger(L, index)); \
192 }
193
194FOR_ENUM(app::CelsTarget)
195FOR_ENUM(app::ColorBar::ColorSelector)
196FOR_ENUM(app::SpriteSheetDataFormat)
197FOR_ENUM(app::SpriteSheetType)
198FOR_ENUM(app::gen::BgType)
199FOR_ENUM(app::gen::BrushPreview)
200FOR_ENUM(app::gen::BrushType)
201FOR_ENUM(app::gen::ColorProfileBehavior)
202FOR_ENUM(app::gen::Downsampling)
203FOR_ENUM(app::gen::EyedropperChannel)
204FOR_ENUM(app::gen::EyedropperSample)
205FOR_ENUM(app::gen::FillReferTo)
206FOR_ENUM(app::gen::OnionskinType)
207FOR_ENUM(app::gen::PaintingCursorType)
208FOR_ENUM(app::gen::PivotPosition)
209FOR_ENUM(app::gen::PixelConnectivity)
210FOR_ENUM(app::gen::RightClickMode)
211FOR_ENUM(app::gen::SelectionMode)
212FOR_ENUM(app::gen::SequenceDecision)
213FOR_ENUM(app::gen::StopAtGrid)
214FOR_ENUM(app::gen::SymmetryMode)
215FOR_ENUM(app::gen::TimelinePosition)
216FOR_ENUM(app::gen::ToGrayAlgorithm)
217FOR_ENUM(app::gen::WindowColorProfile)
218FOR_ENUM(app::tools::FreehandAlgorithm)
219FOR_ENUM(app::tools::RotationAlgorithm)
220FOR_ENUM(doc::AniDir)
221FOR_ENUM(doc::BrushPattern)
222FOR_ENUM(doc::ColorMode)
223FOR_ENUM(doc::RgbMapAlgorithm)
224FOR_ENUM(filters::HueSaturationFilter::Mode)
225FOR_ENUM(filters::TiledMode)
226FOR_ENUM(render::OnionskinPosition)
227
228} // namespace script
229} // namespace app
230