In the embeded lua environment (World of Warcraft - WoW) is missing the require
function.
I want port one existing lua source code (an great OO-library) for the use it in the WoW. The library itself is relatively small (approx 8 small files) but of course it heavily uses the require
.
World of Warcraft loads files and libraries by defining it in an XML file, like:
<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/">
<Script file="LibOne.lua"/>
<Script file="LibTwo.lua"/>
</Ui>
but i don't know how the low level library manipulation is done in the WoW.
AFAIK in the WoW is missing even the package.
table too. :(
So the question(s): For me, the streamlined way would be write an function which will emulate the require
function using the interface available in WoW. The question is how. Could someone give me some directions?
Or as alternative, for the porting the mentioned existing source to WoW, I need replace the require Some.Other.Module
lines in the lua sources to something what WoW will understand. What is the equivalent/replacement for such require Some.Module
in the WoW?
How the WoW handles modules/libraries at low-level?
Lua offers a higher-level function to load and run libraries, called require . Roughly, require does the same job as dofile , but with two important differences. First, require searches for the file in a path; second, require controls whether a file has already been run to avoid duplicating the work.
To encapsulate data and functions, Lua uses modules. A Lua module is a regular Lua table that is used to contain functions and data. The table is declared local not to pollute the global scope: local M = {} -- private local message = "Hello world!" function M.
You could merge all files into one using one of the various amalgamation scripts, e.g. amalg
. Then you can load this file and a stub that implements the require
function using the usual WoW way:
<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/">
<Script file="RequireStub.lua"/>
<Script file="AllModules.lua"/><!-- amalgamated Lua modules -->
<Script file="YourCode.lua"/>
</Ui>
The file RequireStub.lua
could look like:
package = {}
local preload, loaded = {}, {
string = string,
debug = debug,
package = package,
_G = _G,
io = io,
os = os,
table = table,
math = math,
coroutine = coroutine,
}
package.preload, package.loaded = preload, loaded
function require( mod )
if not loaded[ mod ] then
local f = preload[ mod ]
if f == nil then
error( "module '"..mod..[[' not found:
no field package.preload[']]..mod.."']", 1 )
end
local v = f( mod )
if v ~= nil then
loaded[ mod ] = v
elseif loaded[ mod ] == nil then
loaded[ mod ] = true
end
end
return loaded[ mod ]
end
This should emulate enough of the package
library to get you a working require
that loads modules in the amalgamated file. Different amalgamation scripts might need different bits from package
, though, so you probably will have to take a look at the generated Lua source code.
And in the specific case of Coat
you might need to implement stubs for other Lua functions as well. E.g. I've seen that Coat
uses the debug
library ...
WoW environment doesn't have dofile
or any other means to read external files at all. You need to explicitly mention all files that must be loaded in .toc
file or .xml
referenced from .toc
.
You can then write your own implementation of require
to maintain compatibility with your library, which would be quite trivial as it would only need to parse module name and retrieve it's content from modules.loaded
table, but you'd still need to alter original source to make files register in that table and you'll need to manually arrange all files into correct order of loading.
Alternatively you can rearrange files into separate WoW-addons and use its own built-in Dependencies
/OptionalDeps
facilities or popular LibStub
framework to handle loading order automatically.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With