Path.cc
1 /*
2  * MoMEMta: a modular implementation of the Matrix Element Method
3  * Copyright (C) 2016 Universite catholique de Louvain (UCL), Belgium
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 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <lua/bindings/Path.h>
20 
21 #include <momemta/ILuaCallback.h>
22 
23 #include <lua/bindings/Types.h>
24 #include <ExecutionPath.h>
25 
26 #include <lua.hpp>
27 
28 void lua::path_register(lua_State* L, void* ptr) {
29 
30  // Register metatable for type Path
31  push_type_metatable(L, LUA_PATH_TYPE_NAME);
32 
33  // Register destructor
34  static const luaL_Reg functions[] = {
35  {"__gc", path_free},
36  {nullptr, nullptr}
37  };
38  luaL_setfuncs(L, functions, 0);
39 
40  lua_pop(L, 1);
41 
42  // Register global `Path` function, acting as a constructor for `ExecutionPath` struct
43  lua_pushlightuserdata(L, ptr);
44  lua_pushcclosure(L, path_new, 1);
45  lua_setglobal(L, LUA_PATH_TYPE_NAME);
46 }
47 
48 int lua::path_new(lua_State* L) {
49 
50  int n = lua_gettop(L);
51  if (n == 0) {
52  luaL_error(L, "invalid number of arguments: at least 1 expected, got 0");
53  }
54 
55  std::vector<std::string> module_names;
56  for (size_t i = 1; i <= (size_t) n; i++) {
57  std::string module_name = luaL_checkstring(L, i);
58  module_names.push_back(module_name);
59  }
60 
61  ExecutionPath** pPath = static_cast<ExecutionPath**>(lua_newuserdata(L, sizeof(ExecutionPath)));
62  *pPath = new ExecutionPath();
63 
64  luaL_getmetatable(L, LUA_PATH_TYPE_NAME);
65  lua_setmetatable(L, -2);
66 
67  (*pPath)->elements = module_names;
68 
69 
70  void* cfg_ptr = lua_touserdata(L, lua_upvalueindex(1));
71  ILuaCallback* callback = static_cast<ILuaCallback*>(cfg_ptr);
72  callback->onNewPath(**pPath);
73 
74  return 1;
75 }
76 
77 int lua::path_free(lua_State* L) {
78  delete *static_cast<ExecutionPath**>(luaL_checkudata(L, 1, LUA_PATH_TYPE_NAME));
79 
80  return 0;
81 }
82 
83 ExecutionPath* lua::path_get(lua_State* L, int index) {
84  luaL_checktype(L, index, LUA_TUSERDATA);
85  ExecutionPath** path = static_cast<ExecutionPath**>(luaL_checkudata(L, index, LUA_PATH_TYPE_NAME));
86  if (!path) {
87  const char *msg = lua_pushfstring(L, "%s expected, got %s",
88  LUA_PATH_TYPE_NAME, luaL_typename(L, index));
89  luaL_argerror(L, index, msg);
90  }
91 
92  return *path;
93 }
int path_free(lua_State *L)
Free an instance of Path.
Definition: Path.cc:77
Notification callback used for communication between the lua file and MoMEMta.
Definition: ILuaCallback.h:30
int path_new(lua_State *L)
Create a new instance of Path.
Definition: Path.cc:48
Lua binding of C++ Path class.
ExecutionPath * path_get(lua_State *L, int index)
Retrieve an instance of Path from the lua stack.
Definition: Path.cc:83
void push_type_metatable(lua_State *L, const char *name)
Push a new metatable on the stack.
Definition: Types.cc:26
Generic functions to deal with custom lua types.
virtual void onNewPath(const ExecutionPath &path)=0
A new path is declared in the configuration file.
void path_register(lua_State *L, void *ptr)
Register Path into lua runtime.
Definition: Path.cc:28