2014-12-28 1 views
0

I figured out how to make Lua scripts require other Lua scripts in an Android environment.LuaJ - Установить package.path в Java-коде перед вызовом сценария Lua из файла

Однако это решение имеет конфигурацию package.path внутри самого Lua-скрипта верхнего уровня. Я хочу переместить конфигурацию package.path в код Java, который запускает сценарий, потому что package.path специфичен для среды Android, в то время как сценарий можно запускать в любом месте.

Вот что я пробовал:

InputStream input getAssets().open("lua/test/pathTest.lua"); 
Prototype prototype = LuaC.instance.compile(input, "pathTest.lua"); 
Globals globals = JsePlatform.standardGlobals(); 
globals.load(new BaseLib()); 
globals.load("package.path = package.path .. ';/assets/lua/?.lua;/assets/lua/test/?.lua'"); 

LuaClosure c = new LuaClosure(prototype, globals); 
c.call(); 

Я также попробовал несколько других форм как:

globals.load(new StringReader("package.path = package.path .. \";/assets/lua/?.lua;/assets/lua/test/?.lua\""), "pathTest.lua"); 

Или принимать результат LuaValue от нагрузки и попутно, что в LuaClosure. Все они приводят к тому, что сценарий не работает при первом require, не имея возможности найти сценарий с ссылкой.

У кого-нибудь есть идеи?

* edit - Если кто знает, как установить рабочий каталог в папку/assets/lua /, поэтому я могу использовать относительные пути оттуда в сценарии Lua, что было бы предпочтительнее.

ответ

1

Думал, что я пробовал это раньше, но вот решение.

InputStream input getAssets().open("lua/test/pathTest.lua"); 
Prototype prototype = LuaC.instance.compile(input, "pathTest.lua"); 
Globals globals = JsePlatform.standardGlobals(); 
globals.load(new BaseLib()); 
globals.load(new StringReader("package.path = '/assets/lua/?.lua;'"), "initAndroidPath").call(); 

LuaClosure c = new LuaClosure(prototype, globals); 
c.call(); 

Это приведет к инициализации пути к среде Android/lua/folder. Это позволяет мне использовать относительные пути в вызове require в сценарии Lua.

Например, требовать файл в подкаталоге: assets/lua/test/luaScript.lua

Lua требует будет выглядеть так:

require "test.luaFile" 
0

На основе решения mnemy, добавьте некоторое содержимое. по умолчанию определение метода FindResource является (PS: В BaseLib.java из luaj исходного кода):

public InputStream findResource(String filename) { 
    return getClass().getResourceAsStream(filename.startsWith("/")? filename: "/"+filename); 
} 

getResourceAsStream способ поиска ресурсов по отношению Андроида в корневой каталог Android проекта. (Я решил проблему с загрузчиком класса со ссылкой LuaJ and Android: cannot bind class, решение для облачного Zheng.) Итак, если вы хотите использовать «requre» для загрузки другого модуля в другой каталог (например, «/ storage/emulated/0/temp/test/lua») , вы можете реализовать свой собственный интерфейс findResource следующим образом:

// Implement a finder that loads from absolute path. 
public InputStream findResource(String name) { 
    try { 
     File f = new File(name); 
     return new FileInputStream(f); 
    } catch (java.io.IOException ioe) { 
     return null; 
    } 
} 

И установите как ваш globals.finder. Затем соответствующим образом отрегулируйте путь поиска:

globals.load(new StringReader("package.path = '/storage/emulated/0/temp/test/lua/?.lua;'"), "initAndroidPath").call();