![]() |
ImFusion C++ SDK 4.4.0
|
Resource system to retrieve at runtime binary data embedded into the application/library. More...
Resource system to retrieve at runtime binary data embedded into the application/library.
The ImFusion Resource system is a light-weight platform-independent mechanism to embed binary data in a library/executable. It is somewhat similar to the Qt Resource System, however does not have any third-party dependencies except for ImFusionCore. It consists of two layers/steps: The embedding mechanism of the data at compilation time, and the retrieval of the data at runtime.
Use the ImFusionResourceCompiler executable to generate a C++ file to build and link into your library/application. The resulting file will contain the specified input files as well as the code needed to implement a Repository and automatically register it with the ImFusion::Resource system (optional). Storing files as external zip-archives is also supported and should be preferred for large files (>100MB), since embedding large files considerably slows down compilation.
A minimal example to embed two files could look like this:
This will create the file MyRepo.cpp containing code that registers a Repository with name MyRepo. This repository then provides the contents of the files data/mesh.obj and data/texture.png under the names mesh.obj and texture.png. Note that you need to include this file into your build system so that it gets compiled and linked into the target library/executable. The target library/executable needs to link against ImFusionCore.
The ImFusion CMake infrastructure provides a convenience function to perform the above steps automatically with a single function call.
For instance, all you need to do to create the resource repository from the above example for your library MyLibrary is the following:
The option EXTERNAL_STORAGE allows to store files in an external zip-archive and avoid embedding them as binary. This is particularly beneficial if you plan to embed large resources (>100 MB), which would slow down/halt the compilation. You can provide a custom directory as argument to this option. Your resources will then be stored there. When querying an externally stored resource, the following directories are searched (in order) for the corresponding zip archive:
The third option, using the IMFUSION_RESOURCES_DIR environment variable, is mainly useful during development. If you use this option in production, you will need to ensure that IMFUSION_RESOURCES_DIR is configured correctly on all systems running your application. In fact, if a custom resources folder is specified, resources are not automatically relocated during installation. We recommend installing the resources in a /Resources subfolder of the executable's directory, so that they are found at runtime (see above for a list of search-paths at runtime).
Resources that are stored in external archives via EXTERNAL_STORAGE can be encrypted with standard symmetric encryption (ENCRYPT) or with asymmetric encryption (ENCRYPT_ASYM). The latter allows different resource-archives that have been signed with the same key to be interchangeable. Note that this operation does however increase the time required to create such archives. To use this option, a valid key-file must be first generated using directly the --generate-key-file (--g) of the ResourceCompiler executable. Once the key is generated, it must be safely store for later re-use, and can be passed as argument to ENCRYPT_ASYM. If you wish to later exchange your deployed resource-archive with a new one, just run this function again with the same key-file and the new resource-files. Since the key used is the same, the old archive can be safely replaced with the new one and the Resource System will be able to load it.
Use the functions in the ImFusion::Resource namespace to retrieve compiled resources at runtime. Resource::query() will search all registered repositories for a resource with the given name and return the first one it finds (the search order is undefined). You can provide an optional repository name to filter and avoid ambiguities.
A Resource::Repository must be registered with the resource system before it can be used. Manual registration of custom repositories is done using the Resource::addRepository() function.
Repositories created with the ImFusionResourceCompiler as described above are registered automatically by default using the static initialization pattern. Therefore, you normally do not need to do anything else in addition to define the resource repository via CMake.
You can opt-out of this feature by passing the no-auto-register flag. In this case the resource compiler will output a header file next to the cpp file providing the declaration of the created repository. You can then include this header file, instantiate an instance of the repository, and register it with the resource system as needed.
During development it can be convenient to not always embed all resources on every compilation but instead load them dynamically from the filesystem at runtime. The FilesystemRepository enables you to do this while maintaining the same retrieval API through Resource::query(). For instance, you could setup your build system to use the ImFusionResourceCompiler only for production builds and setup a FilesystemRepository with the exact same semantics for development builds.
Namespaces | |
| namespace | ImFusion::Resource |
| ImFusion Resource System to store binary data in the executable/library and retrieve it at runtime. | |
Classes | |
| class | ImFusion::Resource::FilesystemRepository |
| Repository for loading resources from the local filesystem. More... | |
| class | ImFusion::Resource::Repository |
| Base interface for a ImFusion resource repository. More... | |
Functions | |
| void | ImFusion::Resource::addRepository (const Repository *rep) |
| Add the given Repository to the set of registered repositories. | |
| void | ImFusion::Resource::removeRepository (const Repository *rep) |
| Remove the given Repository from the set of registered repositories. | |
| const Repository * | ImFusion::Resource::locate (const std::string_view &repositoryName, const std::string_view &resourceName) |
| Searches the registered repositories if they provide a resource identified by the given name. | |
| std::optional< ByteBuffer > | ImFusion::Resource::query (const std::string_view &repositoryName, const std::string_view &resourceName) |
| Queries the registered repositories for the resource identified by the given name. | |
| const Repository * ImFusion::Resource::locate | ( | const std::string_view & | repositoryName, |
| const std::string_view & | resourceName ) |
#include <ImFusion/Core/Resource/Resource.h>
Searches the registered repositories if they provide a resource identified by the given name.
You can use this function to check if a resource is available without actually retrieving it. If there are multiple repositories matching the given query it is undefined which one is returned.
| repositoryName | Optional filter to restrict the search to repositories of the given name. Will search all registered repositories if empty. |
| resourceName | Name of the resource to search for |
| std::optional< ByteBuffer > ImFusion::Resource::query | ( | const std::string_view & | repositoryName, |
| const std::string_view & | resourceName ) |
#include <ImFusion/Core/Resource/Resource.h>
Queries the registered repositories for the resource identified by the given name.
If there are multiple resources matching the given query it is undefined which one is returned. Will return an invalid Optional if no resource was found.
| repositoryName | Optional filter to restrict the search to repositories of the given name. Will search all registered repositories if empty. |
| resourceName | Name of the resource to search for |