Newer
Older
Import / applications / HighwayDash / ports / Framework / Lua.cpp
// Compile with following to build a command line lua interpreter:
//   g++ Lua.cpp -o lua -DTEST | -DPROG
// With my C++ bindings, LuaVM::CallLua(...) requires C++11
//   g++ -std=c++11 Lua.cpp -o lua -DTEST | -DPROG

#include "Lua.h"
#include "LuaBindings.h"
#ifndef STANDALONE
#include <string>
#include "ResourceLoader.h"
#include "Log.h"
#endif

// Do a unity build of all the lua source
#include "lua-5.3.2/src/lapi.c"
#include "lua-5.3.2/src/lauxlib.c"
#include "lua-5.3.2/src/lbaselib.c"
#include "lua-5.3.2/src/lbitlib.c"
#include "lua-5.3.2/src/lcode.c"
#include "lua-5.3.2/src/lcorolib.c"
#include "lua-5.3.2/src/lctype.c"
#include "lua-5.3.2/src/ldblib.c"
#include "lua-5.3.2/src/ldebug.c"
#include "lua-5.3.2/src/ldo.c"
#include "lua-5.3.2/src/ldump.c"
#include "lua-5.3.2/src/lfunc.c"
#include "lua-5.3.2/src/lgc.c"
#include "lua-5.3.2/src/linit.c"
#include "lua-5.3.2/src/liolib.c"
#include "lua-5.3.2/src/llex.c"
#include "lua-5.3.2/src/lmathlib.c"
#include "lua-5.3.2/src/lmem.c"
#include "lua-5.3.2/src/loadlib.c"
#include "lua-5.3.2/src/lobject.c"
#include "lua-5.3.2/src/lopcodes.c"
#include "lua-5.3.2/src/loslib.c"
#include "lua-5.3.2/src/lparser.c"
#include "lua-5.3.2/src/lstate.c"
#include "lua-5.3.2/src/lstring.c"
#include "lua-5.3.2/src/lstrlib.c"
#include "lua-5.3.2/src/ltable.c"
#include "lua-5.3.2/src/ltablib.c"
#include "lua-5.3.2/src/ltm.c"
#include "lua-5.3.2/src/lundump.c"
#include "lua-5.3.2/src/lutf8lib.c"
#include "lua-5.3.2/src/lvm.c"
#include "lua-5.3.2/src/lzio.c"


LuaVM::LuaVM() {
  L = luaL_newstate();
  luaL_openlibs(L);
  lua_newtable(L);
  registerLuaBindings(L);
}


LuaVM::~LuaVM() {
  lua_close(L);
}


void LuaVM::LoadFile(const char* file) {
#ifndef STANDALONE
  std::string fileStr = file; // Dangerous if we capture the raw pointer, so encapsulate the const char* in something safer
  ::LoadFileAsync(file, true, [this, fileStr](Resource* res) {
    if (!res->IsLoaded() || luaL_loadbuffer(L, (const char*)res->data.data(), res->data.size() - 1, fileStr.c_str()) != 0)
      Log(LL_Error, "LUA", "Error loading LUA file %s\n", fileStr.c_str());
    else if (lua_pcall(L, 0, LUA_MULTRET, 0) != 0)
      Log(LL_Error, "LUA", "Error after loading LUA file %s\n", fileStr.c_str());
  });
#else
  if (luaL_loadfile(L, file) != 0) // Alternative way where Lua directly reads the file instead
    printf("Error loading LUA file %s\n", file);
  else if (lua_pcall(L, 0, LUA_MULTRET, 0) != 0)
    printf("Error after loading LUA file %s\n", file);
#endif
}


void LuaVM::Push(void)                     { lua_pushnil(L); }
void LuaVM::Push(bool b)                   { lua_pushboolean(L, b); }
void LuaVM::Push(const char *str)          { lua_pushstring(L, str); }
void LuaVM::Push(std::vector<char> buf)    { lua_pushlstring(L, buf.data(), buf.size()); }
void LuaVM::Push(void *data)               { lua_pushlightuserdata(L, data); }
void LuaVM::Push(double value)             { lua_pushnumber(L, value); }
void LuaVM::Push(int value)                { lua_pushinteger(L, value); }
void LuaVM::Push(lua_CFunction fn)         { lua_pushcclosure(L, fn, 0); }
void LuaVM::PushArgs(int &)                { }




#ifdef PROG
// Builds the lua command line interpreter
#include "lua-5.3.2/src/lua.c"
#endif


#ifdef TEST
// Builds small test program
int main(int argc, char *argv[])
{
  LuaVM lua;
  lua.LoadFile("test.lua");
  lua.CallLua("helloWorld");
  lua.CallLua("args_test", 1, 2.0, "3");
  //lua.CallLua("args_test", "ids>i", 1, 2.0, "3");
  lua.CallLua("args_test", 1, 2.0, "3");
  return 0;
}
#endif