Resource Management question...

Started by
8 comments, last by Koen 16 years, 1 month ago
I have made a sort of smart(really dumb) array manager... Really I just wanted to ask what flaws you see with it, and what could be improved.

/*
	Author: Cody Doughty
	Data:   March, 6, 2008
*/
#ifndef SMART_ARRAY_H
#define SMART_ARRAY_H

#include <cstdio>

#include <vector>
#include <list>

namespace Varia
{
	template<class Type>
	class XArray
	{
	public:
		XArray(unsigned int p_iMax = 2000, bool p_bDebug = false):m_iMax(p_iMax),m_bDebug(p_bDebug),m_iSize(0)
		{
			if (m_bDebug)
			{
				printf("Creating XArray. Size = %d.\n", m_iMax);
				printf("-->Estimated memory usage: %dbytes.\n", (sizeof(Type)*m_iMax));
			}
			m_vArray.resize(m_iMax);
			std::vector<Type*>::iterator it;
			for ( it = m_vArray.begin(); it != m_vArray.end(); ++it )
				(*it) = NULL;
		}

		~XArray()
		{
			std::vector<Type*>::iterator it;
			for ( it = m_vArray.begin(); it != m_vArray.end(); ++it )
				if ( (*it) != NULL )
				{
					delete (*it);
				}
		}

		void  SetDebug(bool p_bDebug)
		{
			m_bDebug = p_bDebug;
		}

		int   AddElement(Type* p_tType)
		{
			if ( m_iSize >= m_iMax && m_vList.empty() )
			{
				return -1;
			}
			
			if ( !m_vList.empty() )
			{
				unsigned int index = m_vList.front();

				if ( m_vArray.at(index) == NULL )
				{
					if ( m_bDebug )
						printf("Setting Resource:%d\n",index);
					m_vArray.at(index) = p_tType;
					m_vList.erase(m_vList.begin());
				}
				return index;
			}
			else
			{
				if ( m_bDebug )
					printf("Setting Resource:%d\n",m_iSize);
				m_vArray.at(m_iSize) = p_tType;
				++m_iSize;
				return m_iSize-1;
			}
		}

		int	  RemoveElement(unsigned int p_iIndex)
		{
			if ( p_iIndex <= m_iMax-1 )
			{
				if ( m_vArray.at(p_iIndex) != NULL )
				{
					if (m_bDebug)
						printf("Removing element:%d\n",p_iIndex);
					delete m_vArray.at(p_iIndex);
					m_vArray.at(p_iIndex) = NULL;
					m_vList.push_back(p_iIndex);
					return p_iIndex;
				}
				else
				{
					return -1;
				}
			}
			return -1;
		}

		void  IncrementSize()
		{
			if ( m_iMax < m_vArray.max_size() )
			{
				if ( m_bDebug )
					printf("Incrementing Array size from %d to %d.\n",m_iMax,m_iMax+1);
				++m_iMax;
				m_vArray.push_back(NULL);
				m_vList.push_back(m_vArray.size()-1);
			}
		}

		void DecrementSize()
		{
			if (!m_vArray.empty())
			{
				if ( m_bDebug )
					printf("Decrementing Array size from %d to %d.\n",m_iMax,m_iMax-1);
				if ( m_vArray.back() != NULL )
					delete (m_vArray.back());
				if ( m_iMax == m_iSize )
					--m_iSize;
				--m_iMax;
				m_vArray.pop_back();
			}
		}

		void  Clear()
		{
			if ( m_bDebug )
				printf("Clearing Array.\n");
			std::vector<Type*>::iterator it;
			for ( it = m_vArray.begin(); it != m_vArray.end(); ++it )
				if ( (*it) != NULL )
				{
					delete (*it);
				}
			m_vArray.clear();
			m_iMax = 0;
			m_iSize = 0;
		}

		int SetElement(unsigned int p_iIndex, Type* p_tType)
		{
			if ( p_iIndex < m_iMax )
			{
				if ( m_vArray.at(p_iIndex) == NULL )
					m_vArray.at(p_iIndex) = p_tType;
				else
				{
					delete m_vArray.at(p_iIndex);
					m_vArray.at(p_iIndex) = p_tType;
				}
				return 0;
			}
			return -1;
		}
		const Type* GetElement(unsigned int p_iIndex)
		{
			if ( p_iIndex < m_iMax )
				return m_vArray.at(p_iIndex);
			return NULL;
		}
		
	private:
		bool m_bDebug;
		//
		unsigned int m_iMax;
		unsigned int m_iSize;

		std::vector<Type*> m_vArray;
		std::list<int>	   m_vList;
	};
}

#endif //SMART_ARRAY_H


I apologize for the long code. Thank you for any assistance.
Advertisement
Why not just use std::vector directly? I don't really see the point of this code. If you need to manage a vector of pointers rather than objects, that's what smart pointer classes are for.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This is to handle my game objects. Since I have hundred's or more resources floating around I figured it would simplify things to put them all in the same place. not have to worry about cleaning them up, and make the code more readable. This hopefully will also simplify my scripting system when I get it working with it.
I still don't see what this does that can't be accomplished by a std::vector<boost::shared_ptr<Object*> >? (I'm guessing you're not familiar with boost's smart pointers - check it out. They'll make your code a heck of a lot better.)

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Ah I see. Lol, all that code for nothing... Oh well. Thanks.
One last question.
Can you explicitly call delete on a shared pointer?

Just a thought, because if I have 3000+ objects. I may want to get rid of say 800 of them. How would you go about doing that?
Yes, just call ptr.reset().
This seems really weird to me. Do I really need to make the type for the shared_ptr a pointer? If so I can't get it to work.
I can use shared_ptr like this
typedef boost::shared_ptr<int> XInt;	std::vector<XInt> test(0);	test.push_back(XInt(new int));	*test.at(0).get() = 500;	printf("test:%d",*test.at(0).get());

but if I try to make the int a pointer. I cannot seem to access the pointer correctly. Should I just leave it like this? Thank you.
T must be of type int here since shared_ptr is a "replacement" for *. It's a shared pointer to an int.

Quote:
*test.at(0).get() = 500;



Why not simply *test[0] = 500 ?

Quote:
printf("test:%d",*test.at(0).get());



Don't use printf. It's a lot safer to use std::cout.

std::cout << "test: " << *test[0];
The template parameter is the type you need a pointer to, not a pointer to that type. So you don't need to use int*
On a side note: you don't need
*test.at(0).get()

This will do:
*test.at(0)

edit: nevermind... ;)

This topic is closed to new replies.

Advertisement