Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable asset load redirection #106

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jbliesener
Copy link

@jbliesener jbliesener commented May 4, 2024

This patch allows to redirect the LoadAssetFileData function, so that other resource load mechanisms can be implemented. Specifically, assets can be loaded from resource data embedded in the executable. These resources can be produced with any resource compiler, including, for example https://github.com/vector-of-bool/cmrc.

This allows to create single-file-executables in Windows and Linux with all required resources embedded in the executable.

An alternative asset load implementation could look like this:

#include <cmrc/cmrc.hpp> // see https://github.com/vector-of-bool/cmrc
#include "hello_imgui/hello_imgui_assets.h"

CMRC_DECLARE(myAssets); // see https://github.com/vector-of-bool/cmrc 

auto resource_fs = cmrc::myAssets::get_filesystem();

[...]

HelloImGui::AssetFileData LoadAssetFileDataFromResource_Impl(const char *assetPath)
{
    HelloImGui::AssetFileData r;

    cmrc::file assetFile = resource_fs.open(assetPath);
    const char *begin = assetFile.cbegin();
    const char *end = assetFile.cend();
    r.dataSize = end - begin;
    if (r.dataSize)
    {
        r.data = malloc(r.dataSize);
        memcpy(r.data, begin, r.dataSize);
    }
    return r;
}

HelloImGui::AssetFileData LoadAssetFileDataFromResource(const char *assetPath)
{
    // assets starting with ":/" are ALWAYS loaded from the embedded resource file system
    if (strlen(assetPath)>2 && assetPath[0]==':' && assetPath[1] == '/') {
        assetPath++;
        if (!resource_fs.exists(assetPath))
        {
            std::stringstream msg;
            msg << "LoadAssetFileDataFromResource: cannot load " << assetPath << "\n";
            HIMG_ERROR(msg.str());
            return HelloImGui::AssetFileData();
        }
        else
        {
            return LoadAssetFileDataFromResource_Impl(assetPath);
        }
    }
    else
    {
        // other assets are searched on the embedded resource file system first.
        // If not found there, they are loaded from the standard assets folder
        if (resource_fs.exists(assetPath))
        {
            return LoadAssetFileDataFromResource_Impl(assetPath);
        }
        return HelloImGui::DefaultLoadAssetFileData(assetPath);
    }
}

int main(int, char **)
{
    HelloImGui::setLoadAssetFileDataFunction(LoadAssetFileDataFromResource);

    [...]
}

I'm not sure about the Doxygen comments, you may want to check them.

// returns an AssetFileData structure. By default, it points to
// DefaultLoadAssetFileData.
typedef AssetFileData (*LoadAssetFileDataFunc)(const char *assetPath);

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I have to emit Python bindings for all other code in this library, I cannot use bare C function pointers.

Instead I will need to be replaced by a std::function (which is essentially the same except that it can be bound using Python).

@pthom
Copy link
Owner

pthom commented May 6, 2024

Hello Jorg,

Thanks for the nice suggestion ! I need to review that a bit more thoroughly in the next days.
Normally, there is almost no API for Hello ImGui: everything is done via parameters and callbacks.

If we want to follow this philosophy, it might fit better inside runner_callbacks. However, since this is a quite advanced case, I'm not sure it is worth being added in the user facing callbacks, and your solution might be enough.

Let me think of it for a few days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants