The Battle for Wesnoth  1.17.0-dev
lua_widget.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2021
3  by Guillaume Melquiond <guillaume.melquiond@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "scripting/lua_widget.hpp"
18 
19 #include "log.hpp"
20 #include "gui/widgets/widget.hpp"
21 #include "scripting/lua_common.hpp"
22 #include "scripting/lua_unit.hpp"
24 #include "scripting/lua_ptr.hpp"
25 #include "scripting/push_check.hpp"
26 
27 
28 #include "lua/lauxlib.h"
29 #include "lua/lua.h" // for lua_State, lua_settop, etc
30 
31 #include <type_traits>
32 
33 static const char widgetKey[] = "widget";
34 static char widgetdataKey[] = "widgetdata";
35 
37 {
38  new(L) lua_ptr<gui2::widget>(w);
40 }
41 
43 {
45  auto ptr = lp.get_ptr();
46  if(!ptr) {
47  luaL_argerror(L, n, "widget was deleted");
48  }
49  return *ptr;
50 }
51 
53 {
55  auto ptr = lp.get_ptr();
56  if(!ptr) {
57  luaL_argerror(L, n, "widget was deleted");
58  }
59  return lp;
60 }
61 
62 
64 {
65  return luaL_testudata(L, index, widgetKey) != nullptr;
66 }
67 
68 
70 {
73  if(lua_isnoneornil(L, -1)) {
74  lua_pop(L, 1);
75  lua_createtable(L, 0, 0);
77  lua_pushvalue(L , -2);
79  }
80 }
81 
83 {
85  lua_pushlightuserdata(L, owner);
86  lua_rawget(L, -2);
87  if(lua_isnoneornil(L, -1))
88  {
89  //stack: windowstable, nil
90  lua_pop(L, 1);
91  //stack: windowstable
92  lua_createtable(L, 1, 0);
93  //stack: windowstable, {}
94  lua_pushlightuserdata(L, owner);
95  //stack: windowtable, {}, wg_id
96  lua_pushvalue(L, -2);
97  //stack: windowtable, {}, wg_id, {}
98  lua_rawset(L, -4);
99  //stack: windowtable, {}
100  }
101  lua_remove(L, lua_absindex(L, -2));
102 }
103 
105 {
107  lua_pushlightuserdata(L, owner);
108  lua_pushnil(L);
109  lua_rawset(L, -3);
110  lua_pop(L, 1);
111 }
112 
113 
115 {
116  luaW_pushwindowtable(L, owner);
117  lua_pushlightuserdata(L, wg);
118  lua_rawget(L, -2);
119  if(lua_isnoneornil(L, -1))
120  {
121  //stack: windowtable, nil
122  lua_pop(L, 1);
123  //stack: windowtable
124  lua_createtable(L, 1, 0);
125  //stack: windowtable, {}
126  luaW_pushwidget(L, *wg);
127  //stack: windowtable, {}, wg
128  lua_rawseti(L, -2, 1);
129  //stack: windowtable, { wg},
130  lua_pushlightuserdata(L, wg);
131  //stack: windowtable, { wg}, wg_id
132  lua_pushvalue(L, -2);
133  //stack: windowtable, { wg}, wg_id, {wg}
134  lua_rawset(L, -4);
135  //stack: windowtable, { wg}
136  }
137  lua_remove(L, lua_absindex(L, -2));
138 }
139 
140 
141 bool luaW_setwidgetcallback(lua_State* L, gui2::widget* wg, gui2::window* owner, std::string_view name)
142 {
143  //stack: function
144  luaW_pushwidgettable(L, wg, owner);
145  //stack: function, {}
146  lua_push(L, name);
147  //stack: function, {}, name
148  lua_rawget(L, -2);
149  // function, old_function
150  bool existed_already = !lua_isnoneornil(L, -1);
151  lua_pop(L, 1);
152  // function,
153  lua_push(L, name);
154  //stack: function, {}, name
155  lua_rotate(L, lua_absindex(L, -3), -1);
156  //stack: {}, name, function
157  lua_rawset(L, -3);
158  //stack: {name = function}
159  lua_pop(L, 1);
160  return existed_already;
161 }
162 
163 void luaW_getwidgetcallback(lua_State* L, gui2::widget* wg, gui2::window* owner, std::string_view name)
164 {
165  luaW_pushwidgettable(L, wg, owner);
166  //stack: {name = function},
167  lua_push(L, name);
168  //stack: {name = function}, name
169  lua_rawget(L, -2);
170  //stack: {name = function}, function
171  lua_remove(L, lua_absindex(L, -2));
172  //stack: function
173 }
174 
175 void luaW_callwidgetcallback(lua_State* L, gui2::widget* wg, gui2::window* owner, std::string_view name)
176 {
177  luaW_getwidgetcallback(L, wg, owner, name);
178  assert(lua_isfunction(L, -1));
179  luaW_pushwidget(L, *wg);
180  lua_call(L, 1, 0);
181 }
182 
183 
185 {
187  w->~lua_ptr<gui2::widget>();
188  return 0;
189 }
190 
191 
192 namespace lua_widget {
194  {
195 
198  lua_setfield(L, -2, "__index");
200  lua_setfield(L, -2, "__newindex");
202  lua_setfield(L, -2, "__gc");
204  lua_setfield(L, -2, "__metatable");
205  }
206 }
int impl_widget_get(lua_State *L)
#define lua_isnoneornil(L, n)
Definition: lua.h:379
LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
Definition: lapi.cpp:592
LUALIB_API void * luaL_checkudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:345
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:728
#define lua_pushcfunction(L, f)
Definition: lua.h:370
LUA_API void lua_rawseti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:889
Tmust inherit enable_lua_ptr<T>
Definition: lua_ptr.hpp:19
Base class for all widgets.
Definition: widget.hpp:49
#define lua_remove(L, idx)
Definition: lua.h:391
LUA_API int lua_rawget(lua_State *L, int idx)
Definition: lapi.cpp:698
void luaW_pushwidget(lua_State *L, gui2::widget &w)
Definition: lua_widget.cpp:36
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:324
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:385
T * get_ptr()
Definition: lua_ptr.hpp:37
LUA_API int lua_absindex(lua_State *L, int idx)
Definition: lapi.cpp:161
#define lua_pop(L, n)
Definition: lua.h:364
void luaW_getwidgetcallback(lua_State *L, gui2::widget *wg, gui2::window *owner, std::string_view name)
pushed ther callback function onoto the stack [-0, +1, -]
Definition: lua_widget.cpp:163
LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
Definition: lauxlib.cpp:175
static char widgetdataKey[]
Definition: lua_widget.cpp:34
void luaW_callwidgetcallback(lua_State *L, gui2::widget *wg, gui2::window *owner, std::string_view name)
callas a widgets callback [-0, +0, e]
Definition: lua_widget.cpp:175
LUALIB_API void * luaL_testudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:330
LUA_API void lua_pushnil(lua_State *L)
Definition: lapi.cpp:473
void luaW_pushwindowtable(lua_State *L, gui2::window *owner)
[-0, +1, -]
Definition: lua_widget.cpp:82
void register_metatable(lua_State *L)
Definition: lua_widget.cpp:193
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:311
LUA_API void lua_rawset(lua_State *L, int idx)
Definition: lapi.cpp:877
gui2::widget & luaW_checkwidget(lua_State *L, int n)
Definition: lua_widget.cpp:42
static const char widgetKey[]
Definition: lua_widget.cpp:33
#define lua_isfunction(L, n)
Definition: lua.h:372
int w
LUA_API void lua_rotate(lua_State *L, int idx, int n)
Definition: lapi.cpp:217
LUA_API void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.cpp:246
lua_ptr< gui2::widget > & luaW_checkwidget_ptr(lua_State *L, int n)
Definition: lua_widget.cpp:52
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
#define lua_call(L, n, r)
Definition: lua.h:283
#define LUA_REGISTRYINDEX
Definition: lua.h:44
bool luaW_iswidget(lua_State *L, int index)
Definition: lua_widget.cpp:63
static int impl_widget_collect(lua_State *L)
Definition: lua_widget.cpp:184
Standard logging facilities (interface).
static void luaW_pushwidgettablecontainer(lua_State *L)
Definition: lua_widget.cpp:69
void luaW_clearwindowtable(lua_State *L, gui2::window *owner)
[-0, +0, -]
Definition: lua_widget.cpp:104
bool luaW_setwidgetcallback(lua_State *L, gui2::widget *wg, gui2::window *owner, std::string_view name)
returns true if a callback already existed.
Definition: lua_widget.cpp:141
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:65
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:514
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:837
void luaW_pushwidgettable(lua_State *L, gui2::widget *wg, gui2::window *owner)
[-0, +1, -]
Definition: lua_widget.cpp:114