Time again for another update I guess, not much to report but I’ve been doing some good rework to make just the Texture loading for now be able to happen on a different thread from the update thread or the rendering thread.
So for that I have a threadpool that I think I yoinked from somewhere, which let’s me basically queue up functions or lambdas to be executed in the pool of threads. I can also configure how many threads are going to be in the pool, which I currently have set to 3.
Then I also found I needed a way to reference the future Texture that will be spat back from the thread once it’s loaded, so obviously I looked at std::future.
And then found that std::future doesn’t currently have a way to check if the value is ready without waiting for it, that’s an std::future experimental feature, since the std::future valid (or shared_future, for what I would use this for) only checks if the future is a valid future, not if the value/data was set.
So i rolled my own templated Future Class to simply have a way to set or get data from it, as well as tell if the data has been set or not with an isReady().
This means now all my std::shared_ptr<Texture> will need to become std::shared_ptr<Future<Texture>> so that’s quite a bit of refactoring, which I think is mostly done now.
One gotcha with this though, is I didn’t want my Future’s getData() to return the value, since that would be a lot of copying, so now instead of being T getData() it’s T* getData(), but that means now I have to be careful that the Future doesn’t get decontructed when the data is still referenced somewhere. This is a real problem because right now the Texture data is being passed via standard pointer like this to the Render thread, so there is in fact a possibility of segfaulting here.
I’ll probably look into how to wrap that, maybe my Future will hold the Texture as a std::shared_ptr<Texture> itself and return a std::shared_ptr<Texture> from getData instead of Texture*, that would likely solve the issue because then the Future<Texture> only holds a reference to the Texture that will clean itself once all other references are destructed, so it can stay in memory until after the rendering thread is done with it and then once it’s cleared out of the Update thread and the Rendering thread it’ll delete itself instead of leaking or becoming an invalid pointer that is used in the Render Thread.
That’s the main scoop for now I think, good progress though since most of the errors of switching the TextureLoader to return std::shared_ptr<Future<Texture>> are cleared up now and the getResource functions for that will now toss a lambda into the threadpool. I think the jury is still out on whether or not it’ll all actually work but considering that I already use a similar mechanism to the threadpool for my workqueue stuff, which is actively used, I think the lambdas and threadpool and everything should work, it’s only a little issue with that getData() returning a raw pointer and not a shared pointer and hopefully that’ll mean that now I won’t be bogged down as much doing Texture Loading.
I’ll need to do a lot more of this in the future I think, although I realized that I may not need to do this to all of my types, but it’ll probably help for anything that is large enough since I suspect Disk reading all needs to be dumped to a different thread.
And uh, actually I just remembered I need to re-check what I put into the lambda, I need to make sure that the disk reading part is inside the lambda, I think I left it out in front of the lambda portion…