From 8342cd075d47b2225871dede9b62b1038c277c94 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Mon, 16 Aug 2021 16:50:11 +0200
Subject: [PATCH] [WIP] SCRIPT: Add methods to load and export modules and
 functions

---
 src/Lib/Script/CRTPLuaScriptObject.cc | 46 +++++++++++++++++++++++++++
 src/Lib/Script/CRTPLuaScriptObject.hh | 14 +++++---
 src/Lib/Script/LuaContext.cc          |  1 +
 3 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/src/Lib/Script/CRTPLuaScriptObject.cc b/src/Lib/Script/CRTPLuaScriptObject.cc
index 21cf5f0d..083a7ea5 100644
--- a/src/Lib/Script/CRTPLuaScriptObject.cc
+++ b/src/Lib/Script/CRTPLuaScriptObject.cc
@@ -57,6 +57,52 @@ ModuleDeclaration::resolvModules(LuaContext *const context) noexcept
     return true;
 }
 
+int
+ModuleDeclaration::importMethod(lua_State *const L) noexcept
+{
+    auto *const self    = CHECK(L, 1);
+    auto *const context = LuaContext::getContext(L);
+    luaL_checktype(L, 2, LUA_TTABLE);
+
+    // Get the module name
+    lua_pushinteger(L, 1); // Stack is { top: int, table, self }
+    lua_gettable(L, 2);    // Stack is { top: str, table, self }
+    const std::string_view mod = CHECK_STRING_VIEW(L, 3);
+
+    // Import a module
+    err(context) << "Importing a module...";
+    const ModuleDeclaration *const module = context->getModule(mod);
+    if (module) {
+        err(context) << "Loaded module " << module->moduleName << "\n";
+    } else {
+        err(context) << "Failed to load module " << mod << "\n";
+        return 1;
+    }
+    // Stack is { top: module, str, table, self }
+
+    // Import a function
+    if (lua_rawlen(L, 2) == 2) {
+        lua_pushinteger(L, 2); // Stack is { top: int, module, str, table, self }
+        lua_gettable(L, 2);    // Stack is { top: str, module, str, table, self }
+        const std::string_view func = CHECK_STRING_VIEW(L, 5);
+        err(context) << "Load function " << func << " but not implemented, pushing nil\n";
+        lua_pushnil(L);
+        // Stack is { top: nil | function, str, module, str, table, self }
+    }
+
+    return 1;
+}
+
+int
+ModuleDeclaration::exportMethod(lua_State *const L) noexcept
+{
+    auto *const self              = CHECK(L, 1);
+    auto *const context           = LuaContext::getContext(L);
+    const std::string_view object = CHECK_STRING_VIEW(L, 2);
+    err(context) << "Vivy:export: Not implemented\n";
+    return 0;
+}
+
 int
 ModuleDeclaration::setName(lua_State *const L) noexcept
 {
diff --git a/src/Lib/Script/CRTPLuaScriptObject.hh b/src/Lib/Script/CRTPLuaScriptObject.hh
index c51b8e6a..c0a145f4 100644
--- a/src/Lib/Script/CRTPLuaScriptObject.hh
+++ b/src/Lib/Script/CRTPLuaScriptObject.hh
@@ -10,10 +10,11 @@
 namespace Vivy::Script
 {
 // clang-format off
-#define LUA_DECL_METHOD(class, name)            luaL_Reg{ #name, class ::name   }
-#define LUA_DECL_META_METHOD(class, meta, name) luaL_Reg{ meta,  class ::name   }
-#define LUA_DECL_CREATE(class)                  luaL_Reg{ "new", class ::CREATE }
-#define LUA_RETURN_NOTHING(L)                   { lua_settop(L, 0); return 0; }
+#define LUA_DECL_METHOD(class, name)                luaL_Reg{ #name,  class ::name   }
+#define LUA_DECL_NAMED_METHOD(class, method, name)  luaL_Reg{ method, class ::name   }
+#define LUA_DECL_META_METHOD(class, meta, name)     luaL_Reg{ meta,   class ::name   }
+#define LUA_DECL_CREATE(class)                      luaL_Reg{ "new",  class ::CREATE }
+#define LUA_RETURN_NOTHING(L)                       { lua_settop(L, 0); return 0; }
 // clang-format on
 
 #define script_class(theClassName) \
@@ -233,6 +234,9 @@ script_class (ModuleDeclaration) {
 
     static int pushToRuntime(lua_State *const) noexcept;
 
+    static int importMethod(lua_State *const) noexcept;
+    static int exportMethod(lua_State *const) noexcept;
+
     method_list metaMethods = { luaRegDefaultGC };
     method_list methods     = {
         LUA_DECL_METHOD(ModuleDeclaration, setName),
@@ -245,6 +249,8 @@ script_class (ModuleDeclaration) {
         LUA_DECL_METHOD(ModuleDeclaration, setFunctions),
         LUA_DECL_METHOD(ModuleDeclaration, setJobs),
         LUA_DECL_METHOD(ModuleDeclaration, pushToRuntime),
+        LUA_DECL_NAMED_METHOD(ModuleDeclaration, "import", importMethod),
+        LUA_DECL_NAMED_METHOD(ModuleDeclaration, "export", exportMethod),
         LUA_DECL_CREATE(ModuleDeclaration),
     };
 
diff --git a/src/Lib/Script/LuaContext.cc b/src/Lib/Script/LuaContext.cc
index 9894d59a..3c204739 100644
--- a/src/Lib/Script/LuaContext.cc
+++ b/src/Lib/Script/LuaContext.cc
@@ -168,6 +168,7 @@ LuaContext::getModule(const std::string_view name) const noexcept
         lua_rawgeti(L, LUA_REGISTRYINDEX, r);
         return ModuleDeclaration::CHECK(L, -1);
     } else {
+        lua_pushnil(L);
         return nullptr;
     }
 }
-- 
GitLab