Registering Types

All fundamental types are represented (including a custom LuaAPI::Nil type) through overloaded functions. Custom types are supported by first registering the type and then the functions of that type you wish to use, exposing them to Lua.

Registering a Custom Type
class CType {
	public :
    void Output() {
      std::cout << "CType: " << mI << std::endl;
    }
	
	public :
		int mI = 0;
};

luaAPI.RegisterType<CType>("uair.ctype");
luaAPI.RegisterConstructor<CType>();
luaAPI.RegisterFunction<CType, void>("output", &CType::Output);
luaAPI.RegisterGetter<CType, int>("geti", &CType::mI);
luaAPI.RegisterSetter<CType, int>("seti", &CType::mI);

After registering our custom type and whitelisting it to be available in Lua ("uair.ctype") our type can now be passed to Lua, created and manipulated in Lua, and passed back from Lua to our program.

Using a Custom Type
try {
  CType c; c.mI = 4;

  std::string scr = R"(
    local c = ...
    c:seti(6)
    c:output()

    local c2 = uair.ctype()
    c2:seti(3)
    return c2
  )";

  CType c2 = luaAPI.CallString<CType>(scr, c);
  c2.Output();
} catch (std::exception& e) {
  std::cout << e.what() << std::endl;
}

If the custom type that you're registering doesn't allow default construction or has some other special restriction then it might be necessary to manually define the PushStack and ReadStack overloads to properly handle your type.

Custom Push/Read for non-default Special Type
class SType {
	public :
    // no default constructor available
		SType(const int& i) : mI(i) {
			
		}

    void Output() {
      std::cout << "SType: " << mI << std::endl;
    }
	
	public :
		int mI = 0;
};

template <>
void LuaAPI::PushStack<SType>(SType value) {
  typedef UserDataWrapper<SType> WrappedType;
  
  void* userdata = lua_newuserdata(mState,
      sizeof(WrappedType*));
  WrappedType** data = static_cast<WrappedType**>(userdata);
  *data = new WrappedType();
  
  (*data)->mUserData = new SType(0);
  *((*data)->mUserData) = value;
  (*data)->mShouldDelete = true;
  
  lua_setmetatable(mState, -2);
}

template <>
SType LuaAPI::ReadStack(const int& index) {
  typedef UserDataWrapper<SType> WrappedType;
  
  SType result(0);
  WrappedType** data = static_cast<WrappedType**>(userdata);
  result = *((*data)->mUserData);
  return result;
}