From 559738eb656a1e2e96a380495569d187e56da6b1 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Wed, 18 Aug 2021 13:34:19 +0200
Subject: [PATCH] SCRIPT: Implements the 'export' method for the module

---
 src/Lib/Script/CRTPLuaScriptObject.hh         | 10 ++--
 .../FunctionDeclaration.cc                    |  7 +++
 .../CRTPLuaScriptObject/JobDeclaration.cc     |  8 ++++
 .../CRTPLuaScriptObject/ModuleDeclaration.cc  | 23 ++++++---
 utils/lua/simple.module                       | 48 +++++++++++++++++++
 5 files changed, 87 insertions(+), 9 deletions(-)
 create mode 100644 utils/lua/simple.module

diff --git a/src/Lib/Script/CRTPLuaScriptObject.hh b/src/Lib/Script/CRTPLuaScriptObject.hh
index 623de553..4e0e86f5 100644
--- a/src/Lib/Script/CRTPLuaScriptObject.hh
+++ b/src/Lib/Script/CRTPLuaScriptObject.hh
@@ -227,6 +227,7 @@ script_class (JobDeclaration) {
 
     bool isImported{ false };
     int functionRegisterKey{ -1 };
+    JobIteratorType iterationType{ static_cast<JobIteratorType>(0) }; // Invalid by default
 
 public:
     std::string name{};
@@ -235,6 +236,7 @@ public:
 
     bool isLocalToModule() const noexcept;
     void pushLuaFunction(lua_State *const) const noexcept;
+    void getLuaFunctionFromStack(lua_State *const, const JobIteratorType) noexcept;
 };
 
 // Function declaration
@@ -264,6 +266,7 @@ public:
 
     bool isLocalToModule() const noexcept;
     void pushLuaFunction(lua_State *const) const noexcept;
+    void getLuaFunctionFromStack(lua_State *const) noexcept;
 };
 
 // Module declaration
@@ -304,9 +307,10 @@ script_class (ModuleDeclaration) {
     std::vector<std::string> importNames{};
     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;
+    void validateModule(lua_State *const) const noexcept;
+    int exportFunction(lua_State *const, const int tableIndex, const std::string_view) noexcept;
+    int exportJob(lua_State *const, const int tableIndex, const std::string_view,
+                  const std::string_view) noexcept;
 
 public:
     std::string moduleName{};
diff --git a/src/Lib/Script/CRTPLuaScriptObject/FunctionDeclaration.cc b/src/Lib/Script/CRTPLuaScriptObject/FunctionDeclaration.cc
index bc6c55bf..82afe1da 100644
--- a/src/Lib/Script/CRTPLuaScriptObject/FunctionDeclaration.cc
+++ b/src/Lib/Script/CRTPLuaScriptObject/FunctionDeclaration.cc
@@ -62,3 +62,10 @@ FunctionDeclaration::isLocalToModule() const noexcept
 {
     return parentScript.size() == 0;
 }
+
+void
+FunctionDeclaration::getLuaFunctionFromStack(lua_State *const L) noexcept
+{
+    luaL_checktype(L, -1, LUA_TFUNCTION);
+    functionRegisterKey = luaL_ref(L, LUA_REGISTRYINDEX);
+}
diff --git a/src/Lib/Script/CRTPLuaScriptObject/JobDeclaration.cc b/src/Lib/Script/CRTPLuaScriptObject/JobDeclaration.cc
index 538d1cef..39c676d9 100644
--- a/src/Lib/Script/CRTPLuaScriptObject/JobDeclaration.cc
+++ b/src/Lib/Script/CRTPLuaScriptObject/JobDeclaration.cc
@@ -93,3 +93,11 @@ JobDeclaration::pushLuaFunction(lua_State *const L) const noexcept
 {
     [[maybe_unused]] bool ok = PushFunctionFromRegistry(L, functionRegisterKey);
 }
+
+void
+JobDeclaration::getLuaFunctionFromStack(lua_State *const L, const JobIteratorType itType) noexcept
+{
+    luaL_checktype(L, -1, LUA_TFUNCTION);
+    functionRegisterKey = luaL_ref(L, LUA_REGISTRYINDEX);
+    iterationType       = itType;
+}
diff --git a/src/Lib/Script/CRTPLuaScriptObject/ModuleDeclaration.cc b/src/Lib/Script/CRTPLuaScriptObject/ModuleDeclaration.cc
index de147455..949de9c7 100644
--- a/src/Lib/Script/CRTPLuaScriptObject/ModuleDeclaration.cc
+++ b/src/Lib/Script/CRTPLuaScriptObject/ModuleDeclaration.cc
@@ -63,33 +63,40 @@ ModuleDeclaration::exportMethod(lua_State *const L) noexcept
 
     const lua_Unsigned len = lua_rawlen(L, 2);
     if (len == 2)
-        return self->exportFunction(L, objectName);
+        return self->exportFunction(L, 2, 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);
+        return self->exportJob(L, 2, objectName, jobItTypeStr);
     }
 
     LUA_RETURN_NOTHING(L);
 }
 
 int
