Thread: Creating a database

  1. #1
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968

    Creating a database

    So I'm making this class that is supposed to organize all the dynamic data I'm going to use in my game.

    It's basically yet another wrapper for a map wrapper class. Only this time we're going to globalize it and derive subclasses that load in each kind of data when called. I kindof want a centralized database though, so maybe I should instead create a manager inside of the database to manage all the other managers?

    It seems redundant to create a manager of managers in the database don't you think? Instead maybe there should be a database for each kind of dataset in the database class? But then again how would that be any different from having multiple global managers. I shouldn't put them in a database for the sake of keeping them local and not global instances.

    So then the database will of course load a dataset into each manager. So maybe the best thing to do is keep a container, perhaps a simple vector of manager classes. Therefore I can add a manager via function, as well as remove one.

    Then I would have to hardcode the data loading functions, actually, that isn't true! The resource manager is set up to create objects using an initializing variable, which can be fed information via binary or text file.

    So then all the functionality of the database can be in a function that loads data from a file, which then uses the proper manager.. wait how will it know? Then I'll just create a resource manager of resource managers to connect a string to each manager. Templates within templates, bwahaha i love oop. To load the files i'll pass it a string to search for a filename that will co ensign with the proper manager.

    Problem solved.

    Now to write it.

    Code:
    #ifndef DATABASE_H
    #define DATABASE_H
    
    #include "Resource_Manager.h"
    
    class Database
    {
    	
    	
    };
    
    #endif
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  2. #2
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    hm it seems C++ syntax won't let me create a template of templates....

    Code:
    Resource_Manager<Resource_Manager<T_>> Data;
    Code:
    c:\documents and settings\home\my documents\visual studio 2005\projects\textgame\textgame\database.h(9) : error C3203: 'Resource_Manager' : unspecialized class template can't be used as a template argument for template parameter 'T_', expected a real type
    Maybe a vector would work better.

    AHG a vector doesn't work either!!!
    Code:
    std::vector<Resource_Manager<T_>> Data;
    Did they like, fail to add this feature to C++ yet?

    Can't we keep templates in a container?
    Last edited by Shamino; 06-03-2007 at 09:42 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Yes, you can. This compiles:
    Code:
    template <typename T>
    class something {
    public:
        something<something<T> > x;
        std::vector<something<something<something<T> > > > y;
    };
    I'm using Dev-C++ which employs g++.

    You must have some other problem. Can you post some more code?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Code:
    #ifndef DATABASE_H
    #define DATABASE_H
    #include <vector>
    
    #include "Resource_Manager.h"
    
    class Database
    {
    	
    	std::vector<Resource_Manager<T_>> Data;
    };
    
    #endif
    This is the code that is giving me that error...
    I tried this:
    Code:
    std::vector<Database<Database<Resource_Manager<T_>>>> Data;
    And it compiles, the question is, I'm having a real tough time understanding that syntax, what exactly is going on here?
    Last edited by Shamino; 06-05-2007 at 02:03 AM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  5. #5
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    http://www.open-std.org/jtc1/sc22/wg...005/n1757.html

    New release of gcc will have a fix for this

    std::vector<Resource_Manager<T_>> Data;

    What is _T?

  6. #6
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    T_ is the data type that the resource manager manages, since it can't keep a text file or a graphic file in the same std::map. It has to be specified on creation

    I want the Database to be responsible for creating resource managers.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  7. #7
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    As was pointed out earlier, if your Database class is going to contain a template with an undefined datatype, it must also be a template.

    Code:
    template <typename T_>
    class Database
    {
    	
    	std::vector<Resource_Manager<T_>> Data;
    };
    Also, if you don't have a compiler that had started to implement the C++09 standard, you probably need a space between the two >, like so:

    Code:
    std::vector<Resource_Manager<T_> > Data;
    There is no greater sign that a computing technology is worthless than the association of the word "solution" with it.

  8. #8
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    So it's perfectly possible to have multiple types of resource manager (menu, sound, etc etc) in the vector?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  9. #9
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    For some reason I'm having trouble with the syntax of creating an instance of a database class.

    Code:
    #ifndef DATABASE_H
    #define DATABASE_H
    #include <vector>
    
    #include "Resource_Manager.h"
    #include "Menu.h"
    
    template <typename T_>
    class Database
    {
    	Database()
    	{
    		Data.push_back(Resource_Manager<Menu>);
    		//Data.push_back(std::string Name);
    	}
    
    private:
    	std::vector<Resource_Manager<T_> > Data;
    
    };
    
    #endif
    On creation I want them to push back resource managers of various types into the vector, for easy modification and all.

    Does this even work?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  10. #10
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    I think you're on the wrong track because I tried something like this myself before I really understood the inner workings of templates.

    Templates are a compile time construct. They provide the compiler a set of instructions for writing certain types of functions and classes. For example, when you declare a std::vector<int>, the compiler goes to the std::vector template and essentially writes a new class called std::vector<int>. vector<int> and vector<float> and vector<yourclasshere> are all distinct data types, they are as unrelated as bool is to void*.

    Templates are not a means of creating heterogeneous containers. The type of object that a vector holds is determined when you compile your program, and this can't be changed during runtime. If you want a collection of different objects, you need to have a common base class, Manager for example, that all the objects inherit from. Then you need a std::vector<Manager*>.

    You could cheat and use a std::vector<void*>, but that would require you to track what kind of object is at each index, and that would get messy real fast.

    In the long run, your best bet is to create a base class for all of your Managers and store a bunch of pointers to various Manager objects. If you set up the correct virtual functions in class Manager, this should provide all the functionality you need.
    There is no greater sign that a computing technology is worthless than the association of the word "solution" with it.

  11. #11
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    So then I guess all I can do is have the resource managers in the global scope? Oh wait, no I can make them initialize in the Manager object, kudos dude .
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    First of all Shamino I applaud your efforts and your willingness to listen to advice. You have come a very long way in a very short time on this board and in your code.

    In this instance I feel that you may be trying to be too, shall we say, C++'ey? I never did like the template idea and I think I made that known but I also realize that you are a person that has to try out an idea and research it before deciding if you like it or not. There is nothing wrong with that and that is how I learn as well. Here I think you have come to a place in your template approach that is extremely flawed and perhaps should re-think the entire system.

    I almost tried your template idea and then realized what a mess it would be later when I needed to determine object types. Yes there are ways in C++ to do that but I feel there is a much better approach. The approach I took to this comes from my experience with COM programming.

    In COM programming everything is derived from IUnknown which implements a few very simple interfaces. So allow me to show my implementation of the objects and managers and go through the problem logically.

    What both of us are trying to do is create a centralized way of creating, accessing, storing, and destroying objects. The problem is that not all of our objects fit into a nice neat little mold and each have their own quirks. But in the bigger picture we are simpy storing objects.

    So a generic, non-specific manager or container base class will at the very least have:

    1. Have a method to create or add an object to the container and maybe return an ID.
    2. Have a method to delete or remove an object from the container.
    3. Have a method to gain access to an object via the ID returned in item 1 or upon creation.
    4. Have a method to return the number of objects in the container or the object count.
    5. Have a method to store the objects to disk.
    6. Have a method to read the object from disk.

    Classes derived from this base can then implement object-specific functions relative to the type of object they contain. But all container classes will at the very least inherit items 1 through 4. If we make the base too complex we will end up making it object specific and therefore will code ourselves into a corner when trying to add different objects.

    Now at the very least a generic, non-specific object base class will:

    1. Have a method to create the object.
    2. Have a method to access the object.
    3. Have a method to delete the object.
    4. Have a method to store the object to disk.
    5. Have a method to read the object from disk.

    Now for specific objects we derive from the base object class and implement other functions specific to the type of object.

    Now thanks to C++ polymorphism we can do this:

    Code:
    class CObject
    {
       ...
    };
    
    class CObjectMgr
    {
       std::vector<CObject *> m_vObjects;
    
       public:
          DWORD Add(CObject *pObject)
          {
             m_vObjects.push_back(pObject);
             return static_cast<DWORD>(m_vObjects.size()-1);
          }
          
    
    };
    Now as long as the object we want to add is derived from CObject we can pass this to the container base class Add() function and it will work perfectly. My system has the main list or vector in the base container class and all access to and from it is through the container class. The base class is then responsible for destroying the object.

    This is a very simple system but it works well for me. Sorry the post is so long but it is hard to talk about generic container class programming in short posts.

  13. #13
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Hmm

    Your non specific manager class sounds alot like this:
    Code:
    #ifndef RESOURCE_MANAGER_H
    #define RESOURCE_MANAGER_H
    #pragma warning(disable: 4786)
    #pragma warning(disable: 64)
    #include <vector>
    #include <map>
    #include <string>
    #include <boost\shared_ptr.hpp>
    #include <boost\weak_ptr.hpp>
    #include <iostream>
    
    template< typename T_ >
    class Resource_Manager
    {  
    
    public:
    
    	typedef T_ value_type; // std library convention 
    
    	typedef boost::shared_ptr<T_> Resource_Ptr;
    	typedef boost::weak_ptr<T_> Resource_Observer;
    	typedef std::map< std::string, Resource_Ptr > Resource_Map;
    
    	Resource_Manager<T_>() {};
    	~Resource_Manager<T_>() {};
    
    	void Add_Resource(const std::string & name, T_)
    	{
    		Resource_Ptr Raw_Resource(T_);
    		mResources.insert(std::make_pair(name, Raw_Resource));
    	}
    
    	Resource_Observer Request_Resource(const std::string & name)
    	{
    		Resource_Map::iterator  it = mResources.find(name);
    
    		if (it == mResources.end())
    		{
    			std::cout << "Internal program error, " << name << " does not exist!" << std::endl;
    		}
    		else
    		{
    			return Resource_Observer(it->second);
    		}
    	}
    
    	void Request_Resource_Removal(const std::string & name)
    	{
    		Resource_Map::iterator it = mResources.find(name);
    
    		if (it != mResources.end())
    		{
    			mResources.erase(it);
    		}
    	}
    
    private:
    	Resource_Map  mResources;
    };
    
    #endif
    I have 1-4 covered...


    The only thing is we aren't storing a generic object we're storing an actual type determined by me. But in reality they are all objects to store, so you're right there. If I did it your way, it looks like I'd have different kinds of managers for each type of object we're using. But it's funny because they all are objects, but we still can't put them in the same box, I guess it makes sense though, because object is such a generic term. The same would be for my templated resource manager. The question in the end is really which is easier to organize into a master database class?

    So far I've been failing with my template, but thats just because I've been trying to throw them all in the same container, which is impossible with both methods. I think I will still use boost in my managers, it allows for easy dynamic memory. I'll probably have to cut the map down to a vector, actually I don't see why I shouldn't keep it. It seems pretty useful to have a string connected to each type of data.

    I like your method better to be honest, it makes more logical sense. But my question still, is how do I centralize it into a Database class?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  14. #14
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    The manager has been converted!

    Code:
    class Object_Manager
    {  
    public:
    
    	Object_Manager() {};
    	~Object_Manager() {};
    
    	typedef boost::shared_ptr<Object> Object_Ptr;
    	typedef boost::weak_ptr<Object> Object_Observer;
    	typedef std::map< std::string, Object_Ptr > Object_Map;
    
    	void Add_Object(const std::string & name, Object * CObject)
    	{
    		Object_Ptr Raw_Object(CObject);
    		mObjects.insert(std::make_pair(name, Raw_Object));
    	}
    
    	Object_Observer Request_Object(const std::string & name)
    	{
    		Object_Map::iterator  it = mObjects.find(name);
    
    		if (it == mObjects.end())
    		{
    			std::cout << "Internal program error, " << name << " does not exist!" << std::endl;
    		}
    		else
    		{
    			return Object_Observer(it->second);
    		}
    	}
    
    	void Request_Object_Removal(const std::string & name)
    	{
    		Object_Map::iterator it = mObjects.find(name);
    
    		if (it != mObjects.end())
    		{
    			mObjects.erase(it);
    		}
    	}
    private:
    
    	Object_Map  mObjects;
    };
    Last edited by Shamino; 06-10-2007 at 12:57 AM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  15. #15
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    The only thing I'm curious about, the Object base class, does it have nothing but empty virtual methods in it? It seems to me that every single object is different in every aspect 1-5.

    Code:
    class Object
    {
    	virtual void Create()
    	{}
    	virtual void Access()
    	{}
    	virtual void Delete()
    	{}
    	virtual void Read_File(std::string Filename)
    	{}
    	virtual void Save_to_File(std::string Filename)
    	{}
    };
    Last edited by Shamino; 06-10-2007 at 12:15 AM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. literature database: help with planning
    By officedog in forum C++ Programming
    Replies: 1
    Last Post: 01-23-2009, 12:34 PM
  2. Profiler Valgrind
    By afflictedd2 in forum C++ Programming
    Replies: 4
    Last Post: 07-18-2008, 09:38 AM
  3. Creating a database (inside a GUI)
    By goosematt in forum C Programming
    Replies: 7
    Last Post: 10-23-2003, 11:04 AM
  4. Creating a simple database: is my approach OK?
    By m712 in forum C++ Programming
    Replies: 1
    Last Post: 11-18-2002, 02:27 AM
  5. creating a small database need some hints
    By asim0s in forum C++ Programming
    Replies: 1
    Last Post: 02-28-2002, 10:44 AM