From b8b925e0723271f9b12cf3e7f09bcac51f4c318c Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Wed, 18 Aug 2021 10:48:03 +0200
Subject: [PATCH] [WIP] SCRIPT: Add skeleton for export job and function

---
 CMakeLists.txt                                |  3 +-
 rsc/lua/lib.lua                               |  5 +-
 src/Lib/Script/CRTPLuaScriptObject.hh         | 14 +++++
 .../CRTPLuaScriptObject/ModuleDeclaration.cc  | 61 +++++++++++++++++--
 utils/lua/sample-spec.module                  |  2 +-
 5 files changed, 74 insertions(+), 11 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5ff0730..7c21382b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -126,13 +126,14 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
         -Weverything
 
         # Disable some things because we want C++20 and don't constrol some Qt
-        # generated files...
+        # generated files... Also permit VLA
         -Wno-c++98-compat -Wno-c++98-c++11-c++14-c++17-compat-pedantic
         -Wno-extra-semi-stmt
         -Wno-redundant-parens
         -Wno-padded
         -Wno-global-constructors
         -Wno-exit-time-destructors
+        -Wno-vla-extension
     )
     target_link_libraries(Vivy PRIVATE
         -fopenmp
diff --git a/rsc/lua/lib.lua b/rsc/lua/lib.lua
index b8f400e7..fb3f7efe 100644
--- a/rsc/lua/lib.lua
+++ b/rsc/lua/lib.lua
@@ -25,9 +25,8 @@ function generalize(tbl) for k, v in pairs(tbl) do _G[k] = v end end
 function enum(tbl)
     local length = #tbl
     for i = 1, length do
-        local v      = tbl[i]
-        local newval = v .. "_" .. i
-        tbl[v]       = newval
+        local v = tbl[i]
+        tbl[v]  = v
     end
     setrometatable(tbl, "an enum")
     return tbl
diff --git a/src/Lib/Script/CRTPLuaScriptObject.hh b/src/Lib/Script/CRTPLuaScriptObject.hh
index 1e6f3593..9d189783 100644
--- a/src/Lib/Script/CRTPLuaScriptObject.hh
+++ b/src/Lib/Script/CRTPLuaScriptObject.hh
@@ -33,6 +33,18 @@ namespace Vivy::Script
     }                                                                    \
     ~theClassName() noexcept {}
 
+// The type of the thing that a job iterate over
+enum class JobIteratorType { Line = 1, Syllabe = 2 };
+static inline JobIteratorType
+getJobIteratorTypeFromString(const std::string_view it) noexcept
+{
+    if (it == "LINE")
+        return JobIteratorType::Line;
+    else if (it == "SYLLABE")
+        return JobIteratorType::Syllabe;
+    return static_cast<JobIteratorType>(0); // Invalid!
+}
+
 // CRTP to expose objects to Lua
 template <class Object> class CRTPLuaScriptObject {
 protected:
@@ -286,6 +298,8 @@ script_class (ModuleDeclaration) {
     std::vector<const ModuleDeclaration *> importedModules{};
 
     bool validateModule(lua_State *const) const noexcept;
+    int exportFunction(lua_State *const, const std::string_view) noexcept;
+    int exportJob(lua_State *const, const std::string_view, const std::string_view) noexcept;
 
 public:
     std::string moduleName{};
diff --git a/src/Lib/Script/CRTPLuaScriptObject/ModuleDeclaration.cc b/src/Lib/Script/CRTPLuaScriptObject/ModuleDeclaration.cc
index 04f76add..ba0a4b32 100644
--- a/src/Lib/Script/CRTPLuaScriptObject/ModuleDeclaration.cc
+++ b/src/Lib/Script/CRTPLuaScriptObject/ModuleDeclaration.cc
@@ -2,6 +2,7 @@
 #include "lua.hpp"
 #include <QFileInfo>
 #include <QString>
+#include <cstring>
 
 using namespace Vivy::Script;
 
@@ -40,7 +41,8 @@ ModuleDeclaration::importMethod(lua_State *const L) noexcept
         lua_gettable(L, 2);    // Stack is { top: str, module, str, table, self }
         const std::string_view func         = CHECK_STRING_VIEW(L, 5);
         FunctionDeclaration *const function = context->getFunction(mod, func);
-        function->pushLuaFunction(L);
+        if (function)
+            function->pushLuaFunction(L);
         // Stack is { top: nil | function, FunctionDeclaration, str, module, str, table, self }
     }
 
@@ -48,14 +50,58 @@ ModuleDeclaration::importMethod(lua_State *const L) noexcept
     return 1;
 }
 
