Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
72 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Make it a 'singleton' template manager

Well now that you understand how the 'normal' template works, here is the implementation of the 'singleton' template:

template <class T, int n> class TPersistentManager
{
public:
	TPersistentManager(void);
	~TPersistentManager(void);	

	int  Add(const T* p_T);
	int  Delete(const T* p_T);
	int  Delete(int index);
	int  DeleteAll();
	
	T*   Get(int index);
	T*   Get(const T* p_T);
	
	Int  GetCount();
	int  GetError();
	char *GetErrorString();

private:
	static int refcount;
	static TManager<T, n>	*p_m_tManager;	
};

// Note that you MUST initialize these for correct functionality
template <class T, int n> int TPersistentManager<T, n>::refcount = 0;
template <class T, int n> TManager<T, n>* 
   TPersistentManager<T, n>::p_m_tManager = 0x00000000;

template <class T, int n>
TPersistentManager<T, n>::TPersistentManager(void)
{
    if(refcount == 0)
    {
        p_m_tManager = new TManager<T, n>;
    }

    refcount++;
}


template <class T, int n> 
TPersistentManager<T, n>::~TPersistentManager(void)
{
    refcount--;

    if(refcount == 0)
    {
        delete p_m_tManager;
	  p_m_tManager = 0x00000000;
    }
}

template <class T, int n> 
int TPersistentManager<T, n>::Add(const T* p_T)
{
    return p_m_tManager->Add(p_T);
}

// .
// . Rest of code omitted… see the attached code files
// .

template <class T, int n> 
char *TPersistentManager<T, n>::GetErrorString()
{
    return p_m_tManager->GetErrorString();
}

Now this class does some crucial work, it makes sure that there is only one TManager pointer in the TPersistentManager template. It also redirects all functions to use that TManager class for performing its actions. Note that this redirection is needed because otherwise you cannot make your own class deriving from this so that it can use the functions. If you were to try that with the TManager it would just allocate new variables for each instance of the your class. Also note that it keeps a reference count to determine wheter the last instantiation of the class was released, in which case all memory for the managed objects is released as well.

How to use it for your own types

Okay that is all nice, but now the question remains: "How can I use it?" The answer to that question is rather simple: you just instantiate a class the same way you would instantiate a normal template class. Here is an example to make it clear:

class CImageSystem : public TPersistentManager<CImage, 128>
{
public:
    CImageSystem();
    ~CImageSystem();

    . // Functions you want to make specific for the CImageSystem class
    .
    .
}

And now you can create multiple instances of the CImageSystem class in different files and they will still use the same CImageSystem class (which is the property of a singleton class).

Evaluation

Although this code might seem a bit messy (and I cannot deny it is) it allows you to easily create managers for all kind of data structures without having to rewrite code. And although the extra function calling in the TPersistentManager class might seem like overhead (and it is), if you have a good compiler it will inline these functions for you, resulting in close to 0% function calling overhead in some cases.

Conclusion

Well I do not think that I can say anything here that isn't obvious yet. There are really only two choices. You can use this approach, or you can use another approach. I really do not want to say that this is the best way to manage data, but at least it is a way (and in my opinion a rather good one).

If there are any people out there with suggestions, comments or remarks, please feel free to email me at: e.j.folkertsma@student.utwente.nl

Source

Here is the source.

Note that this probably isn't the best code possible. I wrote it in 60 minutes or so with some retouching (since I didn't mean to send it along in the first place) to make it readable.




Contents
  Introduction
  Making it a singleton

  Source code
  Printable version
  Discuss this article