wxString wxLuaCheckStack::DumpStack(const wxString& msg) { wxCHECK_MSG(m_luaState, wxEmptyString, wxT("Invalid lua_State")); lua_State* L = m_luaState; int i, count = lua_gettop(L); wxString str; wxString retStr; str.Printf(wxT("wxLuaCheckStack::DumpStack(L=%p), '%s':'%s', items %d, starting top %d\n"), L, m_msg.c_str(), msg.c_str(), count, m_top); retStr += str; OutputMsg(str); wxLuaState wxlState(L); for (i = 1; i <= count; i++) { int wxl_type = 0; wxString value; int l_type = wxLuaDebugData::GetTypeValue(L, i, &wxl_type, value); str.Printf(wxT(" idx %d: l_type = %d, wxl_type = %d : '%s'='%s'\n"), i, l_type, wxl_type, wxluaT_typename(L, wxl_type).c_str(), value.c_str()); retStr += str; OutputMsg(str); } return retStr; }
void wxLuaEventCallback::OnAllEvents(wxEvent& event) { wxEventType evtType = event.GetEventType(); // Get the wxLuaEventCallback instance to use which is NOT "this" since // "this" is a central event handler function. i.e. this != theCallback wxLuaEventCallback *theCallback = (wxLuaEventCallback *)event.m_callbackUserData; wxCHECK_RET(theCallback != NULL, wxT("Invalid wxLuaEventCallback in wxEvent user data")); if (theCallback != NULL) { // Not an error if !Ok(), the wxLuaState is cleared during shutdown or after a destroy event. wxLuaState wxlState(theCallback->GetwxLuaState()); if (wxlState.Ok()) { wxlState.SetInEventType(evtType); theCallback->OnEvent(&event); wxlState.SetInEventType(wxEVT_NULL); } } // we want the wxLuaWinDestroyCallback to get this too if (evtType == wxEVT_DESTROY) event.Skip(true); }
// %override wxLua_function_GetTrackedEventCallbackInfo // %function LuaTable GetTrackedEventCallbackInfo(bool as_string = false) static int LUACALL wxLua_function_GetTrackedEventCallbackInfo(lua_State *L) { wxLuaState wxlState(L); bool as_string = lua_toboolean(L, 1); // ok if nil if (as_string) wxlua_pushwxString(L, wxlua_concatwxArrayString(wxlState.GetTrackedEventCallbackInfo())); else wxlua_pushwxArrayStringtable(L, wxlState.GetTrackedEventCallbackInfo()); return 1; }
// %override wxLua_romloader_write_image static int LUACALL wxLua_romloader_write_image(lua_State *L) { int iLuaCallbackTag; wxLuaState wxlState(L); // voidptr_long vplCallbackUserData long vplCallbackUserData = (long)wxlua_getnumbertype(L, 5); // LuaFunction fnCallback if( lua_isfunction(L, 4) ) { // push function to top of stack lua_pushvalue(L, 4); // ref function and pop it from stack iLuaCallbackTag = luaL_ref(L, LUA_REGISTRYINDEX); } else { // no callback function provided wxlua_argerror(L, 4, wxT("a 'function'")); } // wxString strData wxString strData; size_t sizLen; const char *pcBuf; pcBuf = lua_tolstring(L, 3, &sizLen); if( sizLen==0 ) { strData = wxEmptyString; } else { strData = wxString::From8BitData(pcBuf, sizLen); } // unsigned long ulNetxAddress double dNetxAddress = wxlua_getnumbertype(L, 2); // get this romloader * self = (romloader *)wxluaT_getuserdatatype(L, 1, wxluatype_romloader); // call write_image self->write_image(dNetxAddress, strData, L, iLuaCallbackTag, (void*)vplCallbackUserData); // remove ref to function luaL_unref(L, LUA_REGISTRYINDEX, iLuaCallbackTag); return 0; }
// %override wxLua_romloader_read_image static int LUACALL wxLua_romloader_read_image(lua_State *L) { int iLuaCallbackTag; wxLuaState wxlState(L); wxString returns; // voidptr_long vplCallbackUserData long vplCallbackUserData = (long)wxlua_getnumbertype(L, 5); // LuaFunction fnCallback if( lua_isfunction(L, 4) ) { // push function to top of stack lua_pushvalue(L, 4); // ref function and pop it from stack iLuaCallbackTag = luaL_ref(L, LUA_REGISTRYINDEX); } else { // no callback function provided wxlua_argerror(L, 4, wxT("a 'function'")); } // unsigned long ulSize double dSize = wxlua_getnumbertype(L, 3); // unsigned long ulNetxAddress double dNetxAddress = wxlua_getnumbertype(L, 2); // get this romloader * self = (romloader *)wxluaT_getuserdatatype(L, 1, wxluatype_romloader); // call read_image returns = (self->read_image(dNetxAddress, dSize, L, iLuaCallbackTag, (void*)vplCallbackUserData)); // remove ref to function luaL_unref(L, LUA_REGISTRYINDEX, iLuaCallbackTag); // push the result string wxlState.lua_PushLString(returns.fn_str(),returns.Len()); return 1; }
wxString wxLuaCheckStack::DumpTable(int stack_idx, const wxString& tablename, const wxString& msg, wxSortedArrayString& tableArray, int indent) { wxCHECK_MSG(m_luaState, wxEmptyString, wxT("Invalid lua_State")); lua_State* L = m_luaState; wxLuaState wxlState(L); wxString indentStr; wxString s; // We only do tables, return error message if (!lua_istable(L, stack_idx)) { s.Printf(wxT("wxLuaCheckStack::DumpTable(L=%p) stack idx %d is not a table.\n"), L, stack_idx); OutputMsg(s); return s; } if (indent == 0) { // First time through print header s.Printf(wxT("wxLuaCheckStack::DumpTable(L=%p) Table: '%s'\n"), L, tablename.c_str()); OutputMsg(s); } else if (indent > 10) { // Don't let things get out of hand... s.Printf(wxT("wxLuaCheckStack::DumpTable(L=%p) Table depth > 10! Truncating: '%s'\n"), L, tablename.c_str()); OutputMsg(s); return s; } else { indentStr = wxString(wxT(' '), indent*2) + wxT(">"); } wxString title = wxString::Format(wxT("%sTable Level %d : name '%s'\n"), indentStr.c_str(), indent, tablename.c_str()); s += title; OutputMsg(title); lua_pushvalue(L, stack_idx); // push the table to read the top of the stack lua_pushnil(L); while (lua_next(L, -2) != 0) { int keyType = 0, valueType = 0; wxString key, value; wxLuaDebugData::GetTypeValue(L, -2, &keyType, key); wxLuaDebugData::GetTypeValue(L, -1, &valueType, value); wxString info = wxString::Format(wxT("%s%-32s\t%-16s\t%-20s\t%-16s\n"), indentStr.c_str(), key.c_str(), wxluaT_typename(L, keyType).c_str(), value.c_str(), wxluaT_typename(L, valueType).c_str()); s += info; OutputMsg(info); if (tableArray.Index(value) == wxNOT_FOUND) { if (valueType == WXLUA_TTABLE) { tableArray.Add(value); s += DumpTable(lua_gettop(L), tablename + wxT(".") + key, msg, tableArray, indent+1); } else { tableArray.Add(value); } } lua_pop(L, 1); // pop value } lua_pop(L, 1); // pop pushed table return s; }
void wxLuaEventCallback::OnEvent(wxEvent *event) { static wxClassInfo* wxSpinEvent_ClassInfo = wxClassInfo::FindClass(wxT("wxSpinEvent")); static wxClassInfo* wxScrollEvent_ClassInfo = wxClassInfo::FindClass(wxT("wxScrollEvent")); // Cannot call it if Lua is gone or the interpreter has been destroyed // This can happen when the program exits since windows may be destroyed // after Lua has been deleted. if (!m_wxlState.Ok()) return; // ref the state in case this generates a wxEVT_DESTROY which clears us wxLuaState wxlState(m_wxlState); // initialize to the generic wxluatype_wxEvent int event_wxl_type = *p_wxluatype_wxEvent; // inits to wxluatype_TUNKNOWN == WXLUA_TUNKNOWN // If !m_wxlBindEvent, we would have errored in Connect(), but don't crash... if (m_wxlBindEvent != NULL) { event_wxl_type = *m_wxlBindEvent->wxluatype; // These wxEventTypes can be wxScrollEvents or wxSpinEvents - FIXME could this be cleaner? // wxEVT_SCROLL_LINEUP, wxEVT_SCROLL_LINEDOWN, wxEVT_SCROLL_THUMBTRACK if ((*m_wxlBindEvent->wxluatype == *p_wxluatype_wxScrollEvent) && event->GetClassInfo()->IsKindOf(wxSpinEvent_ClassInfo)) { if (*p_wxluatype_wxSpinEvent != WXLUA_TUNKNOWN) event_wxl_type = *p_wxluatype_wxSpinEvent; else event_wxl_type = *p_wxluatype_wxEvent; // get the generic wxluatype_wxEvent } else if ((*m_wxlBindEvent->wxluatype == *p_wxluatype_wxSpinEvent) && event->GetClassInfo()->IsKindOf(wxScrollEvent_ClassInfo)) { if (*p_wxluatype_wxScrollEvent != WXLUA_TUNKNOWN) event_wxl_type = *p_wxluatype_wxScrollEvent; else event_wxl_type = *p_wxluatype_wxEvent; // get the generic wxluatype_wxEvent } } // Should know our event type, but error out in case we don't wxCHECK_RET(event_wxl_type != WXLUA_TUNKNOWN, wxT("Unknown wxEvent wxLua tag for : ") + wxString(event->GetClassInfo()->GetClassName())); wxlState.lua_CheckStack(LUA_MINSTACK); int oldTop = wxlState.lua_GetTop(); if (wxlState.wxluaR_GetRef(m_luafunc_ref, &wxlua_lreg_refs_key)) { #if LUA_VERSION_NUM < 502 // lua_setfenv() is not in Lua 5.2 nor can you set an env for a function anymore wxlState.GetGlobals(); if (wxlState.lua_SetFenv(-2) != 0) #endif // LUA_VERSION_NUM < 502 { // Don't track the wxEvent since we don't own it and tracking it // causes clashes in the object registry table since many can be // created and deleted and the mem address is resused by C++. wxlState.wxluaT_PushUserDataType(event, event_wxl_type, false); wxlState.LuaPCall(1, 0); // one input no returns } #if LUA_VERSION_NUM < 502 else wxlState.wxlua_Error("wxLua: wxEvtHandler::Connect() in wxLuaEventCallback::OnEvent(), callback function is not a Lua function."); #endif // LUA_VERSION_NUM < 502 } else wxlState.wxlua_Error("wxLua: wxEvtHandler::Connect() in wxLuaEventCallback::OnEvent(), callback function to call is not refed."); wxlState.lua_SetTop(oldTop); // pop function and error message from the stack (if they're there) }