| 430 | // *********************************************************************** |
| 431 | |
| 432 | int LuaInclude(lua_State* L) { |
| 433 | const char* name = luaL_checkstring(L, 1); |
| 434 | String includeName(name); |
| 435 | |
| 436 | // unlike require we assume the name is an actual file name |
| 437 | String realPath; |
| 438 | VFSPathToRealPath(includeName, realPath, pState->pArena); |
| 439 | |
| 440 | if (!FileExists(realPath)) { |
| 441 | // check if the include is in system/shared/ (assuming it's a relative path) |
| 442 | if (includeName[0] != '/') { |
| 443 | realPath = TempPrint("system/shared/%S", includeName); |
| 444 | } |
| 445 | } |
| 446 | if (!FileExists(realPath)) { |
| 447 | Log::Warn("Unable to locate include %S", includeName); |
| 448 | return 0; |
| 449 | } |
| 450 | |
| 451 | pState->luaFilesToWatch.PushBack(realPath); |
| 452 | |
| 453 | luaL_findtable(L, LUA_REGISTRYINDEX, "_MODULES", 1); |
| 454 | lua_getfield(L, -1, realPath.pData); |
| 455 | if (!lua_isnil(L, -1)) { |
| 456 | // table has already been loaded, and is cached, so we're done |
| 457 | return 1; |
| 458 | } |
| 459 | lua_pop(L, 1); |
| 460 | |
| 461 | // @todo: put modules in another thread and sandbox them |
| 462 | CompileAndLoadModule(realPath, 1); |
| 463 | // stack is [module, _MODULES] |
| 464 | lua_pushvalue(L, -1); |
| 465 | // stack is [module,module,_MODULES] |
| 466 | lua_setfield(L, -3, realPath.pData); |
| 467 | return 1; |
| 468 | } |
| 469 | |
| 470 | // *********************************************************************** |
| 471 |
nothing calls this directly
no test coverage detected