Freeciv21
Develop your civilization from humble roots to a global empire
api_game_specenum.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  __ __ part of Freeciv21. Freeciv21 is free software: you can
4 / \\..// \ redistribute it and/or modify it under the terms of the GNU
5  ( oo ) General Public License as published by the Free Software
6  \__/ Foundation, either version 3 of the License, or (at your
7  option) any later version. You should have received
8  a copy of the GNU General Public License along with Freeciv21. If not,
9  see https://www.gnu.org/licenses/.
10  */
11 
12 #include <cstring>
13 
14 /* dependencies/lua */
15 extern "C" {
16 #include "lauxlib.h"
17 #include "lua.h"
18 #include "lualib.h"
19 }
20 
21 // utility
22 #include "log.h"
23 #include "support.h"
24 
25 // common
26 #include "events.h"
27 
28 #include "api_game_specenum.h"
29 
30 #define API_SPECENUM_INDEX_NAME(type) api_specenum_##type##_index
31 #define API_SPECENUM_CREATE_TABLE(L, type, name) \
32  api_specenum_create_table((L), (name), API_SPECENUM_INDEX_NAME(type))
33 
40 #define API_SPECENUM_DEFINE_INDEX(type_name, prefix) \
41  static int(API_SPECENUM_INDEX_NAME(type_name))(lua_State * L) \
42  { \
43  static char _buf[128]; \
44  const char *_key; \
45  enum type_name _value; \
46  luaL_checktype(L, 1, LUA_TTABLE); \
47  _key = luaL_checkstring(L, 2); \
48  fc_snprintf(_buf, sizeof(_buf), prefix "%s", _key); \
49  _value = type_name##_by_name(_buf, strcmp); \
50  if (_value != type_name##_invalid()) { \
51  /* T[_key] = _value */ \
52  lua_pushstring(L, _key); \
53  lua_pushinteger(L, _value); \
54  lua_rawset(L, 1); \
55  lua_pushinteger(L, _value); \
56  } else { \
57  lua_pushnil(L); \
58  } \
59  return 1; \
60  }
61 
65 static void api_specenum_create_table(lua_State *L, const char *name,
66  lua_CFunction findex)
67 {
68  /* Insert a module table in the global environment,
69  * or reuse any preexisting table */
70  lua_getglobal(L, name);
71  if (lua_isnil(L, -1)) {
72  lua_newtable(L);
73  lua_pushvalue(L, -1);
74  lua_setglobal(L, name);
75  }
76  fc_assert_ret(lua_istable(L, -1));
77  // Create a metatable
78  lua_newtable(L); // stack: module mt
79  lua_pushliteral(L, "__index");
80  lua_pushcfunction(L, findex); // stack: module mt '__index' index
81  lua_rawset(L, -3); // stack: module mt
82  lua_setmetatable(L, -2); // stack: module
83  lua_pop(L, 1);
84 }
85 
89 API_SPECENUM_DEFINE_INDEX(event_type, "E_")
90 
91 
94 int api_specenum_open(lua_State *L)
95 {
96  API_SPECENUM_CREATE_TABLE(L, event_type, "E");
97  return 0;
98 }
#define API_SPECENUM_CREATE_TABLE(L, type, name)
static void api_specenum_create_table(lua_State *L, const char *name, lua_CFunction findex)
Create a module table and set the member lookup function.
#define API_SPECENUM_DEFINE_INDEX(type_name, prefix)
Define a the __index (table, key) -> value metamethod Return the enum value whose name is the concate...
int api_specenum_open(lua_State *L)
Define the __index function for each exported specenum type.
const char * name
Definition: inputfile.cpp:118
#define fc_assert_ret(condition)
Definition: log.h:112