Using 'require' to include Lua modules

BECOME PART OF THE COMMUNITY - Sign up here
  • Hi,

    So what's the proper way to use Lua modules?

    I want to use the 'require' keyword with relative path, but I got 2 issues with it.


    1) it seems to look for file only under :
    /Users/[user]/MALightingTechnology/gma3_1.8.1/shared/resource/lib_plugins/requirements

    I tried to workaround this by adding a symbolic link under 'requirements' to a folder of my choice.

    2) ReloadPlugins does not reload file from that path, even if I add the required file as an installed LuaComponent. Because the file (module) was already "required" so it is not loaded again.


    * Is there a way to edit the search path?
    * Is there another way without using "require"?

  • I found a way !

    after finding this post:
    https://www.reddit.com/.../how_to_force_reload_all.../

    A simple example would be:

    say I have a plugin myPlugin.lua, that want to use a module comp2.lua

    - I add myPlugin.lua as component 1 of the plugin.
    - I add comp2.lua as component 2 of the plugin
    - I set both to be "Installed"

    In myPLugin.lua I do:
    ---------------------
    package.loaded["comp2"] = nil
    local comp2 = require "comp2"
    ---------------------

    That's it. now "RealodPlugins" will work, and reload comp2 if it changes.
    This is a "brutal-force" way, in which we loose loaded module caching. but its good enough.

    The better way would be to have a separate "MyReloadPlugin.lua" that will do the "package.loaded["comp2"] = nil", and is used only in Development time.

  • Here is the full code I am using to allow requiring modules that reside under:

    MALightingTechnology/gma3_library/datapools/plugins

    - Does anyone see any potential issues with using LUA's require module, from this folder?
    - Why doesn't MA3 already include this folder in the package.path ? Is this a bug, or there is a good reason?

  • I agree that the user plugin path very well could be included in package.path as default.

    check out the API function GetPath to simplify your script.
    - these few lines seems to do the job for me:

    Code
    local userplugins = GetPath('plugins')
    if not package.path:find(userplugins) then
      package.path = package.path .. ';' .. userplugins .. '/?.lua'  
    end
  • Now this is reviving an old post. But I have not found any better answers as I have been looking to do what Hepi was after. And your package.path solution looks very well done. I have not given it a try. But I was wanting to create a module to basically bring me back the path to either plugins on USB folder or Internal on my computer folder. and then pass the findings back into the script. This is for Mac by the way. Since my eyesight is not what it used to be and I can make the text larger in VSStudio Code is why I am after this. So in creating a plugin there is a lot of trial and error. Since the plugin section is not very friendly to quickly make changes to it on MA3. I want to create a path to a folder that has my plugins that I am creating with VSCode, brings it back as if it is sitting in the plugins folder on the software and run it. So with this topic and Andreas reply on the GetPath. I have been able to make a function to bring me back the path to the folder.

     Cmd("Select Drive 2")
        SP_Folder = tostring(GetPath("plugins", true))
        return SP_Folder

    which brings me back the path all the way to the plugins folder on my USB drive. If I select Drive 1 it will bring back the path all the way to the plugins folder on my Mac. Which I would like to be able to select a folder of my choosing but I am already deep in this can of worms. But in creating a module with the code above in it too return the answer of the path where my plugin is. Along with some more coding to return a name of the file that I want to run in .lua format. which i would take SP_Folder..name.lua. In typing this I am confusing myself. I trigger from a macro line (which the macro name is Test) Lua "Trigger()" , which then triggers a function in a plugin. that requires the name of the macro and the path to where it lives. So with the code above and getting the name Test adding .lua behind it. Inside the folder is Test.lua and proceeds to execute. Now mind you this is only because I cannot stand the interface on MA3, I might have when my eyesight was 20/20. But in the end of creating a working plugin. Its as simple as right clicking on an empty plugin, adding a lua component, edit and paste into the interface, save, close and have the plugin on my computer then just export it and there it is as Text.xml. That is a long ways to get too the xml I know. But say i have Plugin 1 thru Plugin 10 that I am working on, as the name of the macros with the line Lua"Trigger()". runs Trigger Plugin which first thing requires for the path and file name in a module that its only purpose in life is to return what is asked of it. Then takes that info and runs the plugin inside of MA3. Not even sure I make sense of this myself, I just see it in my head. I have tried to require Test in another plugin with errors. Not getting the component 1 and 2. Do i put get names in component 1 or require it from comp 2. Should I have install set to yes.

  • I have seen your other thread on this topic and it is really hard to make any sense of your approach to solve your problem


    Unless I have totally misunderstood the essence of your workflow-issue, try this small plugin:

    Plugin "Create or update Plugins" (not tested on mac)

  • I had seen the ../../../ in the forums somewhere before. But I know that doesnt work on the mac. I did however get this to work to find the main directory on USB.


    local E=Echo

    SP_RunPlugin=function()
    local f_getdrivemac=function()
    Cmd("Select Drive 2")
    SP_Folder = tostring(GetPath("plugins", true))
    return SP_Folder
    end
    local f_getFileName = function()
    local i_macro = GetFocus().OBJECTINDEX
    local o_macro = ObjectList('Macro '..i_macro)[1]
    local s_macroName = o_macro.NAME or ''
    return s_macroName
    end
    if HostOS() == "Mac" then
    s_path = f_getdrivemac()
    end
    if not s_file then
    SP_Filename = f_getFileName()
    end
    E("The Path is: "..s_path.."/"..SP_Filename)
    end

    Funny thing is I tried to post the code above copied from VSCode and it was definitely bigger. So I copied from MA3. Dont mind the 'if not s_file', it still works I had earlier tried to get the string of the file and wound up not changing that one. So basically if I could take the chunk that realized i'm on a mac. Then it gets the path to the USB directory for plugins. And put that into a require script. Have it return that path always to the plugin. I can take the other part of the chunk in to the plugin that gets the name I would be working on because it's name would be the name of the file.lua i am working on in VSCode.

    So my workflow is a Macro named the name of the plugin that i am working on in VSCode. where it has the .lua file

    line 1 of the macro is Lua "SP_RunPlugin" SP stands for speedy. which as you see triggers the plugin where SP_RunPlugin = function()

    Here is where I need the path to the folder that has the .lua file. which I am keeping in its place on the USB.

    after getting the path. I get the name of the macro. then concat them together.

    Redirect to the USB disk to run and not inside of the MA3 software. But as we come up with stupid ideas for plugins we can wind up with a lot of them. And I can make the text size 20 on MA3 but VSCode is just easier to read. If I have a .lua file that has the code to determine the path. I just need the macro with the name of the plugin that always triggers one plugin to reach into the USB and run that named plugin. Until the day when I can call it complete and create the .xml by exporting it and loading it in. As a note if you change the "Select Drive 1" in the beginning, on a Mac it will return the path inside of the Mac HD to where the plugin folder is. But relative path with '.'s and '/'s i cannot seem to manipulate folder hierarchy. Hopefully the method to my madness has made some sense.

  • I am not getting Hepi's component1 and component2 to work as described. But to describe what i have so far.

    Macro named "testies" with macroline: Lua "SP_RunPlugin3()"

    it triggers a plugin named "SP_Run3" who's code is:

    local E = Echo
    usbPath = true
    local SF = string.format
    SP_RunPlugin3 = function()
     package.loaded["drivePath"] = nil
     local drivePath = require"drivePath"
     Cmd('Lua "SP_RUNFilePath()"')

     local f_getFileName = function()
       local i_macro = GetFocus().OBJECTINDEX
       local o_macro = ObjectList('Macro '..i_macro)[1]
       local s_macroName = o_macro.NAME or ''
       usbPath = false
       return s_macroName
     end
    if usbPath then 
        SP_Filename = f_getFileName()
    end
    s_filePath = SF('%s/%s.lua', SP_Folder, SP_Filename)
    E(s_filePath)
    -- E("The Filepath and filename concat is: "..SP_Folder.."/"..SP_Filename)
    LuaFile(s_filePath) 
    end

    Now i tried to put drivePath on line 2 of the plugins lua coponents. But was doing something all wrong. Kept getting couldn't load error. So in a folder on my HD(on a Mac). Cannot remember how I located this folder but it is: /Users/speedy/MALightingTechnology/gma3_1.9.7/shared/resource/lib_plugins/requirements

    i placed the lua file named drivePath.lua which has code of:

    SP_RUNFilePath = function()
       Echo("This is coming from require script")
       local f_getdrivemac=function()
         Cmd("Select Drive 2")
         SP_Folder = tostring(GetPath("plugins", true))
        return SP_Folder
     end
      if HostOS() == "Mac" then
       SP_Folder = f_getdrivemac()
       Echo(SP_Folder)
     end 
    return SP_Folder
    end

    In my folder where the path that is in the screenshot is a luafile named "testies.lua" that has the code of:

    return function()

    Printf("testing the testies")

    end

    But as you see in the screen shot I am getting attempt to call a nil value (global 'LuaFile'). But I know s_filePath is not nil. I have tried as doc says to do the example. LuaFile("s_filePath") but it keeps saying nil value.

  • I don't define the LuaFile. I thought that LuaFile was a command to run a LuaFile. Which is right where the other code has deciphered it to be. /Volumes/Showz/grandMA3/gma3_library/datapools/plugins/testies.lua which only has return function(); Printf("Testing the Testies file") ; end in it. on different lines.

    Syntax

    LuaFile ["AbsolutePathToLuaFile/FileName.lua"] is what i see in the manual. and I tried LuaFile(s_filepath) and LuaFile("s_filepath") where you see above with StringFormat puts the path and the lua file into the one variable s_filepath.

    I have been in class all week and coming back makes me realize i have to get better at commenting my code.

  • the manual describes LuaFile as a commandline keyword, not as a Lua API function

    LuaFile is just a variant of the commandline keyword Lua, to execute raw Lua:

    Lua "Echo('Hello World!')"

    LuaFile "c:/hello.lua"


    Be aware of the difference of raw lua, and a lua plugin component definition:

    hello.lua file content requirements for being executable with the LoadfFile commandline keyword:

    Echo('Hello World!')

    hello.lua file content requirements for being loadable as a plugin component

    return function() Echo('Hello World!') end

  • regarding the original topic of this hijacked thread:

    to allow requiring modules that reside under:

    MALightingTechnology/gma3_library/datapools/plugins

    - Does anyone see any potential issues with using LUA's require module, from this folder?
    - Why doesn't MA3 already include this folder in the package.path ?

    with the latest release v2.0, this is included..

  • Quote

    /Volumes/Showz/grandMA3/gma3_library/datapools/plugins/testies.lua which only has return function(); Printf("Testing the Testies file") ; end in it.

    I believe that satisfies the raw lua part you suggested above. And there were no other threads about modules that came close as this one to trying to handle one that always loads and runs. It needed revamped. And this is running in vs 2.0.0 with same results.

  • I believe that satisfies the raw lua part you suggested above

    what I was trying to point out is that If you paste the two lua statements below into commandline, only the second will actually print something:

    Lua "return function(); Printf('Testing the Testies file') ; end"

    Lua "Printf('Testing the Testies file')"

    the first statement returns a function definition, there is no mechanism that actually runs the function

    same apply if your replace Lua with LuaFile and the quoted text with a filepath

    as your testies.lua doesn't print anything. but merely defines a function that prints something, nothing will happen when passing its path to the LuaFile keyword.

  • I really love it when you describe what is wrong and don't throw an example to an answer. When I create a plugin that has what I have above it prints on both the command line history and system monitor. So the plugin works

  • unless you have already found your solution, here's how it could be done:

    Workflow: copy this plugin to a new pool-slot and give it the name of the external lua-file you want to run.

    Display Spoiler

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!