Sign in to follow this  

Freetype2 problems using std::vector

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi :P I'm trying to run following code. Every Hud contains a std::vector that's meant to keep it's possible childs. So far, so good. Now some of the relevant code. That's the actual operation i'd like to accomplish.
  Hud Father, Child;
  Father.setPos(30,30);
  Father.setSize(100,150);
  Father.init();

  Child.setPos(302,30);
  Child.setSize(100,150);
  Child.init();
  Father.push_back(Child);





and then render it like:
void Hud::render(){
  freetype::print(font, Position.x, Position.y, "TEST");

  for(std::vector<Hud> ::iterator it = Children.begin(); it < Children.end();it++)
	  it->render();
}





Here's the class:
class Hud {
	private:
		std::vector<Hud> Children;
		
		Vector2px Position;
		Vector2px Size;
		freetype::font_data font;	

	public:
		Hud(){};
		Hud(const Hud &p);

		virtual ~Hud(){font.clean();};
		virtual void render();

		void init(){font.init("test.TTF", 16);};				
		void push_back(Hud Child){Children.push_back(Child);};
};





The problem seems to be the actual push_back() into the actual vector. When i call it i'll get an
_BLOCK_TYPE_IS_VALID_(pheap->nBlockUse);




error. I tried to minimize the problem and reduced the problem to the "font". When i use a copy-constructor like this: (since the freetype::font_data doesn´t seem to have one)
Hud::Hud(const Hud &p)
{
	Children = p.Children;
	Position = p.Position;
	Size = p.Size;
	font.init("test.ttf", 16);    //well, that's how NEW fonts are made, but not how i think a copy should be done.
} 





... i'd be fine but that's no actual copy. So i wonder what i could do to actually get my Huds into those vectors. I hope someone has had this problem before. (btw. i tried to search the freetype src for relevant infos but couldn´t even find "font_data" :/) Thank you for taking the time

Share this post


Link to post
Share on other sites
Quote:
Original post by GreyHound
... i'd be fine but that's no actual copy. So i wonder what i could do to actually get my Huds into those vectors.


You are making 2 copies of the object and storing the second copy in your array instead of the actual instance created in your "actual operation"


//the argument Child here is a copy of what's passed in because
//you are passing by value (instead of by reference or pointer)
void push_back(Hud Child)
{
//what actually ends up in the list here is a copy of the
//function parameter
Children.push_back(Child);
};




If you actually want Father to directly link to Child you need to make your vector a vector of pointers to Hud.

-me

Share this post


Link to post
Share on other sites
i already guessed something like that but my quick tries couldn'd reach the goal. I actually assumed the vector is actually a pointer construct which doesn´t really appear as such.


So i should go with something like



std::vector <Hud*> Children;

Hud *HudA = new Hud();
HudA->DoStuff();
Hud *HudB = new Hud();
HudB->DoStuff();
HudA->push_back(HudB);

?

I´ll prolly have to experiment a bit and see if that's solving my issues.
Looks like i'll have to create the huds on the heap or i'll run into the problem sooner or later again since i'd need a space to store them somewhere anyway.

Share this post


Link to post
Share on other sites
thanks a lot, this is really the right way to do it. When i tried the earlier version i already doubted i won't be able to add child afterwards anyway.

ta, very appreciated

Share this post


Link to post
Share on other sites
Well you don't technically need to create them on the heap, you just need to pass a pointer into the push_back method:

this would work fine

Hud Child, Father;
Father.push_back( &child );



The main reason that you don't want them on the stack is that on windows machines stack space is usually capped at 2MB whereas heap is essentially unlimited (RAM available + disk space available for virtual memory).

-me

Share this post


Link to post
Share on other sites
Don't work with raw pointers yourself if you don't need to.

If every HUD actually does use "the same" font (logically, even if they aren't currently the same freetype::font_data instance), then make a static member of the class instead (so that all instances can share it). You can initialize on first use like so (since freetype isn't using RAII properly):


class HUD {
// other stuff
static freetype::font_data theHUDFont;
static bool inited;
HUD() {
if (!inited) { inited = true; theHUDFont.init("test.ttf", 16); }
// other stuff
}
// other stuff
};
// Initialize the statics.
static freetype::font_data HUD::theHUDFont;
static bool HUD::inited = false;


Otherwise, strongly consider using smart pointers such as boost::shared_ptr, which actually is exactly the right model for this situation. (This will also cover you if you need to call some kind of 'uninit()' function.)




On the other hand, if every HUD in the final configuration logically has "its own" font, and you're just having problems setting up the tree structure, then you don't need anything like that, either. Instead, just change your interface. For example:


// Make this one *private*
HUD::HUD() {}

HUD::HUD(XY pos, XY size, const string& fontname, int fontsize) {
// set position and size, and init the font.
}

HUD::addChild(XY pos, XY size, const string& fontname, int fontsize) {
HUD child;
// set position and size of the child.
children.push_back(child);
// Now get a reference to (alias of) the copy that was pushed back...
HUD& added;
// and init *its* font.
}

Share this post


Link to post
Share on other sites
Morning fellows, hi Zahlman,

i'll need to learn about smartpointers first, never used them. I just know they are capable of freeing theirselfes whenever objects loose their scope or something like that. Probably nice to use for crucial elements that might be created by script/users and may not be very sensible.

Why i'm quite happy with the way it's now is because i like the idea of beeing able to pick a total set of Huds and just move it somewhere else.
I think later i´ll have several GUI objects that actually manage one screen setup. One PlayGUI, one MissionChangeGui, etc. So whenever states change i would just render another Gui. And in this case i mayb want to keep the chathud even when the mission changes so i´d just get the pointer and put it in the missionchangegui.

The basic idea about the hud class is to be quite independent on what is theoretically possible. The usability and security isn't something i took care of yet. (just started 3h before i started the thread)

Saving the font name is something i already considered and i guess i will. But i just started with the freetype library and don't even know what's possible.

I plan to connect the hud interface with a scripting language anyway that's why i used setSize, setPos etc. because that´s prolly the way it will be done via script someday. ;D

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this