Where is CCFileUtils in Lua?

Hi Guys,

i want to use “require” to import some other lua module. it should set package.path for require command. but how to get application bundle path? CCFileUtils class disappeared in the lua. i have no way to set package.path. how to solve it? Thanks in advance.

Best regards.
zhang

I don’t think you can use “require” in lua if all the lua files are packed into apk.
You now, apk is a compressed file.

Somebody copied the lua files into a writeable directory, and can use “require”.

ok, you are right on android platform. but on the iOS platform i have no way to copy lua files to a appointed directory, like the directory “/data/data/” in the file CCFileUtils_android.cpp. but it is easy to get application bundle path. and of course, there is no problem to get lua file path on iOS path.

on the current version for iOS platform, no way to copy lua file, no way to get application boundle path, and no way to use require. so i think CCFileUtils is necessary for some platform.

I had the same problem and solved it with this patch to android-x see https://github.com/giom/cocos2d-x/commit/64463461f8af18d069bd99f7de76323fdec976ec
It adds a addSearchPath method to the lua engine that adds a patch to package.path

In my AppDelegate.cpp I have the following lines:

string lua_libs = CCFileUtils::fullPathFromRelativePath(“lua/libs”);
CCScriptEngineManager::sharedScriptEngineManager()->getScriptEngine()->addSearchPath(lua_libs.c_str());

string path = CCFileUtils::fullPathFromRelativePath(“lua/main.lua”);
CCScriptEngineManager::sharedScriptEngineManager()->getScriptEngine()->executeScriptFile(path.c_str());

Hope this helps…

Cheers,

@Guillaume Maury
Thanks for your patch. This approach looks fine!
Issue #647 created.

Some developer said, in iOS, if your lua files are in the same directory. Then you can use require.
In Android, you can’t use it through you add a search path. Because all the lua files are packed in the apk.

in iOS, you can add the lua path to the package.path.

In my codes, I emplement myself CCScriptEngineProtocol.

In this way, my lua codes can place any subfolder, and use require

like this:
MyLuaEngine::MyLuaEngine()
{
m_scriptModule = new CCLuaScriptModule();
tolua_game_lua_open(m_scriptModule->getLuaState()); // it’s my lua stub
tolua_CocosDenshion_open(m_scriptModule->getLuaState()); // CocosDenshion
InitLuaEnv(m_scriptModule->getLuaState()); // add search path
}

for InitLuaEnv function:

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

int InitLuaEnv( lua_State* lua_S )
{
int error;
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSAllDomainsMask, YES);
NSString* doc_dir = [paths objectAtIndex:0];
NSString* path = [NSString stringWithFormat:"package.path='%/?.lua;%@/?.lua;’…package.path", [[NSBundle mainBundle] resourcePath], doc_dir];
error = luaL_dostring(lua_S, [path UTF8String]);
return error;
}
#endif

My lua folders like this:
resource

|—scripts

|—folder1

|—folder2

|—….

it is a good way to modify script engine. if i can do this in lua code, it would be perfect. i don’t want to modify the engine code. it make upgrading cocos2d hard in furture. but for now, it seems i have no choice. thanks for your reply

Guillaume Maury,
could you pull a request to cocos2d-x?

I can copy your code to resolve it, but I think I can not “steal” it.

I’ve created a pull request for this https://github.com/cocos2d/cocos2d-x/pull/455

Thanks a lot. I just merged it into master.

@Guillaume Maury

In CCLuaScriptModule::addSearchPath():

lua_getglobal( d_state, "package" );
lua_getfield( d_state, -1, "path" ); // get field "path" from table at top of stack (-1)
const char* cur_path =  lua_tostring( d_state, -1 ); // grab path string from top of stack

Where is “package” defined?

It’s part of lua… It’s used by require to find libraries to load…

See http://www.lua.org/manual/5.1/manual.html under require (modname)

“package” is defined by lua, a library, a global table

I ran the codes:

static void testGetGlobal(lua_State *L)
{
    lua_getglobal(L, "package");
    lua_getfield(L, -1, "path");
    const char* path = lua_tostring(L, -1);
}


int main(int argc, char* argv[])
{
    lua_State *L = lua_open();
    testGetGlobal(L);
    lua_close(L);

    return 0;
}

It crashed at lua_getfield(L, –1, “path”), because the return value of lua_getglobal(L, “package”) is nil.

I mean after invoking lua_getglobal(L, “package”), the top value is nil.

Hiyah :slight_smile: So the searchPath fix works great for lua-on-ios, but fails for lua-on-android as the assets are embedded inside the APK which is a zip.

Is that correct? (I think it is from my reading of the source)

A chap here: http://www.anddev.org/ndk_opengl_loading_resources_and_assets_from_native_code-t11978.html

Has come up with a way of exposing a native fread/fopen directly from a zip using libzip to expose the APK file. Do you think its reasonable for us to patch loadlib.c to use this fread-in-zip approach to allow loading in the lua included files within android or is there a better / more obvious solution that I’m missing?

Ah I see in github trunk this all works :wink: hoo-rah!

Now, require can be used in android too.

Hi,
I’m aware that this issue is quite old now, but I tried using the code in android to get the various lua files that reside in sub folders with no success using the latest cocos2dx version.
The addSearchPath although has the root folder in assets, does not make the rest of the lua files reach the other lua files follow the require path.