Saturday, 7 September 2013

Constructing object in new thread?

Constructing object in new thread?

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 the IState-interface in order
to improve design (Discard Construct() calls, if the object is already
avaiable!)
Can I make a list of Object instead of Object*?
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 ;))

No comments:

Post a Comment