The Battle for Wesnoth  1.15.5+dev
lua_widget.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Guillaume Melquiond <guillaume.melquiond@gmail.com>
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 "scripting/lua_widget.hpp"
17 
18 #include "log.hpp"
19 #include "gui/widgets/widget.hpp"
20 #include "scripting/lua_common.hpp"
21 #include "scripting/lua_unit.hpp"
23 #include "scripting/lua_ptr.hpp"
24 #include "scripting/push_check.hpp"
25 
26 
27 #include "lua/lauxlib.h"
28 #include "lua/lua.h" // for lua_State, lua_settop, etc
29 
30 #include <type_traits>
31 
32 static const char widgetKey[] = "widget";
33 static char widgetdataKey[] = "widgetdata";
34 
36 {
37  new(L) lua_ptr<gui2::widget>(w);
39 }
40 
42 {
44  auto ptr = lp.get_ptr();
45  if(!ptr) {
46  luaL_argerror(L, n, "widget was deleted");
47  }
48  return *ptr;
49 }
50 
52 {
54  auto ptr = lp.get_ptr();
55  if(!ptr) {
56  luaL_argerror(L, n, "widget was deleted");
57  }
58  return lp;
59 }
60 
61 
63 {
64  return luaL_testudata(L, index, widgetKey) != nullptr;
65 }
66 
67 
69 {
72  if(lua_isnoneornil(L, -1)) {
73  lua_pop(L, 1);
74  lua_createtable(L, 0, 0);
76  lua_pushvalue(L , -2);
78  }
79 }
80 
82 {
84  lua_pushlightuserdata(L, owner);
85  lua_rawget(L, -2);
86  if(lua_isnoneornil(L, -1))
87  {
88  //stack: windowstable, nil
89  lua_pop(L, 1);
90  //stack: windowstable
91  lua_createtable(L, 1, 0);
92  //stack: windowstable, {}
93  lua_pushlightuserdata(L, owner);
94  //stack: windowtable, {}, wg_id
95  lua_pushvalue(L, -2);
96  //stack: windowtable, {}, wg_id, {}
97  lua_rawset(L, -4);
98  //stack: windowtable, {}
99  }
100  lua_remove(L, lua_absindex(L, -2));
101 }
102 
104 {
106  lua_pushlightuserdata(L, owner);
107  lua_pushnil(L);
108  lua_rawset(L, -3);
109  lua_pop(L, 1);
110 }
111 
112 
114 {
115  luaW_pushwindowtable(L, owner);
116  lua_pushlightuserdata(L, wg);
117  lua_rawget(L, -2);
118  if(lua_isnoneornil(L, -1))
119  {
120  //stack: windowtable, nil
121  lua_pop(L, 1);
122  //stack: windowtable
123  lua_createtable(L, 1, 0);
124  //stack: windowtable, {}
125  luaW_pushwidget(L, *wg);
126  //stack: windowtable, {}, wg
127  lua_rawseti(L, -2, 1);
128  //stack: windowtable, { wg},
129  lua_pushlightuserdata(L, wg);
130  //stack: windowtable, { wg}, wg_id
131  lua_pushvalue(L, -2);
132  //stack: windowtable, { wg}, wg_id, {wg}
133  lua_rawset(L, -4);
134  //stack: windowtable, { wg}
135  }
136  lua_remove(L, lua_absindex(L, -2));
137 }
138 
139 
141 {
142  //stack: function
143  luaW_pushwidgettable(L, wg, owner);
144  //stack: function, {}
145  lua_push(L, name);
146  //stack: function, {}, name
147  lua_rawget(L, -2);
148  // function, old_function
149  bool existed_already = !lua_isnoneornil(L, -1);
150  lua_pop(L, 1);
151  // function,
152  lua_push(L, name);
153  //stack: function, {}, name
154  lua_rotate(L, lua_absindex(L, -3), -1);
155  //stack: {}, name, function
156  lua_rawset(L, -3);
157  //stack: {name = function}
158  lua_pop(L, 1);
159  return existed_already;
160 }
161 
163 {
164  luaW_pushwidgettable(L, wg, owner);
165  //stack: {name = function},
166  lua_push(L, name);
167  //stack: {name = function}, name
168  lua_rawget(L, -2);
169  //stack: {name = function}, function
170  lua_remove(L, lua_absindex(L, -2));
171  //stack: function
172 }
173 
175 {
176  luaW_getwidgetcallback(L, wg, owner, name);
177  assert(lua_isfunction(L, -1));
178  luaW_pushwidget(L, *wg);
179  lua_call(L, 1, 0);
180 }
181 
182 
184 {
186  w->~lua_ptr<gui2::widget>();
187  return 0;
188 }
189 
190 
191 namespace lua_widget {
193  {
194 
197  lua_setfield(L, -2, "__index");
199  lua_setfield(L, -2, "__newindex");
201  lua_setfield(L, -2, "__gc");
203  lua_setfield(L, -2, "__metatable");
204  }
205 }
int impl_widget_get(lua_State *L)
#define lua_isnoneornil(L, n)
Definition: lua.h:359
LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
Definition: lapi.cpp:565
LUALIB_API void * luaL_checkudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:333
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:684
#define lua_pushcfunction(L, f)
Definition: lua.h:350
void luaW_callwidgetcallback(lua_State *L, gui2::widget *wg, gui2::window *owner, utils::string_view name)
callas a widgets callback [-0, +0, e]
Definition: lua_widget.cpp:174
LUA_API void lua_rawseti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:817
Tmust inherit enable_lua_ptr<T>
Definition: lua_ptr.hpp:18
Base class for all widgets.
Definition: widget.hpp:49
#define lua_remove(L, idx)
Definition: lua.h:371
LUA_API int lua_rawget(lua_State *L, int idx)
Definition: lapi.cpp:647
void luaW_pushwidget(lua_State *L, gui2::widget &w)
Definition: lua_widget.cpp:35
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:312
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:400
T * get_ptr()
Definition: lua_ptr.hpp:36
LUA_API int lua_absindex(lua_State *L, int idx)
Definition: lapi.cpp:160
#define lua_pop(L, n)
Definition: lua.h:344
LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
Definition: lauxlib.cpp:164
bool luaW_setwidgetcallback(lua_State *L, gui2::widget *wg, gui2::window *owner, utils::string_view name)
returns true if a callback already existed. [-1, +0, -]
Definition: lua_widget.cpp:140
static char widgetdataKey[]
Definition: lua_widget.cpp:33
LUALIB_API void * luaL_testudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:318
LUA_API void lua_pushnil(lua_State *L)
Definition: lapi.cpp:450
void luaW_pushwindowtable(lua_State *L, gui2::window *owner)
[-0, +1, -]
Definition: lua_widget.cpp:81
void register_metatable(lua_State *L)
Definition: lua_widget.cpp:192
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:299
LUA_API void lua_rawset(lua_State *L, int idx)
Definition: lapi.cpp:801
gui2::widget & luaW_checkwidget(lua_State *L, int n)
Definition: lua_widget.cpp:41
static const char widgetKey[]
Definition: lua_widget.cpp:32
#define lua_isfunction(L, n)
Definition: lua.h:352
int w
LUA_API void lua_rotate(lua_State *L, int idx, int n)
Definition: lapi.cpp:207
LUA_API void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.cpp:237
lua_ptr< gui2::widget > & luaW_checkwidget_ptr(lua_State *L, int n)
Definition: lua_widget.cpp:51
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:71
#define lua_call(L, n, r)
Definition: lua.h:274
#define LUA_REGISTRYINDEX
Definition: lua.h:42
bool luaW_iswidget(lua_State *L, int index)
Definition: lua_widget.cpp:62
static int impl_widget_collect(lua_State *L)
Definition: lua_widget.cpp:183
Standard logging facilities (interface).
static void luaW_pushwidgettablecontainer(lua_State *L)
Definition: lua_widget.cpp:68
void luaW_getwidgetcallback(lua_State *L, gui2::widget *wg, gui2::window *owner, utils::string_view name)
pushed ther callback function onoto the stack [-0, +1, -]
Definition: lua_widget.cpp:162
void luaW_clearwindowtable(lua_State *L, gui2::window *owner)
[-0, +0, -]
Definition: lua_widget.cpp:103
int impl_widget_set(lua_State *L)
static map_location::DIRECTION n
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:491
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:777
void luaW_pushwidgettable(lua_State *L, gui2::widget *wg, gui2::window *owner)
[-0, +1, -]
Definition: lua_widget.cpp:113