class
#include <Corrade/Utility/Resource.h>
Resource Access to compiled-in resources.
This class provides access to data files compiled into the executable using the corrade_
Resource compilation
Resources are organized in groups, where a group is a set of files that are encoded in a hexadecimal form into a single *.cpp
file which is then compiled alongside your other sources.
The corrade-rc executable and the corrade_
group=game-data [file] filename=license.txt [file] filename=../resources/intro-new-final.ogg alias=intro.ogg [file] filename=levels/insane.conf alias=levels/easy.conf
The group
is an identifier that you'll subsequently pass to the Resource() constructor, each [file]
section then describes one file to be compiled in, with paths relative to location of the configuration file. By default, the filename
is the name under which the files will be available when calling getRaw() or getString() later, including any directory separators. Use the alias
option to override the name.
There can be just one resource group or several, organization of the files is completely up to you. For example, if there's a set of files used only by a particular library but not other parts of the application, it might be useful to have them in a dedicated group. Or if there's a lot of files, you might wish to split them up into multiple groups to speed up the compilation and reduce compiler memory use.
Using CMake
Assuming the above file was named resources.conf
, the following CMake snippet will compile the referenced files into a C++ source stored inside the build directory. Its filename gets saved into a ${MyGame_RESOURCES}
variable, which subsequently gets passed to the add_executable()
call:
corrade_add_resource(MyGame_RESOURCES resources.conf) add_executable(MyGame … ${MyGame_RESOURCES})
The corrade_
The variable name also acts as a name used for symbols in the generated file — it has to be a valid C identifier and has to be unique among all resources compiled into the same executable. But apart from that, you'd need the name only if you deal with resources in static libraries as explained below.
Compiling the resources manually
If you're not using CMake, you can execute the corrade-rc utility manually to produce a C++ file that you then compile together with your project. The following invocation would be equivalent to the above CMake macro call:
corrade-rc MyGame_RESOURCES path/to/resources.conf output.cpp
This will generate output.cpp
in current directory, which you then compile together with your sources. The first parameter is again a name used for the symbols in the generated file.
Accessing the resources
If you compiled the resources directly into an executable or into a shared library, you can access them from the C++ code without having to do anything else. First instantiate the class with a group name matching the group
value in the configuration file, and then access the files by their filenames:
Utility::Resource rs{"game-data"}; Containers::StringView licenseText = rs.getString("license.txt"); Containers::ArrayView<const char> soundData = rs.getRaw("intro.ogg"); … std::istringstream in{rs.getString("levels/easy.conf")}; Utility::Configuration easyLevel{in}; …
Because the data are coming from a readonly memory inside the executable itself, the class returns non-owning views. In most conditions you can assume unlimited lifetime of the data, see getRaw() and getString() for details.
Resources in static libraries
If you compile the resources into a static library, the linker will implicitly treat the data as unreferenced and won't include them in the final executable, leading to a not-found assertion during Resource construction. To prevent this, you need to reference them. This can be done using the CORRADE_
int main(int argc, char** argv) { CORRADE_RESOURCE_INITIALIZE(MyGame_RESOURCES) … }
It's important to call it outside of any namespace, otherwise you'll get a linker error. The main()
function is ideal for this, or you can create a dedicated function outside a namespace and then call it from within a namespace.
Overriding compiled-in resources
For shorter turnaround times when iterating on compiled-in resources it's possible to override them at runtime using overrideGroup(). That way you won't need to wait for a recompilation, relink and restart of the application when making changes — instead you tell the application itself to fetch the data from the same location the resource compiler would, by pointing it to the original resource.conf
file on disk:
Utility::Resource::overrideGroup("game-data", Utility::Path::join( /* Assuming resources.conf is next to this C++ source file */ Utility::Path::split(Utility::Path::fromNativeSeparators(__FILE__)).first(), "resources.conf" ));
Resource instance created after this point will parse the configuration file and fetch the data from there, or fall back to the compiled-in resource on error. The files get cached for the lifetime of a particular Resource instance, any subsequent changes in files thus get picked up only next time an instance is created.
Memory access and operation complexity
Resource registration (either automatic or using CORRADE_
The group lookup during construction and hasGroup() is done with a complexity as the resource groups register themselves into a linked list. Actual file lookup after is done in-place on the compiled-in data in a time.
Thread safety
The resources register themselves into a global storage. If done implicitly, the registration is executed before entering main()
and thus serially. If done explicitly via CORRADE_
On the other hand, all other functionality only reads from the global storage and thus is thread-safe.
Public static functions
-
static void overrideGroup(Containers::
StringView group, Containers:: StringView configurationFile) - Override a group.
-
static auto hasGroup(Containers::
StringView group) -> bool - Whether given group exists.
Constructors, destructors, conversion operators
-
Resource(Containers::
StringView group) explicit - Constructor.
Public functions
-
auto list() const -> Containers::
Array<Containers:: StringView> - List of all files in the group.
-
auto getRaw(Containers::
StringView filename) const -> Containers:: ArrayView<const char> - Get resource data.
-
auto getString(Containers::
StringView filename) const -> Containers:: StringView new in Git master - Get resource data as a string.
-
auto get(const std::
string& filename) const -> std:: string deprecated in Git master - Get resource data as a string.
Function documentation
static void Corrade:: Utility:: Resource:: overrideGroup(Containers:: StringView group,
Containers:: StringView configurationFile)
Override a group.
Parameters | |
---|---|
group | Group name |
configurationFile | Filename of the configuration file. Use an empty string to discard a previously set override. |
Overrides compiled-in resources of given group with live data specified in given configuration file, which is useful during development and debugging. Subsequently created Resource instances with the same group will take data from a live filesystem instead and fallback to compiled-in resources only for files that are not found in the overriden file.
Corrade:: Utility:: Resource:: Resource(Containers:: StringView group) explicit
Constructor.
Expects that the group exists.
Containers:: Array<Containers:: StringView> Corrade:: Utility:: Resource:: list() const
List of all files in the group.
The resource group has no concept of a directory hierarchy — if filenames in the input configuration file contain path separators, the returned list will contain them verbatim. The returned strings all have Containers::
Note that the list contains only the compiled-in files, no additional filenames supplied by an overriden group are included. This is done to avoid overrides causing unexpected behavior in code that assumes a fixed set of files.
Containers:: ArrayView<const char> Corrade:: Utility:: Resource:: getRaw(Containers:: StringView filename) const
Get resource data.
Expects that the group contains given filename
. If the file is empty, returns a zero-sized nullptr
view. If the file is not coming from an overriden group, the returned view can be assumed to have unlimited lifetime, otherwise it's alive only until the next overrideGroup() call on the same group.
The filename
is expected to be in in UTF-8. Unlike with Path::
Containers:: StringView Corrade:: Utility:: Resource:: getString(Containers:: StringView filename) const new in Git master
Get resource data as a string.
Expects that the group contains given filename
. If the file is empty, returns a zero-sized nullptr
view. If the file is not coming from an overriden group, the returned string has Containers::
The filename
is expected to be in in UTF-8. Unlike with Path::
std:: string Corrade:: Utility:: Resource:: get(const std:: string& filename) const
Get resource data as a string.