defold / editor2-issues

DEPRECATED
44 stars 4 forks source link

Exposing bundle path for Native Extensions. #2606

Open selimanac opened 5 years ago

selimanac commented 5 years ago

Looks like there is a build-in method for retrieving bundle path to reading "game.projectc" when app launches on different platforms.

It is not super easy for NE developer to retrieve bundle path for different platforms. We have to separate a bunch of code for each platform. Our need is increasing every day and we are starting to repeat the same code base over and over in different NEs. DEfOS has a solution for desktop. I'm using it as it is and expanded it to iOS and Android... I believe many more people is going to need it.

So please expose the bundle path to Native Extension developer(If I'm not mistaken and if it is available). Than we can easily retrieve files from bundle path.

britzl commented 5 years ago

What's the use-case? I'm not 100% sure I understand the problem you are trying to solve.

selimanac commented 5 years ago

What's the use-case?

Loading a bundled files.

Defold's extension-videoplayer-native is a good example. If you want to load mpg file from bundle, you should retrieve complete path of it: Android - iOS

DefOS has the similar logic for desktop. Now, I need all of them. So we are basically start to duplicating same code to every different NE.

I think(I hope) there is build-in solution for retrieving bundle path in Defold. Because looks like Defold is loading "game.projectc" on every platform on app launch and it print the full path of it on the console.

britzl commented 5 years ago

I think you could use the Directories extension by Sergey Lerg: https://github.com/Lerg/extension-directories

local path = directories.path_for_file('video.mpg', directories.resources)

subsoap commented 5 years ago

The Directories extension does work.

Beware (to anyone in the future searching) that on Android it's not so simple to simply know the directory to the base.apk you need to use Android's resource systems

selimanac commented 5 years ago

I think I couldn't explain myself. Suggesting another extension with the same codes just approve my point. Those extensions (Defos, Directories, videoplayer, my extension and maybe more) are uses the same code base to retrieve the path. It is just a copy paste of same thing.

What I'm saying is; if there is a solution in Defold for retrieving the bundle path please expose it to NE and rescue "us" from this repeating code mayhem.

britzl commented 5 years ago

If there is a working extension such as extension-directories then the recommendation should be to use that extension to get the base path. We could spend the time adding it to the engine, but for now my recommendation would be to try and use the extension if it provides what you need.

But it's also worth discussing the point that @subsoap brought up about Android. And what about HTML5?

selimanac commented 5 years ago

I give up...

britzl commented 5 years ago

Nope, you shouldn't give up. We're discussing it here internally.

britzl commented 5 years ago

Created issue 3520 in the Defold repo.

selimanac commented 5 years ago

And what about HTML5?

Reading files from “/res/common” folder with Emscripten

selimanac commented 5 years ago

And what about HTML5?

Reading files from “/res/common” folder with Emscripten

I guess it can be automated by Defold with a simple checkbox. (Read file names and sizes from /res add it to json) : https://forum.defold.com/t/reading-files-from-res-common-folder-with-emscripten/55056/11?u=selimanac

AGulev commented 5 years ago

@selimanac I'm not sure, but maybe it's what you asked for?

-------- / #3520 - Added : Added sys.get_application_path() to get a path to the application executable

https://forum.defold.com/t/defold-1-2-160-has-been-released/60637?u=agulev

AGulev commented 5 years ago

@selimanac did it help with your issue?

selimanac commented 5 years ago

@AGulev I haven't had time to test it on different platforms yet(especially on Android), sorry. However, the main intent was to get the build path directly from the native extension.

PS: It returns "/Applications/Defold.app" on macos. Shouldn't that be the ../project_path/build/ folder or just the project folder?

AGulev commented 5 years ago

It is possible to call lua method from Cpp/C

I don't think so. I think it should be bundle folder.

selimanac commented 5 years ago

I don't think so. I think it should be bundle folder.

But this the application folder: "/Applications/Defold.app" and got no good use.

AGulev commented 5 years ago

yes, sorry application folder.

AGulev commented 5 years ago

As I understand this is a folder where we put Bundle Resources Is this something you need?

britzl commented 5 years ago

sys.get_application_path() returns the path where the exe is running from.

-- macOS: /Applications/my_game.app
local application_path = sys.get_application_path()
print(application_path) --> /Applications/my_game.app

-- Windows: C:\Program Files\my_game\my_game.exe
print(application_path) --> C:\Program Files\my_game

-- Linux: /home/foobar/my_game/my_game
print(application_path) --> /home/foobar/my_game

-- Android package name: com.foobar.my_game
print(application_path) --> /data/user/0/com.foobar.my_game

-- iOS: my_game.app
print(application_path) --> /var/containers/Bundle/Applications/123456AB-78CD-90DE-12345678ABCD/my_game.app

-- HTML5: http://www.foobar.com/my_game/
print(application_path) --> http://www.foobar.com/my_game

This is requested by forum users to load FMOD banks that are bundled with the application so that the fmod.get_bundle_root() function could be deprecated. Many extension creators had to add their own support functions. Now the path can be passed to the extension in function calls etc.

selimanac commented 5 years ago

On MacOs it is not returning "my_game.app" it returns Defold.app which is the Defold itself when building on Defold. I wasn't test this recently but it is not possible to retrieve the /res folder content from this location like: /Applications/Defold.app/res. This is why I had to pass the project folder manually.

subsoap commented 5 years ago

At least with some use cases, when building on Defold you want to detect if you are running from the editor anyway since the folder structure will be different.

local function is_editor()
    if not (sys_info.system_name == "Windows" or sys_info.system_name == "Darwin" or sys_info.system_name == "Linux") then
        return false
    end

    if files.isdir("bundle_resources") then
        return true
    else
        return false
    end
end

ex

        local extra_path = ""

        local bank1 = ""
        local bank2 = ""
        local bank3 = ""

        if is_editor() then
            print("Editor Path")
            extra_path = "./bundle_resources/common/assets"
            bank1 = (extra_path .. "/banks/master.bank")
            bank2 = (extra_path .. "/banks/master.strings.bank")
        elseif sys_info.system_name == "Android" then
            print("Android Path")
            extra_path = "file:///android_asset/"
            bank1 = (extra_path .. "banks/master.bank")
            bank2 = (extra_path .. "banks/master.strings.bank")
        elseif sys_info.system_name == "Darwin" then
            print("macOS Path")
            -- extra_path = "./" -- for building in editor (with script)
            extra_path = "../../" -- for bundling
            bank1 = directories.path_for_file(extra_path .. "assets/banks/master.bank")
            bank2 = directories.path_for_file(extra_path .. "assets/banks/master.strings.bank")         
        else
            print("Other Path")
            bank1 = directories.path_for_file(extra_path .. "assets/banks/master.bank")
            bank2 = directories.path_for_file(extra_path .. "assets/banks/master.strings.bank")
        end 

        fmod.studio.system:load_bank_file(bank1, fmod.STUDIO_LOAD_BANK_NORMAL)
        fmod.studio.system:load_bank_file(bank2, fmod.STUDIO_LOAD_BANK_NORMAL)

files.lua

local M = {}

--- Check if a file or directory exists in this path
function M.exists(file)
    local ok, err, code = os.rename(file, file)
    if not ok then
        if code == 13 then
            -- Permission denied, but it exists
            return true
        end
    end
    return ok, err
end

--- Check if a directory exists in this path
function M.isdir(path)
    -- "/" works on both Unix and Windows
    return M.exists(path.."/")
end

return M