Problems with PGButton

This I have done:


const int num = 20;

NodePath np_2d = framework.get_window(0)->get_aspect_2d();
np_2d.set_scale(0.07);
PT(PGButton) button[num];
NodePath button_np;
for (int i = 0; i < num; ++i)
{
  button[i] = new PGButton("Button");
  button[i]->setup("Label");
  button_np = np_2d.attach_new_node(button[i]);
  button_np.set_pos(0.1 * i, 0.0, 0.1 * i);
}

And here are my problems:

  • when I change num to 30 I get a crash.
  • I can’t see a label on the buttons.
  • how can I attach a callback to the button?

I am looking into the answers to your questions; unfortunately I do not have easy access to a Panda installation this week so it may take me a little bit to get a chance to duplicate your problem. But here is what I can say off the top of my head:

  1. That crash is disturbing. I don’t see that you are doing anything wrong (although you probably don’t really want to be applying a scale to aspect2d; you should probably create an interim node, or scale each button, instead). What is the nature of the crash? Are you sure that your Panda is correctly built?

  2. I will need to investigate the missing label.

  3. You can do something like this for each button:

framework.get_event_handler().add_hook(button[i]->get_click_event(MouseButton::one()),
                                           event_button_click, (void *)i);

Where your function event_button_click looks something like this:

void
event_button_click(CPT_Event event, void *data) {
  int i = (int)data;
  cerr << "got button click: " << i << "\n";
}

In my example, I am casting an integer to a void pointer, which is not strictly proper but usually works. Strictly, you should use the void pointer to pass a pointer to any data structure you like (“this” is commonly used).

David

hi david,

yes, because I am not using an own built - I used the Windows Installer.

This code example is only for tracing the crash. But for sure I will code some stupid things. So please keep telling me strange code lines.

Some notes:

  • When I used PandaNode instead of PGItem or PGButton I don’t get a crash.
  • When I add 30 buttons to the python Sound-Tutorial I don’t get a crash.
  • I am using codeblocks ide with the Visual C++ Toolkit 2003.

I tested the code with VC7.

I got similiar crashes.
Under a debugger run, 50 buttons worked fine, except:

  • no button text was shown
  • after closing the programm i get for every button
    a exception in dtoolbase_cc.h

INLINE void operator delete(void *ptr) {
(*global_operator_delete)(ptr);
}

I have not a debug version of panda3d i can use for deeper
tracking. And i can’t see whats the reason is.

Hmm, are you explicitly calling delete on the buttons that you allocated with new? If you are, you should not, since that will certainly cause a crash (the PT(PGButton) object automatically calls delete for you).

Also, it’s possible it’s related to the sound library. Try disabling sound completely by putting:


audio-library-name null

in your Config.prc.

In my own tests, I am able to create 50 buttons without crashes at exit or any other time, pasting in largely the code that you posted above.

I did, however, discover an error in PGButton::setup() that is causing the label to be obscured by its bevel. I apologize for the error; it’s an example of code rot in rarely-exercised code (most people use the Python DirectButton interface, which doesn’t use the setup() call). I have fixed the bug and the fix will be released in a future version of Panda.

David

no.

no difference.

here the complete code:


#include "pandaFramework.h"
#include "pgbutton.h"
#include "bitMask.h"
#include "pandaNode.h"

// In the File panda_inc/bitMask.h this line was replaced
//  EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, BITMASK32_DEF);
// with this one:
//  template __declspec(dllexport) BITMASK32_DEF;

PandaFramework framework;
CollideMask PandaNode::get_legal_collide_mask() const {	return CollideMask::all_off();}

int main(int argc, char *argv[])
{
	framework.open_framework(argc, argv);
	framework.set_window_title("Daimonin - Client 3d");
	WindowFramework *window = framework.open_window();
	if (!window) { return(-1); }
	NodePath np_2d = framework.get_window(0)->get_aspect_2d();

	const int num = 30;
	PT(PGButton) button[num];
	NodePath button_np;
	NodePath squareRoot = np_2d.attach_new_node("squareRoot");
	for (int i = 0; i < num; ++i)
	{
		button[i] = new PGButton("Button");
		button[i]->setup("test");
		button_np = np_2d.attach_new_node(button[i]);
		button_np.set_pos(0.1 * i, 0.0, 0.1 * i);
	}
	framework.main_loop(); 
	framework.report_frame_rate(nout);
	return (0);
}

btw, i first encountered this problem when i loaded some (256) models.
the first button worked. the second button crashed the program.

hope this helps on locating the problem.

andreas