Jump to content
  • Advertisement
Sign in to follow this  
Madster

Generic Datastore

This topic is 4694 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, haven't posted in a few months.... grr classes. Anyway, here's my question. Has anyone implemented or has ideas on how to implement a generic datastore object? The idea is to have a data-centric architecture and have several classes attaching arbitrary data to the datastore, who will serve it to anyone who wants it, will cache it if needed and will properly destroy it. Also it should only be possible to wipe the data stored by the same class. More than one Datastore should be allowed, as it would be nice, but that's not really critical. The main issues are: -Classes should be allowed to store any kind of data in the store, ordered or unordered. -Data should be cached if needed and classes should be able to turn caching on and off at will (there's probably no need to toggle it after creating the first object in the store for a given class, though) -Classes might want to see the data stored by other classes. -Any class might request the data to be delivered back to them in a certain order, maybe with special ordering types. for the first and second point I just thought of a template with handles and handle dereference objects, as seen in a Gems book. For the third I'm thinking maybe I could define a separate class with the datatype and #include it in all the interested parties For the fourth one I'm at a loss. Is this doable without calls to sort and find on each data fetch? Would I need a sort-of-iterator-for-handles thing? I don't even know if the two methods I had considered before would allow this. Plus, it's all theory so far. An use case would be something like storing the level geometry and then requesting as an octree from the physics engine and then the same geometry as a bsp by the renderer. All of this without having geometry datatypes in the Datastore class. Anyone done this before? PS: please excuse any weirdness in this post.. it's 6am :s

Share this post


Link to post
Share on other sites
Advertisement
Eh I forgot...any class should be able to modify what was stored by another class... and there should be a way to *pair* data, such as attaching physics info to a game actor.

Am I aiming too high? O_o

Share this post


Link to post
Share on other sites
Okay, just thinking out loud here:

collections would be inside of a static STL map after a type specified in a parameter to the template, so that when you want to access a collection of values, you'd ask by type and name.

You would use it this way:

Datastore<mydatatype> *store; // emphasis: you can create it whenever you feel like it, could be in a variable instead
store = new Datastore<mydatatype>("nameofmystore");
store.push( mydata ); // where mydata is of type mydatatype
delete store;

...

store = new Datastore<mydatatype>("nameofmystore");
i = store.begin();
for (....)


So, since the actual store is static, it doesn't get deleted unless you explicitly do so. You only need to spawn "interfases" to the store.
the store name is to avoid confusion when there are more than 1 stores with the same type.

The use for this is decoupling the loaders from the renderers from the memory managers :)
Instead of iterators ( store.begin() and such) I am considering using handlers.

any thoughts?

[Edited by - Madster on December 30, 2005 9:09:38 PM]

Share this post


Link to post
Share on other sites
I don't really understand what you're trying to do, but whatever it is...use a singleton.

DataStore<T>& store = DataStore<T>::GetRef();
store.push_back(t);

Leave them pointers alone!

-Alex

Share this post


Link to post
Share on other sites
umm I'm trying to set a scheme up so that arbitrary classes will be able to post data or get data. They don't have to know who posted the data they need, they just assume it's there and use it. This should improve modularity I think, and clean up dependencies (which have bit me several times in the past).

Say you have a simple procedural control system that modifies a vector of ints called "inputs". You decide to make a new object oriented system with bells and whistles... that does the same thing. It's configurable and has all sorts of nice things, but it's basic purpose is still posting input data.
So... it just modifies the same vector of ints called "inputs". No need to re-hook with game logic everywhere, just once for the update call in the main loop.
The same could be done with everything from pathfinding AI to textures and sounds.

So that's the purpose.
Hm it is really a singleton, isn't it?
getting the instance like that would be faster than creating and destroying stuff explicitly? or it just makes it harder to go wrong?

Share this post


Link to post
Share on other sites
One idea would be to embed a database engine that uses in-memory storage, and then just use SQL statements to query and update the data.

Share this post


Link to post
Share on other sites
I really don't recommend you do this. You are going to be writing code imperatively, and storing mutable data in a global data structure. Even if your code is not multithreaded (which in this situation would cause you pain and suffering, and ultimately death), you are still breaking down walls of abstraction and your ability to reason about the behavior of code is severely crippled. Any given computation can potentially modify this global state, and the rest of your code has no idea that this is happening. Thus, the behavior of a function invoked with the same paramters twice can result in two different values. At least with OO (not recommended, but used as an example) we can encapsulate some of this state and minimize these weird effects. You also have the issue of tracking dependencies ... you are going to end up having some data hanging around in this repository when it is no longer needed, which is basically a memory leak. So you are going to implement some reference-tracking system on top of your existing memory management solution. You really have no modularization, you have merely transformed object-to-object dependencies into object-to-mutable-global-state dependencies. It's like the worst of OO combined with the clean, elegant approach of the Windows Registry.

Share this post


Link to post
Share on other sites
Interesting.

I hadn't considered SQL, and it could be argued that I am reinventing the wheel. I'll look into that, though I'm not too fond of passing strings that need to be parsed for simple accesses.

The Reindeer Effect: thanks for the reply.
For multithreading, mutexes would have to come into play. Acessing the same resource from multiple threads at the same time would mean a simple delay, and a warning would be logged, since one would want to minimize these collisions.
About this:
Quote:
Any given computation can potentially modify this global state, and the rest of your code has no idea that this is happening. Thus, the behavior of a function invoked with the same paramters twice can result in two different values.

This is the purpose of the system, that any given computation could potentially modify the global state. Think of it as a game class, where the datastore is a private member. Any method could modify it, yes, that's why not *all* data goes there, only the kind we need to share.
Calling a stateful function (such as most class methods) will often result in two different values. That's not really a problem.

About data hanging around: yes, could be a problem. I plan to provide erase methods, and the method to get data will create a default object if there is none. Keep in mind this is mostly to keep resources and gamestate. The stored objects can also be reference counted, but i believe that's not what you meant. pointers to objects in the datastore are volatile, and not to be kept around.
Thread safety is accomplished, as usual, trough mutexes.

A memory leak is unfreed data that cannot possibly be freed anymore. This is not the case, as the data is still contained in a class that will free it on closure. If misused, it can produce bad memory management at most.

About this:
Quote:
You really have no modularization, you have merely transformed object-to-object dependencies into object-to-mutable-global-state dependencies. It's like the worst of OO combined with the clean, elegant approach of the Windows Registry.

I believe moving dependencies from object-to-object to object-to-mutable-global-state does produce modularization, since now I can attach and detach modules at will. It was, in fact, the driving idea. Can you elaborate more on why you feel this isn't the case?
I was aiming also for registry-like functionality, without getting Win32-dependant, and also keeping things in RAM. Can you elaborate on why you feel this is the worst of OO? It is not pure OO. is that it? I feel it's pretty clean, but I'm still deciding on the final form.

Thanks again :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!