🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

String Array

Started by
2 comments, last by droz 17 years, 4 months ago
I'm trying to write a string array class. I want it to be accessed by either key names or index number. Handling everything including the INDEX access operator is no problem, but trying to handle the mutator is my problem. I guess what I don't understand is how this would work if that operator only allows one argument? Wouldn't I need two, one for the key name (or index number) and one for the string value to assign to it?
Advertisement
You make the index operator return a reference to the element, that way the script will be able to assign the value to the element. This is the same way you would do it in C++.

When accessing a previously unexisting element you'll need to create that element with a dummy value so that you can return the reference to it.

You may, or may not, want implement some way of determining if a value has been assigned to an element. Otherwise the array will grow just by verifying if an element is already existing or not.

One suggestion for how this can be done is to store the last element accessed, so that the next time an element is accessed in the array you can verify if the previous element was modified. If it wasn't modified you remove it again. You'll need some indicator in the element itself to determine if it has been modified or not.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I was trying to make it more complicated than it needed to be, but it's working now.

Thanks for the reply,
jeremy
If anyone is interested here is my string array class. It supports accessing by a key name, which can be a string or a integer. It also adds a few functions such as pushBack, popBack, count, and clear.

/** * AngelScript String Array *   Jeremy Harmon <jeremy at jeremyh.net> **/#ifndef _AWS_INCLUDE_STRING_ARRAY_H_#define _AWS_INCLUDE_STRING_ARRAY_H_    #include <angelscript.h>    #include <string>    #include <vector>    using namespace std;    class stringArray;    typedef struct    {	    string  	key;    	    string 	value;    	    int     	index;	    stringArray	*parent;    }item_t;        typedef vector<item_t*> sArray;        class stringArray    {        public:            stringArray()            {				m_lastAccessed 	= -1;            };            ~stringArray()            {		// We need to delete items that belong to our class. Not all belong to it as a 		// user can make a copy of the array and then clear the copy. The data in		// the original array needs to be left intact.		sArray::iterator Iter;                for(Iter = m_Items.begin(); Iter != m_Items.end(); Iter++)                {                    if((*Iter)->parent == this)                    delete (*Iter);                }            };                        string &operator[](string key)            {		// Check last accessed		if(m_Items.size() > 0 && m_lastAccessed != -1)		{                    if(m_Items[m_lastAccessed]->value == "<NULL_SITEM>")                    {			sArray::iterator Iter = m_Items.begin() + m_lastAccessed;			m_Items.erase(Iter);                    }                }		// Search for array item                sArray::iterator Iter;                for(Iter = m_Items.begin(); Iter != m_Items.end(); Iter++)                {                    if((*Iter) && (*Iter)->key == key)                        return (*Iter)->value;                }		// Add new item		item_t *item;		item 		= new item_t;		item->key 	= key;		item->index	= -1;		item->value	= "<NULL_SITEM>";		item->parent	= this;		m_Items.push_back(item);						m_lastAccessed = m_Items.size()-1;		return item->value;            };            string &operator[](int index)            {		// Check last accessed		if(m_Items.size() > 0 && m_lastAccessed != -1)		{                    if(m_Items[m_lastAccessed]->value == "<NULL_SITEM>")                    {			sArray::iterator Iter = m_Items.begin() + m_lastAccessed;			m_Items.erase(Iter);                    }                }                // Search for array item                sArray::iterator Iter;                for(Iter = m_Items.begin(); Iter != m_Items.end(); Iter++)                {                    if((*Iter) && (*Iter)->index == index)                        return (*Iter)->value;                }		// Add new item		item_t *item;		item 		= new item_t;		item->index 	= index;		item->key	= "";		item->value	= "<NULL_SITEM>";		item->parent	= this;		m_Items.push_back(item);				                m_lastAccessed = m_Items.size()-1;		return item->value;            };            			            stringArray &operator=(stringArray &other)            {                m_Items 	= other.m_Items;		m_lastAccessed	= other.m_lastAccessed;                return *this;            };                        void pushBack(string &key, string &value)            {		item_t *item 	= new item_t;		item->key 	= key;		item->value	= value;		item->index	= -1;		item->parent	= this;		m_Items.push_back(item);            };            void pushBack(int index, string &value)            {		item_t *item 	= new item_t;		item->index 	= index;		item->key	= "";		item->value	= value;		item->parent	= this;		m_Items.push_back(item);            };            void popBack()            {		sArray::iterator Iter;		Iter = m_Items.end();		if((*Iter)->parent == this)                    delete (*Iter);                m_Items.pop_back();            };            void clear()            {		sArray::iterator Iter;                for(Iter = m_Items.begin(); Iter != m_Items.end(); Iter++)                {                    if((*Iter)->parent == this)			delete (*Iter);                }                m_Items.clear();            };            int count()            {                return m_Items.size();            };            int	        m_lastAccessed;            sArray 	m_Items;	};    void registerStringArray(asIScriptEngine *e)    {	e->RegisterObjectType("string[]", sizeof(stringArray), asOBJ_CLASS_CD);	        	e->RegisterObjectBehaviour("string[]", asBEHAVE_CONSTRUCT,  "void f()", asFUNCTIONPR(Constructor, (stringArray*), void), asCALL_CDECL_OBJLAST);	e->RegisterObjectBehaviour("string[]", asBEHAVE_DESTRUCT,   "void f()", asFUNCTIONPR(Destructor,  (stringArray&), void), asCALL_CDECL_OBJLAST);        e->RegisterObjectBehaviour("string[]", asBEHAVE_INDEX,		"string &f(string)", asMETHODPR(stringArray, operator[], (string), string&), asCALL_THISCALL);        e->RegisterObjectBehaviour("string[]", asBEHAVE_INDEX,		"string &f(int)", asMETHODPR(stringArray, operator[], (int), string&), asCALL_THISCALL);        e->RegisterObjectBehaviour("string[]", asBEHAVE_ASSIGNMENT, "string[] &f(string[] &in)", asMETHOD(stringArray, operator=), asCALL_THISCALL);		                e->RegisterObjectMethod("string[]", "void pushBack(string &in, string &in)", asMETHODPR(stringArray, pushBack, (string&, string&), void), asCALL_THISCALL);			e->RegisterObjectMethod("string[]", "void pushBack(int, string &in)", asMETHODPR(stringArray, pushBack, (int, string&), void), asCALL_THISCALL);	e->RegisterObjectMethod("string[]", "void popBack()", asMETHOD(stringArray, popBack), asCALL_THISCALL);	e->RegisterObjectMethod("string[]", "void clear()", asMETHOD(stringArray, clear), asCALL_THISCALL);	e->RegisterObjectMethod("string[]", "int count()", asMETHOD(stringArray, count), asCALL_THISCALL);    };#endif


The code should be self explanatory. The most complicated bit is checking to see if we actually own the item, or if it was added when we copied another's data. If we own it then we should delete it, otherwise we should leave it up to the class that owns it.

[Edited by - droz on February 28, 2007 4:21:29 PM]

This topic is closed to new replies.

Advertisement