Hi,
I'm trying to use Agar from C++, and am having trouble getting event
callbacks,
like those initiated by AG_Button click events, to call a class method
properly.
The following 4 code files are my attempt at wrapping the Agar GUI elements,
using the Boost library to set up the C-style callback to a class method:
::::::::::::::
guiwin.h
::::::::::::::
#include <agar/core.h>
#include <agar/core/snprintf.h>
#include <agar/gui.h>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef GUIWIN_H
#define GUIWIN_H
class Guiwin {
public:
void init (void);
void dump_content (void);
private:
AG_Window *win_;
AG_Textbox *sltb_;
typedef boost::function<void(AG_Event*)> AG_callback;
static AG_callback click_callback;
static void doClickDefFunc(AG_callback func) { click_callback =
func; }
static void doClick(AG_Event *event) { click_callback(event); }
void clickHandler(AG_Event *event);
};
#endif
::::::::::::::
guiwin.cpp
::::::::::::::
#include "guiwin.h"
// initialize static function pointer
Guiwin::AG_callback Guiwin::click_callback = 0;
void Guiwin::init (void) {
// set up dynamic function pointer for event
Guiwin::doClickDefFunc(boost::bind(&Guiwin::clickHandler, *this, _1));
AG_Button *submit;
win_ = AG_WindowNew(0);
AG_WindowSetCaption(win_, "Single-line Example");
sltb_ = AG_TextboxNew(win_, 0, "Static string: ");
AG_TextboxSizeHint(sltb_, "XXXXXXXXXXX");
AG_TextboxPrintf(sltb_, "Hello");
AG_WidgetFocus(sltb_);
submit = AG_ButtonNewFn(win_, 0, "Click me", doClick, NULL);
AG_WindowSetPosition(win_, AG_WINDOW_MIDDLE_LEFT, 0);
AG_WindowShow(win_);
}
void Guiwin::clickHandler (AG_Event *event) {
// the AG_TextboxDupString() call generates a segmentation fault
printf("text is: %s\n", AG_TextboxDupString(sltb_));
}
::::::::::::::
main.cpp
::::::::::::::
#include "guiwin.h"
int main(int argc, char *argv[]) {
if (AG_InitCore("agar-textbox-demo", 0) == -1) {
fprintf(stderr, "%s\n", AG_GetError());
return (1);
}
if (AG_InitVideo(640, 480, 32, AG_VIDEO_RESIZABLE) == -1) {
fprintf(stderr, "%s\n", AG_GetError());
return (-1);
}
Guiwin testwin;
testwin.init();
AG_BindGlobalKey(SDLK_ESCAPE, KMOD_NONE, AG_Quit);
AG_EventLoop();
AG_Destroy();
return (0);
}
::::::::::::::
Makefile
::::::::::::::
all:
g++ -I/usr/include/agar -I/usr/include/SDL -I/usr/include/freetype2 \
-lag_core -lag_gui -lSDL -lfreetype -ljpeg guiwin.cpp main.cpp \
-o main.exe
I'm using Agar version 1.3.3 on an Ubuntu box with g++. Compiles fine, but
when I click the button in the running program, I get a segfault. The
corefile
gives me the following backtrace:
Core was generated by `./main.exe'.
Program terminated with signal 11, Segmentation fault.
[New process 21397]
#0 0x00000000004017ca in Guiwin::clickHandler ()
(gdb) bt
#0 0x00000000004017ca in Guiwin::clickHandler ()
#1 0x0000000000401f68 in boost::_mfi::mf1<void, Guiwin,
ag_event*>::operator() ()
#2 0x0000000000402011 in boost::_bi::list2<boost::_bi::value<Guiwin>,
boost::arg<1> (*)()>::operator()<boost::_mfi::mf1<void, Guiwin, ag_event*>,
boost::_bi::list1<ag_event*&> > ()
#3 0x0000000000402058 in boost::_bi::bind_t<void, boost::_mfi::mf1<void,
Guiwin, ag_event*>, boost::_bi::list2<boost::_bi::value<Guiwin>,
boost::arg<1> (*)()> >::operator()<ag_event*> ()
#4 0x0000000000402082 in
boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void,
boost::_mfi::mf1<void, Guiwin, ag_event*>,
boost::_bi::list2<boost::_bi::value<Guiwin>, boost::arg<1> (*)()> >, void,
ag_event*>::invoke ()
#5 0x0000000000402902 in boost::function1<void, ag_event*,
std::allocator<void> >::operator() ()
#6 0x0000000000402924 in Guiwin::doClick ()
#7 0x00007f072bbdfe12 in AG_PostEvent () from /usr/lib/libag_core.so.1
#8 0x00007f072b922d88 in mousebuttonup () from /usr/lib/libag_gui.so.1
#9 0x00007f072bbdfe12 in AG_PostEvent () from /usr/lib/libag_core.so.1
#10 0x00007f072b906a6d in AG_WidgetMouseButtonUp () from
/usr/lib/libag_gui.so.1
#11 0x00007f072b90a796 in AG_WindowEvent () from /usr/lib/libag_gui.so.1
#12 0x00007f072b902295 in AG_ProcessEvent () from /usr/lib/libag_gui.so.1
#13 0x00007f072b902015 in AG_EventLoop_FixedFPS () from
/usr/lib/libag_gui.so.1
#14 0x00000000004029e3 in main ()
Current language: auto; currently asm
(gdb)
(Do I need to compile Boost with debugging symbols to get useful info
from this backtrace?)
I'm not super-experienced with C, C++, or Boost for that matter. If anyone
could
spot how I'm doing this incorrectly, knows how to wrap Agar callbacks for
use in
C++, or could point me toward the right direction, it'd be greatly
appreciated.
Also, if there's any word on progress for the C++ wrapper classes for Agar,
I'd be
very interested to hear about it.
Thanks,
Ocamler
_______________________________________________
Agar mailing list
[email protected]
http://libagar.org/lists.html