Newer
Older
Import / applications / HighwayDash / ports / Framework / Lua.h
//  BlockyFroggy
//  Copyright © 2017 John Ryland.
//  All rights reserved.
#pragma once
#ifndef LUA_VM_H
#define LUA_VM_H


struct lua_State;


// Details needed for CallLua impl
#include "lua-5.3.2/src/lua.h"
#include "lua-5.3.2/src/lauxlib.h"
#include <vector>
#include "Log.h"


class LuaVM
{
public:
  LuaVM();
  ~LuaVM();
  void loadFile(const char* file);

  // Unfortunately because this is a template some of the implementation is bleeding out in to the header/interface
  template <typename... Ts>
  void callLua(const char *func, const Ts... values) {
    lua_getglobal(L, func);  /* get function */
    int argc = 0;
    int retc = 0; /* number of expected results */
    pushArgs(argc, values...);
    if (lua_pcall(L, argc, retc, 0) != 0)  /* do the call */
      LogTag(LL_Error, "LUA", "error running function `%s': %s", func, lua_tostring(L, -1));
    //! @todo retrieve results
  }

  void bindCFunction(const char* name, lua_CFunction fn) {
    lua_pushcclosure(L, fn, 0);
    lua_setglobal(L, name);
  }

private:
  lua_State* L;

  // Helpers
  void push(void);
  void push(bool b);
  void push(const char *str);
  void push(std::vector<char> buf);
  void push(void *data);
  void push(double value);
  void push(int value);
  void push(lua_CFunction fn);
  void pushArgs(int &argc);
  template <typename T, typename... Ts>
  void pushArgs(int &argc, const T value, const Ts... values) {
    argc++;
    push(value);
    pushArgs(argc, values...);
  }
};


#endif // LUA_VM_H