Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Static variable headaches

This thread is locked; no one can reply to it. rss feed Print
Static variable headaches
shadyvillian
Member #12,426
December 2010

I'm getting undefined reference linker errors to my static variables

header

#SelectExpand
1class Tooltip 2 { 3 rectangle dimensions; 4 std::string text; 5 int maxWidth; 6 ALLEGRO_TIMER *enableTimer; 7 bool enabled; 8 static bool draw; 9 static ALLEGRO_BITMAP *canvas; 10 11 public: 12 13 Tooltip(): maxWidth(100), enableTimer(NULL), enabled(false){} 14 15 Tooltip(std::string newText, int width): enabled(false) 16 { 17 text = newText; 18 maxWidth = width; 19 } 20 21 void Load(ALLEGRO_EVENT_QUEUE *eventQueue); 22 void HandleEvents(ALLEGRO_EVENT &event, bool isMouseOverObject); 23 void Cleanup(); 24 void Draw(); 25 static void drawCanvas() 26 { 27 //if(draw == true) 28 // { 29 // al_draw_bitmap(canvas, 0, 0, 0); 30 // } 31 } 32 };

source

#SelectExpand
1bool Tooltip::draw = false; 2ALLEGRO_BITMAP Tooltip::*canvas = NULL; 3 4void Tooltip::Load(ALLEGRO_EVENT_QUEUE *eventQueue) 5{ 6 fontHandler font; 7 8 enableTimer = al_create_timer(1.0); 9 al_register_event_source(eventQueue, al_get_timer_event_source(enableTimer)); 10 11 canvas = al_create_bitmap(al_get_display_width(al_get_current_display()), al_get_display_height(al_get_current_display())); 12 13 dimensions = rectangle(0, 0, 10+al_get_text_width(font.size12(), text.c_str()), 10+al_get_font_line_height(font.size12())); 14 15}

I'm getting them on these to variables in the function(also in the header for the part commented out). I've accolated the memory for them at the top of the source file, is there something I'm missing here? using mingw 4.6.2 and c++0x.

Software Engineer by day, hacker by night.

jmasterx
Member #11,410
October 2009

Nevermind.

bamccaig
Member #7,536
July 2006
avatar

Static variables are global, and should be avoided. You probably don't have a good reason to be using them. /rant

It might help if you gave us the exact error messages. More code wouldn't hurt either. Which files and how you're processing and compiling them might be a factor.

ALLEGRO_BITMAP Tooltip::*canvas = NULL;

I'm 99% sure that that is the wrong syntax. I think you want this instead:

ALLEGRO_BITMAP * Tooltip::canvas = NULL;

(Not verified)

shadyvillian
Member #12,426
December 2010

And that was it... derp. I wasn't sure but It wasn't giving a compile error so I never would of figured that out ;D

EDIT: ugh since I added 2 static variables my memory usage went from 41 mb to 250mb :o. Heres my dilemma. I have tooltips for my ui elements. Each object has a class tool tip and the tooltip class in each object manages when they should display. But since they draw in the objects draw function the objects are drawing in different orders when I draw all my objects that need to be drawn some tooltips are under other images so you can't see them. So the first thing I thought of is to have a static bitmap in the tooltip class so that when a tooltip should be drawn I draw it to that bitmap instead then I call a static function of tooltip at the end of all drawing make it so that the tooltip is always drawn last. Does anyone have a better solution ???

Software Engineer by day, hacker by night.

jmasterx
Member #11,410
October 2009

The way I do it is when a tooltip is shown in my Gui, regardless of where it is in the widget hierarchy it gets pushed to the top so that it is then the top most widget.

As for your memory usage... :o

shadyvillian
Member #12,426
December 2010

Haha when I saw that I got rid of that instanstly and went back to the drawing board. No way I'm using another 200mb for that...

Software Engineer by day, hacker by night.

jmasterx
Member #11,410
October 2009

I'm really curious to know how on earth you got 200MB usage... I mean, that's like 200 512x512 uncompressed RGBA images... It just doesn't add up...

You should not need globals though. As BamBam would agree, they are evil.

shadyvillian
Member #12,426
December 2010

It was a 1200x700 px static bitmap and a boolean variable. I got rid of them and back down to 41 mb. it was probably more than the variables taking up the space probably the stuff I was doing with them. I need to learn to hate static variables last time I used them they made my program use like 4Gb of memory and crash... that gave me a good laugh at least ;D

Software Engineer by day, hacker by night.

Thomas Fjellstrom
Member #476
June 2000
avatar

You were probably loading that bitmap over and over.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

bamccaig
Member #7,536
July 2006
avatar

shadyvillian
Member #12,426
December 2010

Does anyone have a suggestion for my problem? My classes aren't anything elaborate just some simple reusable code in a static library for my programs to use. Here's the header just to get an idea:

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_font.h> 3#include <allegro5/allegro_ttf.h> 4#include <allegro5/allegro_native_dialog.h> 5#include <string> 6#include <vector> 7 8namespace framework 9{ 10 /********************************************\ 11 * 12 utility functions 13 * 14 ********************************************/ 15 16 std::string changeCase(std::string word); 17 bool findWord(std::string searchThis, std::string target); 18 std::string getFileName(std::string filePath); 19 std::string intToStr(int value, int base); 20 std::string floatToString(float number); 21 int showMessageBox(std::string header, std::string message, int flag); 22 std::string getXmlData(std::string data, std::string element); 23 24 /********************************************\ 25 * 26 enum declarations 27 * 28 ********************************************/ 29 30 enum LOAD_RESULT 31 { 32 LOAD_FAIL = -1, 33 LOAD_SUCCESS = 0 34 }; 35 36 enum BUTTON_LAYOUT 37 { 38 LAYOUT_OVERLAP, 39 LAYOUT_VERTICAL, 40 LAYOUT_HORIZONTAL, 41 }; 42 43 enum PROGRESSBAR_DISPLAY_FLAG 44 { 45 PB_DISPLAY_NOTHING, 46 PB_DISPLAY_PERCENTAGES, 47 PB_DISPLAY_NUMBERS 48 }; 49 50 enum INPUT_TYPE 51 { 52 INPUT_ALL, 53 INPUT_ALPHA, 54 INPUT_ALPHA_PLUS_COM_APO_DASH, //short for comma and apostrophe 55 INPUT_NUMERIC, 56 INPUT_COMPARISON, 57 INPUT_NUMERIC_NO_SPACE, 58 INPUT_COMPARISON_NO_SPACE, 59 INPUT_ALPHA_PLUS_NUMERIC, 60 INPUT_ALPHA_NO_SPACE, 61 INPUT_ALPHA_PLUS_NUMERIC_NO_SPACE, 62 }; 63 64 /*******************************************\ 65 * 66 general namespace variable declarations 67 * 68 *******************************************/ 69 70 const int NO_BUTTON_SELECTED = -1; 71 72 /********************************************\ 73 * 74 class declarations 75 * 76 ********************************************/ 77 78 class fontHandler 79 { 80 static ALLEGRO_FONT *size12Font; 81 static ALLEGRO_FONT *size64Font; 82 static ALLEGRO_FONT *size16Font; 83 84 public: 85 86 fontHandler(){} 87 ~fontHandler(){} 88 89 LOAD_RESULT initialize(); 90 void cleanup(); 91 ALLEGRO_FONT *size12(); 92 ALLEGRO_FONT *size64(); 93 ALLEGRO_FONT *size16(); 94 }; 95 96 class vector2d 97 { 98 float x, y; 99 100 public: 101 102 vector2d(): x(0.0), y(0.0){} 103 vector2d(float xpos, float ypos) 104 { 105 x = xpos; 106 y = ypos; 107 } 108 109 float getX(); 110 float getY(); 111 112 bool operator== (vector2d &pos) 113 { 114 return (x == pos.x && y == pos.y); 115 } 116 117 bool operator!= (vector2d &pos) 118 { 119 return !(x == pos.x && y == pos.y); 120 } 121 }; 122 123 /********************************************\ 124 rectangle - class that defines the basics 125 of an objects dimensions. 126 ********************************************/ 127 class rectangle 128 { 129 vector2d position; 130 float height, width; 131 132 public: 133 134 ~rectangle(){} 135 rectangle(): position(vector2d()), height(0.0), width(0.0){} 136 rectangle(float xpos, float ypos, float w, float h) 137 { 138 position = vector2d(xpos, ypos); 139 width = w; 140 height = h; 141 } 142 143 rectangle(framework::vector2d newPosition, float w, float h) 144 { 145 position = newPosition; 146 width = w; 147 height = h; 148 } 149 150 vector2d getCenter(); 151 vector2d getPosition(); 152 float getX1(); 153 float getX2(); 154 float getY1(); 155 float getY2(); 156 float getWidth(); 157 float getHeight(); 158 void setPosition(vector2d newPosition); 159 void setPosition(float x, float y); 160 }; 161 162 class Tooltip 163 { 164 rectangle dimensions; 165 std::string text; 166 int maxWidth; 167 ALLEGRO_TIMER *enableTimer; 168 bool enabled; 169 170 public: 171 172 Tooltip(): maxWidth(100), enableTimer(NULL), enabled(false){} 173 174 Tooltip(std::string newText, int width): enabled(false) 175 { 176 text = newText; 177 maxWidth = width; 178 } 179 180 void Load(ALLEGRO_EVENT_QUEUE *eventQueue); 181 void HandleEvents(ALLEGRO_EVENT &event, bool isMouseOverObject); 182 void Cleanup(); 183 void Draw(); 184 }; 185 186 class basicImage 187 { 188 rectangle dimensions; 189 ALLEGRO_BITMAP *image; 190 bool over, scalable; 191 192 public: 193 194 ~basicImage(){} 195 basicImage(): dimensions(rectangle()), image(NULL), over(false), scalable(false){} 196 basicImage(rectangle newDimensions): image(NULL), over(false), scalable(false) 197 { 198 dimensions = newDimensions; 199 } 200 201 void draw(); 202 LOAD_RESULT load(std::string path); 203 void isMouseOver(ALLEGRO_EVENT &event); 204 bool isClicked(ALLEGRO_EVENT &event); 205 void cleanup(); 206 207 void setPosition(vector2d newPosition); 208 void highlight(); 209 bool isImageOver(vector2d position); 210 rectangle getDimensions(); 211 void setDimensions(rectangle newDimensions); 212 void setScalable(bool state); 213 }; 214 215 216 /********************************************\ 217 button - class that represents a button 218 in the program. 219 ********************************************/ 220 221 class button 222 { 223 rectangle dimensions; 224 ALLEGRO_BITMAP *upImage, *overImage, *upPiece, *upLeftPiece, *upRightPiece, *overPiece, *overLeftPiece, *overRightPiece; 225 bool over, scalable, tooltipEnabled; 226 int minimumWidth; 227 Tooltip tooltip; 228 229 public: 230 231 ~button(){} 232 button(): dimensions(rectangle()), upImage(NULL), overImage(NULL), upPiece(NULL), upLeftPiece(NULL), 233 upRightPiece(NULL), overPiece(NULL), overLeftPiece(NULL), overRightPiece(NULL), 234 over(false), scalable(false), tooltipEnabled(false), minimumWidth(0){} 235 236 button(rectangle newDimensions): 237 upImage(NULL), overImage(NULL), upPiece(NULL), upLeftPiece(NULL), upRightPiece(NULL), 238 overPiece(NULL), overLeftPiece(NULL), overRightPiece(NULL), 239 over(false), scalable(false), tooltipEnabled(false), minimumWidth(0) 240 { 241 dimensions = newDimensions; 242 } 243 244 button(rectangle newDimensions, std::string text): 245 upImage(NULL), overImage(NULL), upPiece(NULL), upLeftPiece(NULL), upRightPiece(NULL), 246 overPiece(NULL), overLeftPiece(NULL), overRightPiece(NULL), 247 over(false), scalable(false), tooltipEnabled(false), minimumWidth(0) 248 { 249 dimensions = newDimensions; 250 tooltip = Tooltip(text, 100); 251 } 252 253 void draw(); 254 LOAD_RESULT load(std::string upPath, std::string overPath); 255 LOAD_RESULT load(std::string upPath, std::string overPath, ALLEGRO_EVENT_QUEUE *eventQueue); 256 void isMouseOver(ALLEGRO_EVENT &event); 257 bool isClicked(ALLEGRO_EVENT &event); 258 void cleanup(); 259 void scale(int newWidth); 260 LOAD_RESULT enableScaling(std::string upPiecePath, std::string upLeftPath, std::string upRightPath, std::string overPiecePath, std::string overLeftPath, std::string overRightPath, int minimum); 261 rectangle getDimensions(); 262 void setPosition(vector2d newPosition); 263 ALLEGRO_BITMAP* getUpImage(); 264 void EnableToolTips(ALLEGRO_EVENT_QUEUE *eventQueue); 265 }; 266 267 class selectableButton 268 { 269 rectangle dimensions; 270 ALLEGRO_BITMAP *upImage, *selectedImage; 271 bool over, selected, tooltipEnabled; 272 bool irregularShape; 273 Tooltip tooltip; 274 275 public: 276 277 ~selectableButton(){} 278 selectableButton(): dimensions(rectangle()), 279 upImage(NULL), selectedImage(NULL), 280 over(false), selected(false), tooltipEnabled(false){} 281 282 selectableButton(rectangle newDimensions, bool shape): 283 upImage(NULL), selectedImage(NULL), 284 over(false), selected(false), tooltipEnabled(false) 285 { 286 dimensions = newDimensions; 287 irregularShape = shape; 288 } 289 290 selectableButton(rectangle newDimensions, bool shape, std::string text): 291 upImage(NULL), selectedImage(NULL), 292 over(false), selected(false), tooltipEnabled(false) 293 { 294 dimensions = newDimensions; 295 irregularShape = shape; 296 tooltip = Tooltip(text, 100); 297 } 298 299 void draw(); 300 LOAD_RESULT load(std::string upPath, std::string selectedPath); 301 LOAD_RESULT load(std::string upPath, std::string selectedPath, ALLEGRO_EVENT_QUEUE *eventQueue); 302 bool handleEvents(ALLEGRO_EVENT &event); 303 bool isSelected(); 304 void cleanup(); 305 void setSelectedState(bool state); 306 void setY1(float y); 307 void setX1(float x); 308 void setImage(ALLEGRO_BITMAP *img1, ALLEGRO_BITMAP *img2); 309 }; 310 311 class selectableButtonSet 312 { 313 std::vector<selectableButton> buttons; 314 rectangle dimensions; 315 316 int selectedButton; 317 float xSpace, ySpace; 318 BUTTON_LAYOUT layout; 319 bool irregularShape; 320 321 public: 322 323 ~selectableButtonSet(){} 324 selectableButtonSet(rectangle newDimensions, float x_space, float y_space, BUTTON_LAYOUT newLayout, bool shape): selectedButton(NO_BUTTON_SELECTED) 325 { 326 irregularShape = shape; 327 layout = newLayout; 328 xSpace = x_space; 329 ySpace = y_space; 330 dimensions = newDimensions; 331 } 332 333 selectableButtonSet(): selectedButton(NO_BUTTON_SELECTED) 334 { 335 layout = LAYOUT_HORIZONTAL; 336 xSpace = 0; 337 ySpace = 0; 338 dimensions = rectangle(); 339 } 340 341 void draw(); 342 LOAD_RESULT addButton(std::string upPath, std::string selectedPath); 343 LOAD_RESULT load(std::string upPath, std::string selectedPath, int targetButton); 344 bool handleEvents(ALLEGRO_EVENT &event); 345 void cleanup(); 346 int getSelectedButton(); 347 int getNumButtons(); 348 void setNoButtonSelected(); 349 void setSelectedButton(int selected); 350 void setBaseY(float y); 351 void setBaseX(float x); 352 }; 353 354 class progressBar 355 { 356 rectangle dimensions; 357 int maxItems, numItems; 358 float increaseRate, percentageIncrease, barProgress, percentageProgress; 359 ALLEGRO_COLOR barColor; 360 std::string text; 361 362 public: 363 364 progressBar(){} 365 progressBar(rectangle newDimensions, std::string newText, int maxi, ALLEGRO_COLOR color): numItems(0), barProgress(0.0), percentageProgress(0.0) 366 { 367 dimensions = newDimensions; 368 text = newText; 369 barColor = color; 370 maxItems = maxi; 371 increaseRate = dimensions.getWidth() / maxItems; 372 percentageIncrease = 100.0 / maxItems; 373 } 374 375 void draw(PROGRESSBAR_DISPLAY_FLAG displayFlag); 376 void increaseItems(int updates = 1); 377 void setMaxItems(int newMax); 378 void setDimensions(rectangle newDimensions); 379 rectangle getDimensions(); 380 void setNumItems(int num); 381 }; 382 383 class scrollbar 384 { 385 ALLEGRO_BITMAP *piece, *topPiece, *bottomPiece, *bar; 386 387 float minimumBarHeight, maximumBarHeight, moveRate; 388 int numItems, numItemsDisplayed, topListItem, spaceFromTop; 389 390 rectangle barDimensions, bgBarDimensions, targetArea; 391 392 button upButton, downButton; 393 bool dragging, overScrollBar, mouseButtonDown; 394 395 public: 396 397 scrollbar(rectangle bgBar, rectangle target, float mini, int displayed): 398 piece(NULL), topPiece(NULL), bottomPiece(NULL), bar(NULL), numItems(0), topListItem(0), spaceFromTop(0), 399 dragging(false), overScrollBar(false), mouseButtonDown(false) 400 { 401 bgBarDimensions = bgBar; 402 barDimensions = bgBar; 403 targetArea = target; 404 405 minimumBarHeight = mini; 406 maximumBarHeight = bgBarDimensions.getHeight(); 407 numItemsDisplayed = displayed; 408 } 409 410 scrollbar(): 411 412 piece(NULL), topPiece(NULL), bottomPiece(NULL), bar(NULL), numItems(0), topListItem(0), spaceFromTop(0), 413 dragging(false), overScrollBar(false), mouseButtonDown(false) 414 { 415 bgBarDimensions = rectangle(); 416 barDimensions = rectangle();; 417 targetArea = rectangle();; 418 419 minimumBarHeight = 0; 420 maximumBarHeight = 0; 421 numItemsDisplayed = 0; 422 } 423 424 LOAD_RESULT load(std::string piecePath, std::string topPath, std::string bottomPath, int num); 425 LOAD_RESULT loadButtons(std::string upButtonUpPath, std::string upButtonOverPath, std::string DownButtonUpPath, std::string DownButtonOverPath); 426 void cleanup(); 427 void draw(); 428 429 int handleEvents(ALLEGRO_EVENT &event); 430 int getTopListItem(); 431 void recalcuate(rectangle newDimensions, rectangle newTargetArea, int displayed, int num); 432 void recalcuate(int displayed, int num); 433 void resetTopListItem(); 434 void setTopListItem(int num); 435 }; 436 437 class textBox 438 { 439 rectangle dimensions; 440 std::string text; 441 bool shiftMod, over, isActive, drawCursor, disableClicks; // so textbox cant be disabled if clicked off 442 unsigned int maxTextLength; 443 ALLEGRO_TIMER *cursorTimer; 444 445 public: 446 447 textBox(rectangle newDimensions, bool click): 448 shiftMod(false), over(false), isActive(false), drawCursor(false), 449 maxTextLength(20) 450 { 451 disableClicks = click; 452 dimensions = newDimensions; 453 } 454 455 textBox(): 456 dimensions(rectangle()), 457 shiftMod(false), over(false), isActive(false), drawCursor(false), disableClicks(false), 458 maxTextLength(20){} 459 460 bool handleEvents(ALLEGRO_EVENT &event, INPUT_TYPE inputType); 461 462 void setActiveState(bool newState); 463 bool getActiveState(); 464 465 void draw(); 466 void cleanup(); 467 int load(int limit, ALLEGRO_EVENT_QUEUE *eventQueue); 468 void setDimensions(rectangle newDimensions); 469 rectangle getDimensions(); 470 471 void clearText(); 472 std::string getText(); 473 void setText(std::string newText); 474 }; 475 476 class selectionMenu 477 { 478 std::vector<button> menuItems; 479 selectableButton menuBase; 480 int selectedButton; 481 rectangle dimensions; 482 483 public: 484 485 selectionMenu(){} 486 selectionMenu(rectangle position): selectedButton(0) 487 { 488 dimensions = position; 489 } 490 491 int getSelectedItem(); 492 int addButton(std::string upPath, std::string overPath); 493 int loadBase(std::string upPath, std::string selectedPath); 494 void draw(); 495 void handleEvents(ALLEGRO_EVENT &event); 496 void setSelectedItem(int item); 497 }; 498}

Software Engineer by day, hacker by night.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

shadyvillian
Member #12,426
December 2010

The drawing order, thats how my library works I'm trying to integrate a way to make the tooltips draw last. Before I tried to use a static variable that I drew on the size of the screen then drew it last.

Software Engineer by day, hacker by night.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Well, in my GUI library, every widget class is derived from a base widget class. This allows you to make vectors of WidgetBase*'s. After that you can sort them however you want, especially for a drawing order. Need to draw on top? Move it to the bottom of the list.

For you, I suppose your GUI could have something like a current Tooltip*, that it just draws last no matter what. Have your buttons or whatever uses a tool tip set the current GUI tooltip and then let it draw it.

shadyvillian
Member #12,426
December 2010

Yes that is true since only one tooltip can ever be drawn at once. Thanks I'll look into that.

Software Engineer by day, hacker by night.

Go to: