Array of unknown size needing intialisation?

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

Recommended Posts

Hi everyone! I have this structure in my code:
struct GuiInit {
/// The type of element to create
string type;

/// A key/value pair
struct GuiKey {
string key;
string value;
};
//vector<struct GuiKey> values;

/// Array of key/value pairs
struct GuiKey values[]; // invalid - can't have a zero-sized array here!
};


What I want is to be able to do a similar thing to this:
	D3DVERTEXELEMENT9 vDeclaration[] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
{ 0, 28, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 40, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
D3DDECL_END()
};


The reason is that GuiInit defines one GUI element that needs to be created, and the key/value pairs are different parameters for it (such as textures or sizes). I'd like to be able to put it all into one array declaration and use it in my code like that, but the closest I'm able to get is using std::vector (as seen in the first source snippet) which won't do what I need it to. Am I trying the impossible?

Share on other sites
Quote:
 Am I trying the impossible?

I don't really know what you are trying...

Are you attempting this in C or C++? By the use of std::vector and what looks like std::string I would say C++, but you also use structs in a very C like way. Either way, there are much better ways to do what you are trying to do I am assuming. For instance if you are using C++ it really looks like you want an std::map to me.

EDIT: Also if you do not know the scores ahead of time you are going to want to look at dynamic memory allocation

GuiKey * values;int the_size;//get sizevalues = new GuiKey[the_size];delete[] values;

Share on other sites
Why not store your key/value pairs in a data structure designed to hold key/value pairs, like a std::map or stdext::hash_map?

Share on other sites
Yes, I'm doing this in C++. I don't want to create a whole new class just for this one concept, though.

What I'd like is to be able to do something like this:
struct GuiInit initialisers[] = {    { "type", { { "key1", "value1" }, { "key2", "value2" } } }};

But I don't think it's possible - am I right?

EDIT: Driv3MeFar, you posted while I was typing this reply - I'll look into them. The main problem is that I need to retrieve a key and value for each element and pass it to a function.

Bascially, the "key" is the parameter to set, and the "value" is the value to set the parameter to. This structure is meant to simplify initialisation code by letting me use a couple of for loops instead of creating each element manually.

Share on other sites
Ok, I've settled on this...

Structure:
struct GuiInit {	/// The type of element to create	string type;	/// A key/value pair	struct GuiKey {		string key;		string value;	};	/// Position of the element	RECT pos;	/// Key/value pairs for GuiElement::SetElementValue	map<string, string> values;};

Initialisation stuff:
	// initialise all the elements	struct GuiInit init[] = {		{ "Sprite", { m_d3d->GetWidth() - 512, m_d3d->GetHeight() - 128, 512, 128 }, map<string,string>() },		{ "END", { 0, 0, 0, 0 }, map<string,string>() },	};	// setup the sprite information	init[0].values["texture"] = "Assets/UI/Texture/victor.tga";	// create elements	int i = 0;	while( true )	{		if( init.type == "END" )			break;		GuiElement* elem = GuiElement::Factory( init.type.c_str() );		if( elem )		{			elem->InitialiseElement( init.pos );			map<string,string>::iterator z;			for( z = init.values.begin(); z != init.values.end(); ++z )				elem->SetElementValue( z->first, z->second );			m_elements.push_back( elem );		}		i++;	}

This all feels really hacky - any suggestions to fix it up would be appreciated.

Share on other sites
I'll re-iterate what has already been said- Sounds like you want std::map...
Personally I love using maps (maybe too much).

std::map<std::string, std::string> Keyset;
std::map<std::string, std::string>::itorator KeySetItor;
std::string MyValue

KeySetItor = Keyset.find("my key");
if (KeySetItor != Keyset.end())
MyValue = KeySetItor->second;

...something like that should get you started.

Sry - you posted that chunk of code wile I was typing-

To me it is un- obvious as to what you are doing in the second code chunk... could you elaborate some more on your intent?

Share on other sites
Would it not be easier to read this data from a file?

Share on other sites
Quote:
 EDIT: Driv3MeFar, you posted while I was typing this reply - I'll look into them. The main problem is that I need to retrieve a key and value for each element and pass it to a function.

And you didn't read mine? What is going on in your code? I really think you should re-think your design.

Quote:
 I don't want to create a whole new class just for this one concept, though.

Why not?

Share on other sites
Quote:
 Original post by rip-offWould it not be easier to read this data from a file?

Yes, actually, it would. I'll have to look into reading XML files now - they're structure complements the task quite nicely.

My main worry is that this is for the two GUIs in the game (HUD and main menus) and I don't want them to be editable without having the actual game code. I could just use resources and embed the XML data into the executable (at least, if I remember correctly), couldn't I?

EDIT: @Portmanteau: I didn't realise you said "For instance if you are using C++ it really looks like you want an std::map to me.". I just skimmed over your post to be honest and saw the dynamic allocation stuff and figured it wasn't what I was looking for.

And I don't want to create a whole new class because I'm being a lazy coder at the moment :/. If I think about it for a bit I'm actually realising a class for these things would be much easier than what I'm attempting here.

Share on other sites
Quote:
 I could just use resources and embed the XML data into the executable (at least, if I remember correctly), couldn't I?

I believe you can, though I've never used resources.

• 16
• 9
• 13
• 41
• 15