Skip to content

quinsmpang/Lux

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

81 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lux is an emitting C++ glue for Lua. By 'emitting' I mean that it exploits a
C++ feature in which the compiler emits functions at compile time. This happens
whenever a templated function recieves a new argument type. Using this feature,
as well as some C++11 additions, Lux manages to greatly simplify the task of
exporting C functions, structures, unions, arrays, and C++ classes to the Lua
language. It is so simple that the user need only learn one thing to perform the
most basic task of exporting any C function.

	lua_register(state, "AnyFunction", lux_cast(AnyFunction));

The lux_cast macro returns a lua_CFunction which is a wrapper for any arbitrary
C function or C++ class function. 

	#define lux_cast(fun) [](lua_State *L) { return lux_thunk(L, &fun); }

The above lux_thunk is a dispatching routine responsible for converting the Lua
stack values to the correct arguments for "fun" and pushing its return value,
if any. This way lux_cast(fun) has the type lua_CFunction and can be used any
place in Lua's C API that asks for it. For example, you can pass it as the
CFunction in a luaL_Reg entry before a call to luaL_setfuncs. The lux_thunk
function can also take C++ class functions provided that they've been specified.

template <> luaL_Reg lux_Class<AnyClass>::regs[] = 
	{
	{"SomeMethod", lux_cast(AnyClass::SomeMethod)},
	// more...
	{nullptr}
	};

And then, sometime after having created a Lua state (and for each state).

	luaL_registerf(state, "AnyClass", lux_Class<AnyClass>::open, true);

Aside from classes, Lux can also give Lua access to C style arrays and will
allow for dealing with memory blocks in a similar way as structs and unions.
See the test files for examples of how these are used.

Lux was designed to be minimalist and non intrusive. This means that you should
not have to modify any of your existing C/C++ code in order to give it to the
state machine. You do not need to write any "wrapper" functions to manipulate
the stack for C function calls (a lengthy process). Nor do you need to run an
external program that will parse your sources (an error prone process) to
generate extra sources files for your build (a cumbersome process). Everything
normally done by the user to export their native code is instead done by the
compiler itself when the C++ source code is processed.

Effectively, you don't have to maintain or manually edit the code for interface
changes. The C++ compiler already does this. That is to say, when you change
the arity (number of arguments) to AnyFunction or AnyClass::SomeMethod or you
simply change the type of one or more of its arguments, you don't have to
change the specifications, because they don't involve such details. All changes
are reflected in the Lua interface when the C++ compiler fills out the template
specifications the next time you build your code.

The name Lux was chosen from the word of the same spelling. It is the SI unit
of illuminance, equal to one lumen per square metre. It is the units in which
the luminance of the moon is measured, and thus to Lua. 

About

An emitting C++ glue for Lua

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 97.9%
  • Lua 1.7%
  • Makefile 0.4%