+#include <iostream>
+
 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;
+    ModuleDeclaration *const self = CHECK(L, 1);
+    luaL_checktype(L, 2, LUA_TTABLE);
+
+    // Stack will be { top: string, table, self }
+    lua_pushinteger(L, 1);
+    lua_gettable(L, 2);
+    const std::string_view objectName = CHECK_STRING_VIEW(L, -1);
+
+    const lua_Unsigned len = lua_rawlen(L, 2);
+    if (len == 2)
+        return self->exportFunction(L, objectName);
+
+    else if (len == 3) {
+        // Stack will be { top: int, string, table, self }
+        lua_pushinteger(L, 2);
+        lua_gettable(L, 2);
+        const std::string_view jobItTypeStr = CHECK_STRING_VIEW(L, -1);
+        return self->exportJob(L, objectName, jobItTypeStr);
+    }
+
+    LUA_RETURN_NOTHING(L);
+}
+
+int
+ModuleDeclaration::exportFunction(lua_State *const L, const std::string_view name) noexcept
+{
+    auto *const context = LuaContext::getContext(L);
+    out(context) << "Export function " << moduleName << "::" << name << '\n';
+    LUA_RETURN_NOTHING(L);
+}
+
+int
+ModuleDeclaration::exportJob(lua_State *const L, const std::string_view name,
+                             const std::string_view itTypeStr) noexcept
+{
+    auto *const context             = LuaContext::getContext(L);
+    const JobIteratorType jobItType = getJobIteratorTypeFromString(itTypeStr);
+    if (jobItType != JobIteratorType::Line && jobItType != JobIteratorType::Syllabe) {
+        char str[itTypeStr.length() + 1];
+        std::memset(str, 0, sizeof(str));
+        std::strncpy(str, itTypeStr.data(), sizeof(str));
+        luaL_error(L, "The iteration type must be LINE or SYLLABE, got %s", str);
+    }
+
+    out(context) << "Export job " << moduleName << "::" << name << "{" << itTypeStr << "}\n";
+
+    LUA_RETURN_NOTHING(L);
 }
 
 int
@@ -169,6 +215,9 @@ ModuleDeclaration::pushToRuntime(lua_State *const L) noexcept
     else
         context->setFailed("Module " + self->moduleName + " is invalid");
 
+    // TODO: Import needed modules here!
+    const std::string_view importNeededModulesHere = "Import needed modules here!";
+
     LUA_RETURN_NOTHING(L);
 }
 
diff --git a/utils/lua/sample-spec.module b/utils/lua/sample-spec.module
index 74ad9edb..b007d97a 100644
--- a/utils/lua/sample-spec.module
+++ b/utils/lua/sample-spec.module
@@ -37,7 +37,7 @@ module:export { "printFoo", function () prettyPrint ("Bar") end }
 module:export { "retime_lines", LINE, function (opt, line)
     line.start  = line.start + opt.preTime
     line.finish = line.start + opt.postTime
-    if line.start <= 0 then line.start = 0 end
+    if line.start  <= Vivy:start()  then line.start  = Vivy:start()  end
     if line.finish >= Vivy:finish() then line.finish = Vivy:finish() end
     return line
 end }
-- 
GitLab