-ModuleDeclaration::exportFunction(lua_State *const L, const std::string_view name) noexcept
+ModuleDeclaration::exportFunction(lua_State *const L, const int tableIndex,
+                                  const std::string_view name) noexcept
 {
-    auto *const context = LuaContext::getContext(L);
+    auto *const context             = LuaContext::getContext(L);
+    FunctionDeclaration *const func = context->getFunction(moduleName, name);
     out(context) << "Export function " << moduleName << "::" << name << '\n';
+
+    lua_pushinteger(L, 2);
+    lua_gettable(L, tableIndex);
+    func->getLuaFunctionFromStack(L);
+
     LUA_RETURN_NOTHING(L);
 }
 
 int
-ModuleDeclaration::exportJob(lua_State *const L, const std::string_view name,
+ModuleDeclaration::exportJob(lua_State *const L, const int tableIndex, const std::string_view name,
                              const std::string_view itTypeStr) noexcept
 {
     auto *const context             = LuaContext::getContext(L);
     const JobIteratorType jobItType = getJobIteratorTypeFromString(itTypeStr);
+    JobDeclaration *const job       = context->getJob(moduleName, name);
     if (jobItType != JobIteratorType::Line && jobItType != JobIteratorType::Syllabe) {
         char str[itTypeStr.length() + 1];
         std::memset(str, 0, sizeof(str));
@@ -99,6 +106,10 @@ ModuleDeclaration::exportJob(lua_State *const L, const std::string_view name,
 
     out(context) << "Export job " << moduleName << "::" << name << "{" << itTypeStr << "}\n";
 
+    lua_pushinteger(L, 3);
+    lua_gettable(L, tableIndex);
+    job->getLuaFunctionFromStack(L, jobItType);
+
     LUA_RETURN_NOTHING(L);
 }
 
diff --git a/utils/lua/simple.module b/utils/lua/simple.module
new file mode 100644
index 00000000..2c963d70
--- /dev/null
+++ b/utils/lua/simple.module
@@ -0,0 +1,48 @@
+--- Declaration
+
+local custom_opt = DeclareOption { option1 = false }
+local time_opt   = DeclareOption { preTime = -900, postTime = 300, }
+local color_opt  = DeclareOption { color1 = Vivy:newColor("#314159") }
+
+local module = DeclareModule {
+    name        = "sample-spec",
+    description = "Sample script used for the specification proposition",
+    author      = "Vivy",
+    revision    = "rev-1254",
+    options     = { custom_opt, time_opt, color_opt },
+    functions   = {
+        DeclareFunction { "tripleCopySyl" },
+        DeclareFunction { "printFoo" },
+    },
+    jobs = {
+        DeclareJob { "set_retime", options = { time_opt } },
+        DeclareJob { "demultiply_syllabes" },
+    }
+}
+
+--- Implementation
+
+local tripleCopySyl = module:export { "tripleCopySyl", function (syl)
+    return { syl:copy(), syl:copy(), syl:copy() }
+end }
+
+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  <= Vivy:start()  then line.start  = Vivy:start()  end
+    if line.finish >= Vivy:finish() then line.finish = Vivy:finish() end
+    return line
+end }
+
+module:export { "create_syllabes", SYLLABE, function (opt, syl)
+    local newSyls     = tripleCopySyl(syl)
+    newSyls[1].start  = syl.line.start
+    newSyls[1].finish = syl.start
+    newSyls[3].finish = syl.line.finish
+    newSyls[3].start  = syl.finish
+    return newSyls
+end }
+
+-- vim: ft=lua
-- 
GitLab