Hi, all!
I try to implement Lua script loader for lua's require() function for it to use Ogre's resource function.
The problem is that script lib I use has a lot of scripts and extensively use require() with lots of subdirectories, so script paths ending up like tests/common/ops.lua which is not compatible with Ogre's resource system which flattens everything out if I add subdirectories to locations or just knows nothing about subdirectories. So the question is how can I make ResourceGroupManager let me open subdirectory paths?
lua script loader Topic is solved
-
slapin
- Bronze Sponsor

- Posts: 250
- Joined: Fri May 23, 2025 5:04 pm
- x 16
lua script loader
-
slapin
- Bronze Sponsor

- Posts: 250
- Joined: Fri May 23, 2025 5:04 pm
- x 16
Re: lua script loader
I found super cool thing now which let me make lua's require work via Ogre's resource system.
Code: Select all
Ogre::ResourceGroupManager::getSingleton().createResourceGroup(
"LuaScripts", false);
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
"./lua-scripts", "FileSystem", "LuaScripts", true,
true);
in OgreBites::ApplicationContext derived class (App) method locateResources()
and I have LuaScripts section in resource.cfg.
The loader function:
Code: Select all
int luaLibraryLoader(lua_State *L)
{
int i;
if (!lua_isstring(L, 1)) {
luaL_error(
L,
"luaLibraryLoader: Expected string for first parameter");
}
std::string libraryFile = lua_tostring(L, 1);
std::cout << libraryFile << std::endl;
// In order to be compatible with the normal Lua file loader,
// translate '.' to the file system seperator character.
// In this case (An ogre resource) '/'
while (libraryFile.find('.') != std::string::npos)
libraryFile.replace(libraryFile.find('.'), 1, "/");
libraryFile += ".lua";
std::cout << libraryFile << std::endl;
Ogre::StringVectorPtr scripts =
Ogre::ResourceGroupManager::getSingleton().listResourceNames(
"LuaScripts", false);
std::vector<Ogre::String> &strings = *scripts;
for (i = 0; i < strings.size(); i++)
std::cout << strings[i] << std::endl;
if (0 && !Ogre::ResourceGroupManager::getSingleton()
.resourceExistsInAnyGroup(libraryFile)) {
// Could not find the file.
std::string errMessage = "\n no file '" + libraryFile +
"' found in Ogre resource archives.";
lua_pushstring(L, errMessage.c_str());
} else {
Ogre::DataStreamList streams =
Ogre::ResourceGroupManager::getSingleton().openResources(
"*.lua", "LuaScripts");
Ogre::DataStreamPtr stream =
Ogre::ResourceGroupManager::getSingleton().openResource(
libraryFile, "LuaScripts");
Ogre::String script = stream->getAsString();
if (luaL_loadbuffer(L, script.c_str(), script.length(),
libraryFile.c_str())) {
luaL_error(
L,
"Error loading library '%s' from resource archive.\n%s",
libraryFile.c_str(), lua_tostring(L, -1));
}
}
return 1;
}
[code]
loader "installer" function:
[code]
static void installLibraryLoader(lua_State *L)
{
// Insert the c++ func 'luaLibraryLoader' into package.loaders.
// Inserted at the start of the table in order to take precedence.
lua_getglobal(L, "table");
lua_getfield(L, -1, "insert");
lua_remove(L, -2); // table
lua_getglobal(L, "package");
lua_getfield(L, -1, "searchers");
lua_remove(L, -2); // package
lua_pushnumber(L, 1); // index where to insert into loaders table
lua_pushcfunction(L, luaLibraryLoader);
if (lua_pcall(L, 3, 0, 0))
Ogre::LogManager::getSingleton().stream() << lua_tostring(L, 1);
}
Lua init code:
Code: Select all
installLibraryLoader(L);
lua_pop(L, 1);
after base libs and it works perfectly well.
All the struggle was mainly for stuff like https://github.com/astrochili/narrator which help a lot with dialogue systems.
To make it work the following init sequence was necessary:
Code: Select all
luaopen_base(L);
luaopen_table(L);
luaopen_package(L);
luaL_requiref(L, "table", luaopen_table, 1);
lua_pop(L, 1);
luaL_requiref(L, "math", luaopen_math, 1);
lua_pop(L, 1);
luaL_requiref(L, "package", luaopen_package, 1);
lua_pop(L, 1);
luaL_requiref(L, "string", luaopen_string, 1);
lua_pop(L, 1);
luaL_requiref(L, "io", luaopen_io, 1);
lua_pop(L, 1);
luaL_requiref(L, "lpeg", luaopen_lpeg, 1); // just compile source with lua and extern "C" the function
lua_pop(L, 1);
installLibraryLoader(L);
lua_pop(L, 1);
To write working code I was heavily digging https://github.com/merlinblack/Game-Eng ... source.cpp.