• Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

We're also offering banner ads on our site from just \$5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.

### #ActualKing Mir

Posted 21 February 2013 - 05:05 AM

You still have a bug. If two object are ever retrieved at the same time, and the second causes some vector to resize, the first reference to the first object will become invalid. You need to use a std::deque. Or a std::list, but deque is almost always faster.

Could you elaborate on this a bit more? Is this related to multithreading or something else?

gDefaultDataStoreSize = 1; //This is probably a const global, but assume that it's one for this example
const int & from_state( State<int>(10) ).as<int>();
auto state2( State<int>(20) ); //causes Datastore::_data to resize
use(from_state);//uses freed memory. 
That's a quick and dirty example, and you can imagine that generally from_state would be a parameter to a function up the tree, in unrelated code.

Gotcha. You're using _storeRepo->getDataStore<T>() to check if the stored type matches the accessed or assinged type, by _storeRepo->getDataStore<T>() is an expensive operation, involving a hashmap search. You can find a less expensive way to do this check.

I was thinking about just skipping the type check entirely, and just casting down the private interface member down to whatever the as<T>() function was invoked with, but that seems dangerous, and i'm not sure if i'd get errors in case of a bad cast. I was thinking of using static_cast, is trying to avoid dynamic_cast here ok?
I also thought of saving the result of typeid on initialization of State and then checking if the saved type and attempted type are equal, but i dont know whether that's an expensive operation to do every time i call the as<T>() method (which happens a lot, as most of the data is stored in these - physics data, game logic data etc). I've read about it a bit, and some sources say it's bad, some say it's good, and mostly from a design standpoint. Is saving the type_info structure inside State and checking it against the parameter of the as<T>() method an okay design decision? That way i could make the acquisition of the data a bit faster instead of doing the map lookup every time.

If you don't check, then as long as you never do the wrong call, everything is fine. If you ever do use the wrong call, it could be hard to track down the error. I suggest putting the check in an assert.

Yeah saving the typeid seems like a much better approach to a check.

### #1King Mir

Posted 21 February 2013 - 05:04 AM

You still have a bug. If two object are ever retrieved at the same time, and the second causes some vector to resize, the first reference to the first object will become invalid. You need to use a std::deque. Or a std::list, but deque is almost always faster.

Could you elaborate on this a bit more? Is this related to multithreading or something else?

gDefaultDataStoreSize = 1; //This is probably a global, but assume that it's one for this example
const int & from_state( State<int>(10) ).as<int>();
auto state2( State<int>(20) ); //causes Datastore::_data to resize
use(from_state);//uses freed memory. 
That's a quick and dirty example, and you can imagine that generally from_state would be a parameter to a function up the tree, in unrelated code.

Gotcha. You're using _storeRepo->getDataStore<T>() to check if the stored type matches the accessed or assinged type, by _storeRepo->getDataStore<T>() is an expensive operation, involving a hashmap search. You can find a less expensive way to do this check.

I was thinking about just skipping the type check entirely, and just casting down the private interface member down to whatever the as<T>() function was invoked with, but that seems dangerous, and i'm not sure if i'd get errors in case of a bad cast. I was thinking of using static_cast, is trying to avoid dynamic_cast here ok?
I also thought of saving the result of typeid on initialization of State and then checking if the saved type and attempted type are equal, but i dont know whether that's an expensive operation to do every time i call the as<T>() method (which happens a lot, as most of the data is stored in these - physics data, game logic data etc). I've read about it a bit, and some sources say it's bad, some say it's good, and mostly from a design standpoint. Is saving the type_info structure inside State and checking it against the parameter of the as<T>() method an okay design decision? That way i could make the acquisition of the data a bit faster instead of doing the map lookup every time.

If you don't check, then as long as you never do the wrong call, everything is fine. If you ever do use the wrong call, it could be hard to track down the error. I suggest putting the check in an assert.

Yeah saving the typeid seems like a much better approach to a check.

PARTNERS