#include #include #include #include extern "C" { #include #include #include } #include #include #include #include "callbackhandeler.hpp" using namespace irr; using namespace gui; using namespace std; extern lua_State* L; std::map guielements; //For basic events //{guielement} void registerguielement(lua_State* L, gui::EGUI_EVENT_TYPE et, const char* funcname){ int ref = luaL_ref(L,LUA_REGISTRYINDEX);// lua_rawgeti(L,LUA_REGISTRYINDEX,ref);//{guielement} lua_getfield(L,-1,"guielement");//{guielement},ud_guielement IGUIElement* el = (IGUIElement*)lua_touserdata(L,-1);//{guielement},ud_guielement guielements[el] = ref; lua_pop(L,1);//{guielement} } GlobalEventReceiver::GlobalEventReceiver(IrrlichtDevice* d){ //device = d; } int callMouse(lua_State* L, const char* funcname, double x, double y, double event){ int consume = 0; assert(lua_gettop(L) == 0); lua_getglobal(L,"GAME");//GAME pusherrorfunc(L);//{GAME},errfun lua_getfield(L,-2,funcname);//{GAME},errfunc,funcname? if(!lua_isnil(L,-1)){ lua_pushnumber(L,x);//{GAME},errfunc,func,x lua_pushnumber(L,y);//{GAME},errfunc,func,x,y lua_pushnumber(L,event);//{GAME},errfunc,func,x,y,event int err = lua_pcall(L,3,1,-5);//{GAME},errfunc,consume|err if(err){ printf("Failed to call GAME.%s\n",funcname); }else{ if(!lua_isnil(L,-1)){ consume = lua_toboolean(L,-1); } } lua_pop(L,3); assert(lua_gettop(L) == 0); }else{ //{GAME},errfunc,nil lua_pop(L,3);// assert(lua_gettop(L) == 0); } assert(lua_gettop(L) == 0); return consume; } bool GlobalEventReceiver::OnEvent(const SEvent& e){ //printf("Onevent triggered when top was %d\n", lua_gettop(L)); assert(lua_gettop(L) == 0); //lua_State* L = this->L; EEVENT_TYPE type = e.EventType; SEvent::SMouseInput se = e.MouseInput; //printf("Onevent called:%d\n",(int)type); switch (type){ case EET_GUI_EVENT:{ //printf("Gui event\n"); IGUIElement* caller = e.GUIEvent.Caller; EGUI_EVENT_TYPE get = e.GUIEvent.EventType; printf("detected gui event: %d\n",get); if(guielements.find(caller) == guielements.end()) return false; int ref = guielements[caller]; printf("About to get gui element\n"); lua_rawgeti(L,LUA_REGISTRYINDEX,ref);//{guielement} printf("done getting gui element\n"); const char* fieldname; switch(get){ /*** (Callback)Called when an @{iguiwindow} is focused If the function returns true, the element will not be focused. @function iguiwindow:onFocus() */ case EGET_ELEMENT_FOCUSED: fieldname = "onFocus"; break; /*** (Callback)Called when an @{iguiwindow} is unfocused If the function returns true, the element will not be unfocused. @function iguiwindow:onUnfocus() */ case EGET_ELEMENT_FOCUS_LOST: fieldname = "onUnfocus"; break; /*** (Callback)Called when an @{iguielement is hovered over with the mouse. If an element has child elements, you also get this call for each child element. @function iguielement:onHover() */ case EGET_ELEMENT_HOVERED: fieldname = "onHover"; break; case EGET_ELEMENT_LEFT: fieldname = "onLeave"; break; case EGET_ELEMENT_CLOSED: fieldname = "onClose"; break; case EGET_BUTTON_CLICKED: fieldname = "onClick"; break; case EGET_SCROLL_BAR_CHANGED: fieldname = "onScroll"; break; case EGET_CHECKBOX_CHANGED: fieldname = "onCheck"; break; case EGET_LISTBOX_CHANGED: fieldname = "onChange"; break; case EGET_LISTBOX_SELECTED_AGAIN: fieldname = "onSame"; break; case EGET_FILE_SELECTED: fieldname = "onFileSelect"; break; case EGET_DIRECTORY_SELECTED: fieldname = "onDirectorySelect"; break; case EGET_FILE_CHOOSE_DIALOG_CANCELLED: fieldname = "onCanceled"; break; case EGET_MESSAGEBOX_YES: fieldname = "onYes"; break; case EGET_MESSAGEBOX_NO: fieldname = "onNo"; break; case EGET_MESSAGEBOX_OK: fieldname = "onOk"; break; case EGET_MESSAGEBOX_CANCEL: fieldname = "onCancel"; break; case EGET_EDITBOX_ENTER: fieldname = "onEnter"; break; case EGET_EDITBOX_CHANGED: fieldname = "onChange"; break; case EGET_EDITBOX_MARKING_CHANGED: fieldname = "onMarkChange"; break; case EGET_TAB_CHANGED: fieldname = "onTabChange"; break; case EGET_MENU_ITEM_SELECTED: fieldname = "onSelect"; break; case EGET_COMBO_BOX_CHANGED: fieldname = "onChange"; break; case EGET_SPINBOX_CHANGED: fieldname = "onChange"; break; case EGET_TABLE_CHANGED: fieldname = "onChange"; break; case EGET_TABLE_HEADER_CHANGED: fieldname = "onHeadersChange"; break; case EGET_TABLE_SELECTED_AGAIN: fieldname = "onReselect"; break; case EGET_TREEVIEW_NODE_DESELECT: fieldname = "onNodeDeselect"; break; case EGET_TREEVIEW_NODE_SELECT: fieldname = "onNodeSelect"; break; case EGET_TREEVIEW_NODE_EXPAND: fieldname = "onNodeExpand"; break; case EGET_TREEVIEW_NODE_COLLAPSE: fieldname = "onNodeCollapse"; break; case EGET_COUNT: break; } printf("About to push error func"); pusherrorfunc(L);//{guielement},errfunc() lua_getfield(L,-2,fieldname);//{guielement},errfunc(),(func() | nil) if(lua_isnil(L,-1)){ printf("Element did not have a function %s, returning\n",fieldname); lua_pop(L,3);// assert(lua_gettop(L) == 0); return false; } lua_rawgeti(L,LUA_REGISTRYINDEX,ref);//{guielement},errfunc(),func(),{guielement} printf("About to pcall in callback.cpp!\n"); lua_pcall(L,1,1,-3);//{guielement},errfunc(),(nil|true) if(!lua_isnil(L,-1)){ printf("Got an argument back!\n"); int ans = lua_toboolean(L,-1); lua_pop(L,3); assert(lua_gettop(L) == 0); return ans; } lua_pop(L,3);// assert(lua_gettop(L) == 0); return false; } break; case EET_MOUSE_INPUT_EVENT:{ //printf("Mouse event - X: %d Y: %d\n",se.X, se.Y); /*** (Callback)Detects mouse movement. Detects when the mouse moves across the game. @function GAME.onMouseMove(x,y,event) @tparam number x The key that the user pressed down @tparam boolean down Was the key pressed down? @tparam boolean pressed_ctrl Was control pressed? @tparam boolean pressed_shift Was shift pressed? */ switch(se.Event){ case EMIE_MOUSE_MOVED:{ /*** (Callback)Detects mouse movement Called whenever the mouse is moved @function GAME.onMouseMove(x,y,button) @tparam number x The x position that the mouse now occupies @tparam number y The y position that the mouse now occupies @tparam number button Will be EMIE_MOUSE_MOVED. */ return callMouse(L,"onMouseMove",se.X,se.Y,se.Event); } break; case EMIE_LMOUSE_PRESSED_DOWN: case EMIE_RMOUSE_PRESSED_DOWN: case EMIE_MMOUSE_PRESSED_DOWN:{ printf("Mouse down\n"); /*** (Callback)Detects mouse presses. Called whenever the a mouse button has been pressed @function GAME.onMouseDown(x,y,button) @tparam number x The x position of the mouse @tparam number y The y position of the mouse @tparam number button Which mouse button was pressed. Will be one of: EMIE_LMOUSE_PRESSED_DOWN, EMIE_RMOUSE_PRESSED_DOWN, or EMIE_MMOUSE_PRESSED_DOWN */ return callMouse(L,"onMouseDown",se.X,se.Y,se.Event); } break; case EMIE_LMOUSE_LEFT_UP: case EMIE_RMOUSE_LEFT_UP: case EMIE_MMOUSE_LEFT_UP:{ /*** (Callback)Detects mouse presses. Detects when the mouse has been released. @function GAME.onMouseUp(x,y,button) @tparam number x The x position of the mouse on the screen (in pixels) @tparam number y The y position of the mouse @tparam number button The mouse key that was clicked, will be one of: EMIE_LMOUSE_LEFT_UP, EMIE_RMOUSE_LEFT_UP, or EMIE_MMOUSE_LEFT_UP. */ return callMouse(L,"onMouseUp",se.X,se.Y,se.Event); } break; case EMIE_MOUSE_WHEEL:{ /*** (Callback)Detects mouse scroll wheel. Triggered whenever the scroll wheel moves up or down. @function GAME.onMouseWheel(x,y,direction) @tparam number x The x position of the mouse @tparam number y The y position of the mouse @tparam number direction The direction of the scroll wheel, -1, 0 or 1 */ return callMouse(L,"onMouseWheel",se.X,se.Y,se.Wheel); } break; case EMIE_RMOUSE_DOUBLE_CLICK: case EMIE_MMOUSE_DOUBLE_CLICK: case EMIE_LMOUSE_DOUBLE_CLICK:{ /*** (Callback)Detects double clicking. Tirggered whenever the user double clicked in the screen. The speed for double clicking is system defined, and may not be the same across platforms. @function GAME.onDoubleClick(x,y,button) @tparam number x The x position of the mouse @tparam number y The y position of the mouse @tparam number button Which button was double clicked. Will be one of: EMIE_RMOUSE_DOUBLE_CLICK, EMIE_LMOUSE_DOUBLE_CLICK, or EMIE_MMOUSE_DOUBLE_CLICK */ return callMouse(L,"onDoubleClick",se.X,se.Y,se.Event); } break; case EMIE_RMOUSE_TRIPLE_CLICK: case EMIE_MMOUSE_TRIPLE_CLICK: case EMIE_LMOUSE_TRIPLE_CLICK:{ /*** (Callback)Detects triple clicking. Triggered whenever the user tripple clicks on the screen. The speed for tripple clicking is system defined, and may not be the same across platforms. @function GAME.onTripleClick(x,y,button) @tparam number x The x position of the mouse @tparam number y The y position of the mouse @tparam number button Which button was tripple clicked. Will be one of: EMIE_RMOUSE_TRIPLE_CLICK, EMIE_MMOUSE_TRIPLE_CLICK, EMIE_LMOUSE_TRIPLE_CLICK */ return callMouse(L,"onTripleClick",se.X,se.Y,se.Event); } break; case EMIE_COUNT:break; } return false; } break; /*** (Callback)Detects key presses. Detects any key presses from the game. @function GAME.onKeyDown(key,down,pressed_ctrl,pressed_shift) @tparam number key The key that the user pressed down @tparam boolean down Was the key pressed down? @tparam boolean pressed_ctrl Was control pressed? @tparam boolean pressed_shift Was shift pressed? */ case EET_KEY_INPUT_EVENT:{ //printf("Got input event\n"); SEvent::SKeyInput se = e.KeyInput; assert(lua_gettop(L) == 0); lua_getglobal(L,"GAME");//{} lua_getfield(L,-1,"onKeyDown");//{},()|nil if(!lua_isnil(L,-1)){ //printf("onKeyDown not nil, calling...\n"); pusherrorfunc(L);//GAME,GAME.onKeyDown(),errfunc lua_pushvalue(L,-2);//GAME,GAME.onKeyDown(),errfunc,onKeyDown() lua_pushnumber(L,se.Key);//{GAME},GAME.onKeyDown(),errfunc,onKeyDown(),key_number lua_pushboolean(L,se.PressedDown);//{GAME},GAME.onKeyDown(),errfunc,onKeyDown(),key_number,is_down lua_pushboolean(L,se.Control);//{GAME},GAME.onKeyDown(),errfunc,onKeyDown(),key_number,is_down,is_ctrl lua_pushboolean(L,se.Shift);//{GAME},GAME.onKeyDown(),errfunc,onKeyDown(),key_number,is_down,is_ctrl,is_shift lua_pcall(L,4,0,-6);//GAME,GAME.onKeyDown() } lua_pop(L,lua_gettop(L)); assert(lua_gettop(L) == 0); return false; break; } default:{ //printf("Called an unknown event\n"); return false; } } assert(lua_gettop(L) == 0); return true; }