Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds an asset management system, in two parts:
This PR depends on the Profiler (#30).
FileSystem abstraction
Since our engine plans to use object "pack" files to efficiently store assets, we need some concise way to interact with both the on-disk filesystem and our "virtual filesystem" for these packs, as if they were one and the same.
Thus, the first major thing implemented here is a FileSystem abstraction:
You can create a DiskFS from a root folder using the static helper:
You can also create a VFS from a root pack file:
The FileSystem allows you to perform many disk operations, some asynchronously.
The main point here is that no matter what is underlying the file resources, you can interact with them in the same way, through the FileSystem.
The main consumer of FileSystem is the Resource Management.
Resources & Resource Managers
A Resource is a single, self contained object that something in the Engine can consume.
It may be a texture, a mesh, a model (which would depend on and thus load both the texture and model, as well as other things like animations..), or something like a library, resource script, etc.
Every type of Resource is identified by a unique ResourceType key, and has its own ResourceTypeManager. All ResourceTypeManagers are managed by the central, unique ResourceManager.
The ResourceManager has three ways to load a Resource - and it can load a resource of any type that has a recognized ResourceTypeManager loaded:
The first option is simply
resourceManager.load<RESOURCE>(path)
, which will load the file at the given path, check whether it's of the type given, then return the type. The second option is to give the resource type directly, which is obtainable by every Resource class' static TYPE member. The third option is to get the ResourceTypeManager of a given ResourceType, then pass that back in to get a resource.Each of these ways provide better compile-time stability, better runtime performance, and better clarity of programming, so usage of these is preferential and circumstantial.
Once a Resource goes out of scope, it can be culled by the ResourceManager - as all Resource references are counted.
You can get another reference to a loaded Resource by calling load() again with the same path - it will return the cached value, and increase the number of references internally.
Closes #18.