The Battle for Wesnoth  1.17.12+dev
lua_color.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2020 - 2022
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "color_range.hpp"
16 #include "scripting/lua_color.hpp"
17 #include "scripting/lua_common.hpp"
18 #include "scripting/push_check.hpp"
19 #include "lua/lauxlib.h"
20 #include "log.hpp"
21 #include "game_config.hpp"
22 
23 static lg::log_domain log_scripting_lua("scripting/lua");
24 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
25 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
26 
27 static const char colorKey[] = "color range";
28 
29 static bool luaW_iscolor(lua_State* L, int index)
30 {
31  return luaL_testudata(L, index, colorKey) != nullptr;
32 }
33 
34 static color_range& LuaW_checkcolor(lua_State *L, int index)
35 {
36  if(!luaW_iscolor(L, index)) {
37  luaW_type_error(L, index, "color");
38  throw "luaW_type_error returned";
39  }
40  return *static_cast<color_range*>(lua_touserdata(L, index));
41 }
42 
43 
44 static color_range* luaW_pushcolor(lua_State *L, const color_range& color)
45 {
46  color_range* res = new(L) color_range(color);
47  luaL_setmetatable(L, colorKey);
48  return res;
49 }
50 
51 static int luaW_pushsinglecolor(lua_State *L, const color_t& color)
52 {
53  lua_createtable(L, 0, 4);
54  luaW_table_set(L, -1, "r", color.r);
55  luaW_table_set(L, -1, "g", color.g);
56  luaW_table_set(L, -1, "b", color.b);
57  luaW_table_set(L, -1, "a", color.a);
58  return 1;
59 }
60 
61 static int impl_color_collect(lua_State *L)
62 {
63  color_range *c = static_cast<color_range *>(lua_touserdata(L, 1));
64  c->color_range::~color_range();
65  return 0;
66 }
67 
68 /**
69  * Checks two color units for equality. (__eq metamethod)
70  */
71 static int impl_color_equality(lua_State* L)
72 {
73  color_range& left = LuaW_checkcolor(L, 1);
74  color_range& right = LuaW_checkcolor(L, 2);
75  const bool equal = left == right;
76  lua_pushboolean(L, equal);
77  return 1;
78 }
79 
80 /**
81  * Turns a lua color to string. (__tostring metamethod)
82  */
83 static int impl_color_tostring(lua_State* L)
84 {
85  color_range& c = LuaW_checkcolor(L, 1);
86  //TODO: is this the best way to call tostring?
87  lua_push(L, c.debug());
88  return 1;
89 }
90 
91 
92 /**
93  * - Arg 1: userdata (ignored).
94  * - Arg 2: string containing the name of the color.
95  * - Ret 1: color_range containing the color.
96  */
97 static int impl_get_color(lua_State *L)
98 {
99  std::string color_id = luaL_checkstring(L, 2);
101  return 1;
102 }
103 
104 static int impl_color_get(lua_State *L)
105 {
106  color_range& c = LuaW_checkcolor(L, 1);
107  char const *m = luaL_checkstring(L, 2);
108 
109  if(strcmp(m, "min") == 0) {
110  return luaW_pushsinglecolor(L, c.min());
111  }
112  if(strcmp(m, "max") == 0) {
113  return luaW_pushsinglecolor(L, c.max());
114  }
115  if(strcmp(m, "mid") == 0) {
116  return luaW_pushsinglecolor(L, c.mid());
117  }
118  if(strcmp(m, "minimap") == 0) {
119  return luaW_pushsinglecolor(L, c.rep());
120  }
121  // returns a string which can be used in Pango's foreground= attribute
122  if(strcmp(m, "pango_color") == 0) {
123  lua_push(L, c.mid().to_hex_string());
124  return 1;
125  }
126  return 0;
127 }
128 
129 static int impl_color_dir(lua_State* L)
130 {
131  static const std::vector<std::string> keys{"min", "max", "mid", "minimap", "pango_color"};
132  lua_push(L, keys);
133  return 1;
134 }
135 
136 static int impl_color_set(lua_State *L)
137 {
138  return luaL_argerror(L, 2, "color objects canot be modified");
139 }
140 
141 static int impl_colors_table_dir(lua_State* L)
142 {
143  std::vector<std::string> all_colours;
144  for(const auto& [key, value] : game_config::team_rgb_range) {
145  all_colours.push_back(key);
146  }
147  lua_push(L, all_colours);
148  return 1;
149 }
150 
151 namespace lua_colors {
152  std::string register_metatables(lua_State* L)
153  {
154  std::ostringstream cmd_out;
155 
156  // Create the getunit metatable.
157  cmd_out << "Adding color metatable...\n";
158 
159  luaL_newmetatable(L, colorKey);
160  lua_pushcfunction(L, impl_color_collect);
161  lua_setfield(L, -2, "__gc");
162  lua_pushcfunction(L, impl_color_equality);
163  lua_setfield(L, -2, "__eq");
164  lua_pushcfunction(L, impl_color_tostring);
165  lua_setfield(L, -2, "__tostring");
166  lua_pushcfunction(L, impl_color_get);
167  lua_setfield(L, -2, "__index");
168  lua_pushcfunction(L, impl_color_set);
169  lua_setfield(L, -2, "__newindex");
170  lua_pushcfunction(L, impl_color_dir);
171  lua_setfield(L, -2, "__dir");
172  lua_pushstring(L, "color range");
173  lua_setfield(L, -2, "__metatable");
174 
175 
176  // Create the current variable with its metatable.
177  cmd_out << "Adding wesnoth.colors table...\n";
178 
179  lua_getglobal(L, "wesnoth");
180  lua_newuserdatauv(L, 0, 0);
181  lua_createtable(L, 0, 2);
182  lua_pushcfunction(L, impl_get_color);
183  lua_setfield(L, -2, "__index");
184  lua_pushcfunction(L, impl_colors_table_dir);
185  lua_setfield(L, -2, "__dir");
186  lua_pushstring(L, "colors table");
187  lua_setfield(L, -2, "__metatable");
188  lua_setmetatable(L, -2);
189  lua_setfield(L, -2, "colors");
190  lua_pop(L, 1);
191 
192  return cmd_out.str();
193  }
194 }
color_t min() const
Minimum color shade.
Definition: color_range.hpp:92
std::map< std::string, color_range > team_rgb_range
Colors defined by WML [color_range] tags.
static color_range * luaW_pushcolor(lua_State *L, const color_range &color)
Definition: lua_color.cpp:44
int luaW_type_error(lua_State *L, int narg, const char *tname)
static int impl_color_set(lua_State *L)
Definition: lua_color.cpp:136
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:373
static int impl_color_get(lua_State *L)
Definition: lua_color.cpp:104
void luaW_table_set(lua_State *L, int index, std::string_view k, const T &value)
Definition: push_check.hpp:405
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:58
std::string register_metatables(lua_State *L)
Definition: lua_color.cpp:152
static lg::log_domain log_scripting_lua("scripting/lua")
static int impl_color_tostring(lua_State *L)
Turns a lua color to string.
Definition: lua_color.cpp:83
color_t max() const
Maximum color shade.
Definition: color_range.hpp:89
static int impl_color_equality(lua_State *L)
Checks two color units for equality.
Definition: lua_color.cpp:71
std::string to_hex_string() const
Returns the stored color in rrggbb hex format.
Definition: color.cpp:78
A color range definition is made of four reference RGB colors, used for calculating conversions from ...
Definition: color_range.hpp:49
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:72
static int impl_color_dir(lua_State *L)
Definition: lua_color.cpp:129
static int impl_color_collect(lua_State *L)
Definition: lua_color.cpp:61
std::string debug() const
Return a string describing the color range for debug output.
color_t rep() const
High-contrast shade, intended for the minimap markers.
Definition: color_range.hpp:95
const color_range & color_info(const std::string &name)
Standard logging facilities (interface).
static color_range & LuaW_checkcolor(lua_State *L, int index)
Definition: lua_color.cpp:34
static int luaW_pushsinglecolor(lua_State *L, const color_t &color)
Definition: lua_color.cpp:51
static int impl_get_color(lua_State *L)
Definition: lua_color.cpp:97
mock_char c
static int impl_colors_table_dir(lua_State *L)
Definition: lua_color.cpp:141
static const char colorKey[]
Definition: lua_color.cpp:27
static bool luaW_iscolor(lua_State *L, int index)
Definition: lua_color.cpp:29
color_t mid() const
Average color shade.
Definition: color_range.hpp:86