I'm trying to construct objects, that take a while to build in a seperate thread. (Later for loading game assets in real time, while the render loop is running :))
While the object is still building, requests to that object will not fail, but do something in replacement. (Like drawing without textures, while the texture is still loading, in the game). My approach to this is using the State-Pattern - one state for avaiable one for still loading. (My first one was with Proxy, but you really don't wanna see THAT code!)
Here's the complete source code:
#include <thread>
#include <iostream>
#include <list>
using namespace std;
class Object
{
private:
int _data;
/// Classes for states ///
class IState
{
public:
virtual void Use(Object *obj) = 0;
};
class Unavailable : public IState
{
public:
void Use(Object *obj)
{cout << "Object not avaiable..." << endl;}
};
class Avaiable : public IState
{
public:
void Use(Object *obj)
{cout << "Data is: " << obj->_data << endl;}
};
////////////////////////
IState *_state;
void ChangeState(IState *newstate)
{
delete _state;
_state = newstate;
}
void Construct() //Can this be part of IState?
{
this_thread::sleep_for(chrono::seconds(1)); //Work hard
_data = 50;
ChangeState(new Avaiable());
}
public:
Object()
{
//Set the state to unavaiable
_state = new Unavailable();
//Construct the object in seperate thread
thread constructor(&Object::Construct, this); //How do I refer to Construct if its a member of IState?
constructor.detach();
//Thread runs while out of scope!
}
~Object()
{delete _state;}
void Use()
{
//Redirect actions
_state->Use(this);
}
};
int main()
{
{
list<Object*> objects;
for (int i = 0; i < 10; i++)
{
this_thread::sleep_for(chrono::milliseconds(500));
objects.push_back(new Object()); //I can't use Object as the list type, because of push_back()
//copying the Object then DELETING it, thus deleting the state
for (auto obj : objects) //The objects, which are already build shoud write "50"
//otherwise it should write "Not avaiable" as a replacement
{
obj->Use();
}
}
//Free the objects (I really want to avoid this....)
for (auto obj : objects)
delete obj;
} //Extra scope to prevent false memory leaks!
_CrtDumpMemoryLeaks(); //Reports memory leak somewhere. Couldn't track the block back to my code(...)
}
The questions are (as mentiont in the code):
- How could I move the
Construct()
method in theIState
-interface in order to improve design (DiscardConstruct()
calls, if the object is already avaiable!) - Can I make a list of
Object
instead ofObject*
? - What could that memory leak be? (I can't track the block back to my own code with
_CrtSetBreakAlloc
?!)
Looking forware to your answers and comments on design. (I just began to deal with software-architecture, so please correct me if this approach is rubbish ;))