wxString wxLuaEventCallback::Connect(const wxLuaState& wxlState, int lua_func_stack_idx, wxWindowID win_id, wxWindowID last_id, wxEventType eventType, wxEvtHandler *evtHandler) { // Assert too since these errors are serious and not just bad Lua code. wxCHECK_MSG(evtHandler != NULL, wxT("Invalid wxEvtHandler in wxLuaEventCallback::Connect()"), wxT("Invalid wxEvtHandler in wxLuaEventCallback::Connect()")); wxCHECK_MSG((m_evtHandler == NULL) && (m_luafunc_ref == 0), wxT("Attempting to reconnect a wxLuaEventCallback"), wxT("Attempting to reconnect a wxLuaEventCallback")); wxCHECK_MSG(wxlState.Ok(), wxT("Invalid wxLuaState"), wxT("Invalid wxLuaState")); // NOTE: See below about how we use the root lua_State to avoid these problems. // We must always be installed into the main lua_State, never a coroutine // 1) It will be called only when the lua_State is suspended or dead // 2) We have no way of tracking when the coroutine state is garbage collected/dead //if (lua_pushthread(wxlState.GetLuaState()) != 1) //{ // wxlState.lua_Pop(1); // return wxT("wxLua: Creating a callback function in a coroutine is not allowed since it will only be called when the thread is either suspended or dead."); //} //wxlState.lua_Pop(1); m_wxlState = wxlState; m_evtHandler = evtHandler; m_id = win_id; m_last_id = last_id; // NOTE: FIXME? We look for the wxLuaBindEvent in all of the bindings, but it // may not have actually been installed if someone had modified the bindings. // It should be ok since it will error out soon enough without crashing. m_wxlBindEvent = wxLuaBinding::FindBindEvent(eventType); // Do not install this invalid or unknown event type since we won't know // what wxEvent type class to use and someone probably made a mistake. if (m_wxlBindEvent == NULL) { return wxString::Format(wxT("wxLua: Invalid or unknown wxEventType %d for wxEvtHandler::Connect(). winIds %d, %d."), (int)eventType, win_id, last_id); } m_wxlState.AddTrackedEventCallback(this); // create a reference to the Lua event handler function if (lua_func_stack_idx != WXLUAEVENTCALLBACK_NOROUTINE) m_luafunc_ref = m_wxlState.wxluaR_Ref(lua_func_stack_idx, &wxlua_lreg_refs_key); // Note: We use the callback userdata and not the event sink since the event sink // requires a wxEvtHandler object which is a fairly large class. // The userdata (i.e. this) is also deleted for us which makes our life easier. m_evtHandler->Connect(win_id, last_id, eventType, (wxObjectEventFunction)&wxLuaEventCallback::OnAllEvents, this); // We always must run the function in the main lua_State. // See above about the problems not doing so... // Note saving the main lua_State to use in the callback may not always work // and if a problem is found we need to resort to blocking connecting event // handlers in coroutines as was done before. m_wxlState = wxLuaState(wxlState.GetLuaState(), wxLUASTATE_GETSTATE|wxLUASTATE_ROOTSTATE); return wxEmptyString; }
int wxLuaFreezeApp::OnExit() { if (m_wxlState.Ok()) m_wxlState.CloseLuaState(true); return wxApp::OnExit(); }
void wxLuaConsole::DisplayStack(const wxLuaState& wxlState) { wxCHECK_RET(wxlState.Ok(), wxT("Invalid wxLuaState")); int nIndex = 0; lua_Debug luaDebug = INIT_LUA_DEBUG; wxString buffer; lua_State* L = wxlState.GetLuaState(); while (lua_getstack(L, nIndex, &luaDebug) != 0) { if (lua_getinfo(L, "Sln", &luaDebug)) { wxString what (luaDebug.what ? lua2wx(luaDebug.what) : wxString(wxT("?"))); wxString nameWhat(luaDebug.namewhat ? lua2wx(luaDebug.namewhat) : wxString(wxT("?"))); wxString name (luaDebug.name ? lua2wx(luaDebug.name) : wxString(wxT("?"))); buffer += wxString::Format(wxT("[%d] %s '%s' '%s' (line %d)\n Line %d src='%s'\n"), nIndex, what.c_str(), nameWhat.c_str(), name.c_str(), luaDebug.linedefined, luaDebug.currentline, lua2wx(luaDebug.short_src).c_str()); } nIndex++; } if (!buffer.empty()) { AppendText(wxT("\n-----------------------------------------------------------") wxT("\n- Backtrace") wxT("\n-----------------------------------------------------------\n") + buffer + wxT("\n-----------------------------------------------------------\n\n")); } }
void wxLuaConsole::DisplayStack(const wxLuaState& wxlState) { wxCHECK_RET(wxlState.Ok(), wxT("Invalid wxLuaState")); int nIndex = 0; lua_Debug luaDebug; wxString buffer; m_debugListBox->Clear(); lua_State* L = wxlState.GetLuaState(); while (lua_getstack(L, nIndex, &luaDebug) != 0) { buffer.Empty(); if (lua_getinfo(L, "Sln", &luaDebug)) { int lineNumber = luaDebug.currentline; if (lineNumber == -1) { if (luaDebug.name != NULL) buffer.Printf(wxT("function %s"), lua2wx(luaDebug.name).c_str()); else buffer.Printf(wxT("{global}")); } else { if (luaDebug.name != NULL) buffer.Printf(wxT("function %s line %d"), lua2wx(luaDebug.name).c_str(), lineNumber); else buffer.Printf(wxT("{global} line %d"), lineNumber); } // skip over ourselves on the stack if (nIndex > 0) m_debugListBox->Append(buffer, (void *)(long) nIndex); } nIndex++; } // only show the listbox if it has anything in it if (m_debugListBox->GetCount() && !m_splitter->IsSplit()) { m_splitter->SplitHorizontally( m_textCtrl, m_debugListBox, 150); m_splitter->SetMinimumPaneSize(50); } }
bool HandlrApp::OnInit() { #ifdef __WXGTK__ setlocale(LC_NUMERIC, "C"); #endif wxString logDir; #ifdef H_PORTABLE logDir = wxStandardPaths::Get().GetLocalDataDir(); #else logDir = wxStandardPaths::Get().GetUserDataDir(); #endif #ifndef H_DEBUG wxString logPath = logDir + wxFileName::GetPathSeparator() + _T("handlr.log"); FILE* logFile = fopen (logPath.mb_str(), "a"); wxLogStderr* logger = new wxLogStderr (logFile); wxLog::SetActiveTarget (logger); #endif wxInitAllImageHandlers(); WXLUA_IMPLEMENT_BIND_STD wxLuaState::sm_wxAppMainLoop_will_run = true; m_wxlState = wxLuaState(this, wxID_ANY); if (!m_wxlState.Ok()) return false; m_wxlState.lua_PushString(logDir.mb_str()); m_wxlState.lua_SetGlobal("H_DIR"); #include "handlr.h" wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); if (node) return true; return false; }
bool wxLuaBinding_wxlua::RegisterBinding(const wxLuaState& wxlState) { bool ret = wxLuaBinding::RegisterBinding(wxlState); lua_State* L = wxlState.GetLuaState(); lua_pushlstring(L, "NULL", 4); wxluaT_pushuserdatatype(L, NULL, wxluatype_NULL, true, true); lua_rawset(L, -3); // set t["NULL"] = userdata(NULL) w/ NULL tag return ret; }
bool wxLuaFreezeApp::OnInit() { #ifdef __WXGTK__ // this call is very important since otherwise scripts using the decimal // point '.' could not work with those locales which use a different symbol // (e.g. the comma) for the decimal point... // It doesn't work to put os.setlocale('c', 'numeric') in the Lua file that // you want to use decimal points in. That's because the file has been lexed // and compiler before the locale has changed, so the lexer - the part that // recognises numbers - will use the old locale. setlocale(LC_NUMERIC, "C"); #endif // load all image handlers for the wxLua script to make things easy wxInitAllImageHandlers(); // Initialize the wxLua bindings we want to use. // See notes for WXLUA_DECLARE_BIND_ALL above. WXLUA_IMPLEMENT_BIND_ALL m_fileName = argv[0]; // the filename of 'this' program // When this function returns wxApp:MainLoop() will be called by wxWidgets // and so we want the Lua code wx.wxGetApp:MailLoop() to not // prematurely start it. wxLuaState::sm_wxAppMainLoop_will_run = true; m_wxlState = wxLuaState(this, wxID_ANY); if (!m_wxlState.Ok()) return false; // if no script attached try to run a the program on the command line if (LoadScript(m_fileName, true) == LOADSCRIPT_MISSING) { if (argc > 1) { wxlua_pushargs(m_wxlState.GetLuaState(), argv, argc, 1); // just run it, lua gives a nice error message on failure m_wxlState.RunFile(argv[1]); } else { OutputPrint(wxString::Format(wxT("Expecting '<wxLuaFreeze:[script length]>' at end of '%s'.\n") wxT("Did you forget to run wxluafreeze.lua to attach your script?\n") wxT("You may run wxLua programs by specifying them on the command line."), m_fileName.c_str())); } } else { // now load our script to run that should have been appended to this file // by wxluafreeze.lua wxString script = LoadScript(m_fileName); if (!script.IsEmpty()) { wxlua_pushargs(m_wxlState.GetLuaState(), argv, argc, 0); m_wxlState.RunString(script); } } // no matter what - try to see any toplevel windows exist, if not then // there's no way to exit so assume that the program is all done wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); if (node) return true; return false; }
int HandlrApp::OnExit() { if (m_wxlState.Ok()) m_wxlState.CloseLuaState(true); return wxApp::OnExit(); }