1. Bart van Strien
  2. love-experiments

Commits

Bart van Strien  committed 35aede2

Start dynamically resolving love modules at runtime, currently probably only works on linux, but at least it runs again.
Hopefully I'll be able to add some more stuff later on to actually register types and such with love later as well, then
we need to make sure we can have an entrypoint, then we need to make it work on other OSes as well.

  • Participants
  • Parent commits 03fa7db
  • Branches runtimemoduledetection

Comments (0)

Files changed (2)

File src/modules/love/love.cpp

View file
  • Ignore whitespace
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
+// STL
+#include <map>
+#include <string>
+
+// SDL
+#include <SDL_loadso.h>
+
 // LOVE
 #include "common/config.h"
 #include "common/version.h"
 // Scripts
 #include "scripts/boot.lua.h"
 
-// All modules define a c-accessible luaopen
-// so let's make use of those, instead
-// of addressing implementations directly.
-extern "C"
+static std::map<std::string, lua_CFunction> modules;
+extern "C" void registerModule(const char *name, void *f)
 {
-#if defined(LOVE_ENABLE_AUDIO)
-	extern int luaopen_love_audio(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_EVENT)
-	extern int luaopen_love_event(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_FILESYSTEM)
-	extern int luaopen_love_filesystem(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_FONT)
-	extern int luaopen_love_font(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_GRAPHICS)
-	extern int luaopen_love_graphics(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_IMAGE)
-	extern int luaopen_love_image(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_JOYSTICK)
-	extern int luaopen_love_joystick(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_KEYBOARD)
-	extern int luaopen_love_keyboard(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_MATH)
-	extern int luaopen_love_math(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_MOUSE)
-	extern int luaopen_love_mouse(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_PHYSICS)
-	extern int luaopen_love_physics(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_SOUND)
-	extern int luaopen_love_sound(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_SYSTEM)
-	extern int luaopen_love_system(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_TIMER)
-	extern int luaopen_love_timer(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_THREAD)
-	extern int luaopen_love_thread(lua_State*);
-#endif
-#if defined(LOVE_ENABLE_WINDOW)
-	extern int luaopen_love_window(lua_State*);
-#endif
-	extern int luaopen_love_boot(lua_State*);
+	modules[name] = (lua_CFunction) f;
 }
 
-static const luaL_Reg modules[] = {
-#if defined(LOVE_ENABLE_AUDIO)
-	{ "love.audio", luaopen_love_audio },
-#endif
-#if defined(LOVE_ENABLE_EVENT)
-	{ "love.event", luaopen_love_event },
-#endif
-#if defined(LOVE_ENABLE_FILESYSTEM)
-	{ "love.filesystem", luaopen_love_filesystem },
-#endif
-#if defined(LOVE_ENABLE_FONT)
-	{ "love.font", luaopen_love_font },
-#endif
-#if defined(LOVE_ENABLE_GRAPHICS)
-	{ "love.graphics", luaopen_love_graphics },
-#endif
-#if defined(LOVE_ENABLE_IMAGE)
-	{ "love.image", luaopen_love_image },
-#endif
-#if defined(LOVE_ENABLE_JOYSTICK)
-	{ "love.joystick", luaopen_love_joystick },
-#endif
-#if defined(LOVE_ENABLE_KEYBOARD)
-	{ "love.keyboard", luaopen_love_keyboard },
-#endif
-#if defined(LOVE_ENABLE_MATH)
-	{ "love.math", luaopen_love_math },
-#endif
-#if defined(LOVE_ENABLE_MOUSE)
-	{ "love.mouse", luaopen_love_mouse },
-#endif
-#if defined(LOVE_ENABLE_PHYSICS)
-	{ "love.physics", luaopen_love_physics },
-#endif
-#if defined(LOVE_ENABLE_SOUND)
-	{ "love.sound", luaopen_love_sound },
-#endif
-#if defined(LOVE_ENABLE_SYSTEM)
-	{ "love.system", luaopen_love_system },
-#endif
-#if defined(LOVE_ENABLE_TIMER)
-	{ "love.timer", luaopen_love_timer },
-#endif
-#if defined(LOVE_ENABLE_THREAD)
-	{ "love.thread", luaopen_love_thread },
-#endif
-#if defined(LOVE_ENABLE_WINDOW)
-	{ "love.window", luaopen_love_window },
-#endif
-	{ "love.boot", luaopen_love_boot },
-	{ 0, 0 }
-};
+void resolveModule(const char *modulename)
+{
+	std::string luaopen_name = std::string("luaopen_") + modulename;
+	for (int i = 8; i < luaopen_name.length(); ++i)
+		if (luaopen_name[i] == '.')
+			luaopen_name[i] = '_';
+
+	lua_CFunction f = (lua_CFunction) SDL_LoadFunction(0, luaopen_name.c_str());
+	if (f)
+	{
+		modules[modulename] = f;
+		return;
+	}
+}
+
+int moduleLoader(lua_State *L)
+{
+	const char *modulename = lua_tostring(L, 1);
+	// If we don't know it, try to resolve it.
+	if (!modules.count(modulename))
+		resolveModule(modulename);
+
+	// If we still don't know it.. it doesn't exist.
+	if (!modules.count(modulename))
+	{
+		lua_pushfstring(L, "\n\tno LOVE module '%s'.", modulename);
+		return 1;
+	}
+
+	lua_pushcfunction(L, modules[modulename]);
+	return 1;
+}
 
 #ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
 int w__openConsole(lua_State *L);
 #endif
 	lua_setfield(L, -2, "_os");
 
-	// Preload module loaders.
-	for (int i = 0; modules[i].name != 0; i++)
-	{
-		love::luax_preload(L, modules[i].func, modules[i].name);
-	}
+	// Preload love.boot.
+	love::luax_preload(L, luaopen_love_boot, "love.boot");
+
+	// Add our module loader
+	love::luax_register_searcher(L, moduleLoader, 2);
 
 #ifdef LOVE_ENABLE_LUASOCKET
 	love::luasocket::__open(L);

File src/modules/love/love.h

View file
  • Ignore whitespace
 {
 #endif
 
+LOVE_EXPORT void registerModule(const char *name, void *f);
 LOVE_EXPORT const char *love_version();
 LOVE_EXPORT const char *love_codename();
 LOVE_EXPORT int luaopen_love(lua_State *L);