I think there is a bug in tolua regarding unions. If you have a declaration like this:
struct SDL_WindowEvent {
int type;
int windowID;
};
union SDL_Event {
int type;
SDL_WindowEvent window;
};
extern SDL_Event * create(void);
extern void frobnicate(SDL_Event *);
then it should be okay to have lua code like this:
event = create()
frobnicate(event)
print(event.window.windowId)
frobnicate(event)
But the second call to frobnicate(event) will fail with an error:
argument #1 is 'SDL_WindowEvent'; 'SDL_Event' expected.
A little poking at the debugger reveals that a tolua_pushusertype in the event.window access rewrites the type of my variable!
Here's what I've tried so far: From my declaration, tolua will create the following call for declaring the SDL_WindowEvent class:
tolua_cclass(tolua_S,"SDL_WindowEvent","SDL_WindowEvent","",NULL);
thus making the SDL_Event and SDL_WindowEvent two unrelated classes, not base classes of each other. Let's say I have code later on that is equivalent to the following:
tolua_pushusertype(tolua_S, event, "SDL_Event");
assert(tolua_isusertype(tolua_S,1,"SDL_Event",0,&tolua_err));
tolua_pushusertype(tolua_S, event->window, "SDL_WindowEvent");
assert(tolua_isusertype(tolua_S,2,"SDL_Event",0,&tolua_err));
then the assert in the fourth line will fail, because the value on the stack has magically changed type since the assert in line two. This is because tolua_pushusertype() changes it - foo and foo.window have the same address, and internally, tolua only tracks one type per each address. tolua_isusertype() would have been satisfied if the object had been of base type SDL_Event, but that would require the tolua_cclass declaration above to have a "SDL_Event" as its fourth argument. When I manually fix that, both asserts pass, but I can't manually change that each time - I would like to fix tolua to do this, but I don't
understand it well enough yet to do that. I don't even know if that would be the right thing to do.
I'm using tolua 5.1.4, but the same problem occurs with tolua++ 1.92.3.
Is there something I am doing wrong, first of all? Is there a way I can rewrite my declaration to have this work with tolua as-is? Or, failing that, a fix I can apply to tolua that makes this work?