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

Extend ResourceCache for factory functions #972

Open
DanRStevens opened this issue Aug 2, 2021 · 2 comments
Open

Extend ResourceCache for factory functions #972

DanRStevens opened this issue Aug 2, 2021 · 2 comments

Comments

@DanRStevens
Copy link
Collaborator

Currently ResourceCache can only be used with constructors of the cached type. We should find a way to extend this to allow factory functions to be used instead. Really we want some function that takes a given fixed set of parameters, and returns the desired type, which can be added to the cache, and looked up using a parameter list tuple.

@DanRStevens
Copy link
Collaborator Author

@DanRStevens
Copy link
Collaborator Author

I found I can update the syntax slightly to change how parameters are specified. It's not quite what I want, but interesting.

Changing to this allows function style syntax:

template <typename FactoryFunction>
class ResourceCache;

template <typename Resource, typename... Params>
class ResourceCache<Resource(Params...)>
// ...

Example usage:

using AnimationCache = ResourceCache<AnimationSet(std::string)>;

Example usage:

NAS2D::ResourceCache<MockResource(std::string, int)> cache;

The current syntax requires all types to be listed serially:

using AnimationCache = ResourceCache<AnimationSet, std::string>;
NAS2D::ResourceCache<MockResource, std::string, int> cache;

This updated syntax isn't quite what I want, since it's still just a type definition, and doesn't allow specifying a specific factory function that matches that type.

Actually, the limitation is on how objects are instantiated and stored in the std::map:

const auto pairIterBool = cache.try_emplace(key, params...);

Here the try_emplace method is implicitly calling the object's constructor with the given parameters. If we use a factory function to first construct and return an object, we may find the insert method may make more sense. That will have slightly lower efficiency. I don't know of any way to emplace into a std::map using a factory function.


Incidental note: We should probably be using std::forward for those parameters.

It may also make sense to use std::move with the std::tuple used as the key, particularly for large keys, or keys containing std::string objects. The try_emplace has an rvalue overload for the key parameter.

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

No branches or pull requests

1 participant