1 module luad.lmodule; 2 3 import luad.state; 4 import luad.stack; 5 import luad.conversions.functions; 6 7 import luad.c.lua : lua_State; 8 9 import std.traits; 10 11 // Internal, but needs to be public 12 extern(C) int openDModule(F)(lua_State* L, F initFunc) 13 { 14 auto lua = new LuaState(L); 15 16 alias ParameterTypeTuple!F Args; 17 18 static assert(Args.length > 0 && Args.length < 3 && 19 is(Args[0] == LuaState), 20 "invalid initFunc signature"); 21 22 Args args; 23 args[0] = lua; 24 25 static if(Args.length == 2) 26 { 27 static assert(is(Args[1] : const(char[])), "second parameter to initFunc must be a const string"); 28 args[1] = getArgument!(F, 1)(L, -1); 29 } 30 31 return callFunction!F(L, initFunc, args); 32 } 33 34 /** 35 * Generate module entry point for use by Lua's $(D require) function. 36 * 37 * Params: 38 * modname = module name. Typically this should be the same as the name of 39 * the shared library containing this module. Only characters in the set 40 * $(D [a-zA-Z_]) are allowed. Underscores are used to denote a submodule. 41 * The module name must be unique for the current executable. 42 * 43 * initFunc = module initialization function. Called when the module is loaded. 44 * Its return value is returned by $(D require) on the Lua side. Its first 45 * parameter must be of type $(DPREF state,LuaState), which is the state of the calling environment. 46 * Optionally, there may be a second parameter implicitly convertible to the type 47 * $(D const(char[])), which is the name of the module to be loaded (useful for submodules). 48 */ 49 // TODO: verify modname 50 template LuaModule(string modname, alias initFunc) 51 { 52 enum LuaModule = "import luad.c.lua : lua_State;" ~ 53 // The first exported C symbol always gets a preceeding 54 // underscore on Windows with DMD/OPTLINK, but Lua 55 // expects "luaopen_*" exactly. 56 "version(Windows) export extern(C) void _luad_" ~ modname ~ "_systemconvdummy() {}" ~ 57 "export extern(C) int luaopen_" ~ modname ~ "(lua_State* L) {" ~ 58 "return openDModule(L, &" ~ __traits(identifier, initFunc) ~ ");" ~ 59 "}"; 60 }