1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wxlstate.cpp
3 // Purpose:     wxLuaState, a wxWidgets interface to Lua
4 // Author:      Ray Gilbert, John Labenski, J Winwood (Reuben Thomas for bitlib at bottom)
5 // Created:     14/11/2001
6 // Copyright:   (c) 2012 John Labenski, 2001-2002 Lomtick Software. All rights reserved.
7 // Licence:     wxWidgets licence
8 /////////////////////////////////////////////////////////////////////////////
9 
10 // For compilers that support precompilation, includes "wx/wx.h"
11 #include <wx/wxprec.h>
12 
13 #ifdef __BORLANDC__
14     #pragma hdrstop
15 #endif
16 
17 // for all others, include the necessary headers
18 #ifndef WX_PRECOMP
19     #include <wx/wx.h>
20 #endif
21 
22 #include "wxlua/wxlstate.h"
23 #include "wxlua/wxlcallb.h"
24 #include <wx/tokenzr.h>
25 
26 //#include "wxluadebug/include/wxldebug.h" // for debugging only
27 
28 wxLuaState wxNullLuaState(false);
29 
30 extern "C"
31 {
32     // provided by bit.c (Lua BitOp)
33     int luaopen_bit(lua_State *L);
34 
35 #if (LUA_VERSION_NUM < 502)
36     // provided by lbitlib.c for 5.1 or we use the one in 5.2 or LuaJIT.
37     int luaopen_bit32 (lua_State *L);
38 #endif // (LUA_VERSION_NUM < 502)
39 }
40 
41 // ----------------------------------------------------------------------------
42 // C functions for Lua used in wxLuaState
43 // ----------------------------------------------------------------------------
44 
45 // The print function that we push into Lua replacing "print(...)"
46 // to generate wxLuaEvent(wxEVT_LUA_PRINT, ...)
47 // Code copied from Lua's luaB_print() function in lbaselib.c
wxlua_printFunction(lua_State * L)48 int LUACALL wxlua_printFunction( lua_State *L )
49 {
50     wxLuaState wxlState(L); // doesn't have to be ok
51 
52     // If the wxLuaState is not going to print, we'll let Lua print normally
53     if (!wxlState.Ok() || (wxlState.GetEventHandler() == NULL) ||
54         (!wxApp::IsMainLoopRunning() && !wxlState.sm_wxAppMainLoop_will_run))
55     {
56         // Get our saved copy of the Lua's print function from the registry
57         lua_pushlstring(L, "print_lua", 9);
58         lua_rawget( L, LUA_REGISTRYINDEX ); // pop key, push print function
59 
60         // LuaJIT's print() is not a lua_CFunction and it is more flexible to
61         // simply lua_call() whatever was saved when wxLua was loaded.
62         //lua_CFunction lua_print = lua_tocfunction(L, -1);
63         //lua_pop(L, 1);                      // pop the print function
64         //return lua_print(L);
65         lua_insert(L, 1);
66         lua_call(L, lua_gettop(L)-1, 0);
67         return 0;
68     }
69 
70     // The wxLuaState can print by sending an event
71     wxString msg;
72     int i, n = lua_gettop(L);
73 
74     // Use the Lua tostring() function to print them as Lua would
75     lua_getglobal(L, "tostring");
76 
77     if (!lua_isfunction(L, -1))
78     {
79         // This code is also used in wxledit.cpp, wxLuaShell::RunString()
80         msg = wxT("wxLua ERROR: Unable to print() without the tostring() function. Did you remove it?");
81         lua_pop(L, 1);  // pop the nil or whatever replaced tostring()
82         n = 0;          // don't let for loop run
83     }
84 
85     for (i = 1; i <= n; ++i)
86     {
87         const char *s;
88         lua_pushvalue(L, -1);       /* function to be called */
89         lua_pushvalue(L, i);        /* value to print */
90         lua_call(L, 1, 1);
91         s = lua_tostring(L, -1);    /* get result */
92         if (s == NULL)
93         {
94             return luaL_error(L, "'tostring' must return a string to 'print'");
95         }
96 
97         if (i > 1) msg.Append(wxT("\t")); // Lua uses a tab in luaB_print
98         msg += lua2wx(s);
99 
100         lua_pop(L, 1);  /* pop result */
101     }
102 
103     if (!msg.IsEmpty())
104     {
105         wxLuaEvent event(wxEVT_LUA_PRINT, wxlState.GetId(), wxlState);
106         event.SetString(msg);
107         wxlState.SendEvent(event);
108     }
109     //else if (!msg.IsEmpty())
110     //    wxPrintf(wxT("%s\n"), msg.c_str()); // Lua puts a \n too
111 
112     return 0; // no items put onto stack
113 }
114 
wxlua_debugHookFunction(lua_State * L,lua_Debug * LDebug)115 void LUACALL wxlua_debugHookFunction(lua_State *L, lua_Debug *LDebug)
116 {
117     // NULL when shutting down.
118     wxLuaStateData* wxlStateData = wxlua_getwxluastatedata(L);
119     if (!wxlStateData) return;
120 
121     // FIXME - for select event types we don't want to do anything
122     wxEventType evtType = wxlua_getwxeventtype(L);
123     if ((evtType != wxEVT_NULL))
124         //(evtType == wxEVT_IDLE) && (evtType == wxEVT_PAINT) &&
125         //(evtType == wxEVT_DESTROY) && (evtType == wxEVT_CLOSE_WINDOW))
126         return;
127 
128     // they want to break the program, restore old debug hook, then error out
129     if (wxlStateData->m_debug_hook_break)
130     {
131         // It's ok that we get the wxLuaState here since we're stopping anyway.
132         wxLuaState wxlState(L);
133 
134         // restore hook to previous state
135         wxlState.ClearDebugHookBreak();
136         wxlua_error(L, wxlStateData->m_debug_hook_break_msg.c_str());
137         return;
138     }
139 
140     // We use wxLuaState::SendEvent() because it sets wxEvent::SetEventObject() for us.
141     if (wxlStateData->m_lua_debug_hook_send_evt && wxlStateData->m_evtHandler)
142     {
143         wxLuaState wxlState(L);
144 
145         lua_getinfo(L, "l", LDebug); // line (ldebug.currentline)
146 
147         wxLuaEvent event(wxEVT_LUA_DEBUG_HOOK, wxlState.GetId(), wxlState);
148         event.m_lua_Debug = LDebug;
149         event.SetInt(LDebug->currentline);
150         wxlState.SendEvent( event );
151         if (event.m_debug_hook_break)
152             wxlState.wxlua_Error("Lua interpreter stopped.");
153     }
154 
155     // Try to yield *after* sending event to allow C++ gui update
156     if (wxlStateData->m_lua_debug_hook_yield > 0)
157     {
158         // yield based on number of ms passed NOT every hook event
159         unsigned long last_time = wxlStateData->m_last_debug_hook_time;
160         unsigned long cur_time  = wxGetLocalTimeMillis().GetLo();
161 
162         if ((cur_time > last_time + wxlStateData->m_lua_debug_hook_yield) ||
163             (cur_time < last_time)) // wrapped
164         {
165             wxlStateData->m_last_debug_hook_time = cur_time;
166 
167             bool painting = (evtType == wxEVT_PAINT);
168 
169 /*
170             wxLongToLongHashMap::iterator it;
171             wxLongToLongHashMap* hashMap = &wxlState.GetLuaStateRefData()->m_wxlStateData->m_trackedObjects;
172             for (it = hashMap->begin(); it != hashMap->end(); ++it)
173             {
174                 wxObject* obj = (wxObject*)it->second;
175                 if (obj && wxDynamicCast(obj, wxPaintDC))
176                 {
177                     painting = true;
178                     break;
179                 }
180             }
181 */
182 
183             if (!painting)
184                 wxYield(); //IfNeeded();
185         }
186     }
187 }
188 
189 // ----------------------------------------------------------------------------
190 // wxFindWindowByPointer - find a window by its pointer
191 //     return NULL if doesn't exist, see wxFindWindowByID and wxFindWindowByLabel
192 // ----------------------------------------------------------------------------
wxFindWindowPointerRecursively(const wxWindow * parent,const wxWindow * win)193 static wxWindow *wxFindWindowPointerRecursively(const wxWindow *parent, const wxWindow *win)
194 {
195     wxCHECK_MSG(win, NULL, wxT("invalid window in wxFindWindowPointerRecursively"));
196 
197     if ( parent )
198     {
199         // see if this is the one we're looking for
200         if ( parent == win )
201             return (wxWindow*)win;
202 
203         // It wasn't, so check all its children
204         for ( wxWindowList::compatibility_iterator node = parent->GetChildren().GetFirst();
205               node;
206               node = node->GetNext() )
207         {
208             // recursively check each child
209             wxWindow *child_win = (wxWindow *)node->GetData();
210             wxWindow *retwin = wxFindWindowPointerRecursively(child_win, win);
211             if (retwin)
212                 return retwin;
213         }
214     }
215 
216     return NULL; // Not found
217 }
218 
219 // Check to see if wxWidgets still thinks "win" is a valid window
220 //   parent is the window to start with, if parent=NULL check all windows
wxFindWindowByPointer(const wxWindow * parent,const wxWindow * win)221 static wxWindow* wxFindWindowByPointer(const wxWindow *parent, const wxWindow *win)
222 {
223     wxCHECK_MSG(win, NULL, wxT("Invalid window in wxFindWindowByPointer"));
224 
225     if ( parent )
226     {
227         // just check parent and all its children
228         return wxFindWindowPointerRecursively(parent, win);
229     }
230     // start at very top of wx's windows
231     for ( wxWindowList::compatibility_iterator top_node = wxTopLevelWindows.GetFirst();
232           top_node;
233           top_node = top_node->GetNext() )
234     {
235         // recursively check each window & its children
236         wxWindow *top_win = top_node->GetData();
237         wxWindow *retwin = wxFindWindowPointerRecursively(top_win, win);
238         if (retwin)
239             return retwin;
240     }
241 
242     return NULL; // Not found
243 }
244 
245 // ----------------------------------------------------------------------------
246 // wxLuaCleanupWindows - given a wxWindowList of wxWindows it runs wxFindWindowByPointer
247 //   on it to remove dead pointers from the list if only_check=true or
248 //   Destroy() the windows and remove them from the list if !only_check.
249 // Returns true if any windows are removed, i.e. the list has changed
250 // ----------------------------------------------------------------------------
wxLuaCleanupWindows(lua_State * L,bool only_check)251 bool wxLuaCleanupWindows(lua_State* L, bool only_check)
252 {
253     wxCHECK_MSG(L, false, wxT("Invalid wxLuaState"));
254 
255     bool removed = false;
256 
257     lua_pushlightuserdata(L, &wxlua_lreg_topwindows_key); // push key
258     lua_rawget(L, LUA_REGISTRYINDEX);                     // pop key, push value (table)
259 
260     bool try_again = true;
261 
262     while (try_again)
263     {
264         try_again = false;
265 
266         lua_pushnil(L);
267         while (lua_next(L, -2) != 0)
268         {
269             // value = -1, key = -2, table = -3
270             wxWindow* win = (wxWindow*)lua_touserdata(L, -2);
271             wxCHECK_MSG(win, false, wxT("Invalid wxWindow"));
272 
273             if (wxFindWindowByPointer(NULL, win) == NULL)
274             {
275                 // simply remove dead window from the list
276                 removed = true;
277                 lua_pop(L, 1);        // pop value
278 
279                 lua_pushvalue(L, -1); // copy key for next iteration
280                 lua_pushnil(L);
281                 lua_rawset(L, -4);    // set t[key] = nil to remove it
282             }
283             else if (!only_check)
284             {
285                 removed = true;
286                 if (win->HasCapture())
287                     win->ReleaseMouse();
288 
289                 // 2.9 insists that all pushed event handlers are popped before destroying window
290                 // we assume (for now) that they're properly owned so we don't pop or delete them
291                 //while (win->GetEventHandler() != win)
292                 //    win->PopEventHandler(false);
293 
294                 // release capture for children since we may be abruptly ending
295                 for ( wxWindowList::compatibility_iterator childNode = win->GetChildren().GetFirst();
296                     childNode;
297                     childNode = childNode->GetNext() )
298                 {
299                     wxWindow *child = childNode->GetData();
300 
301                     lua_pushlightuserdata(L, child);
302                     lua_pushnil(L);
303                     lua_rawset(L, -5);
304 
305                     if (child->HasCapture())
306                         child->ReleaseMouse();
307 
308                     // 2.9 insists that all pushed event handlers are popped before destroying window
309                     // we assume (for now) that they're properly owned so we don't pop or delete them
310                     //while (child->GetEventHandler() != child)
311                     //    child->PopEventHandler(false);
312                 }
313 
314                 if (!win->IsBeingDeleted())
315                 {
316                     delete win;
317                 }
318 
319                 // wxLuaWindowDestroyHandler should destroy this node
320                 //  and also delete all the children and their nodes
321                 //  it's probably best to start from the top again
322                 lua_pop(L, 1);        // pop value
323 
324                 lua_pushnil(L);
325                 lua_rawset(L, -3);    // set t[key] = nil to remove it
326 
327                 try_again = true;
328                 break;
329             }
330             else
331                 lua_pop(L, 1); // pop value, lua_next will pop key at end
332         }
333     }
334 
335     lua_pop(L, 1); // pop table
336 
337     return removed;
338 }
339 
340 //----------------------------------------------------------------------------
341 // wxLuaStateRunLocker
342 //----------------------------------------------------------------------------
343 
344 class wxLuaStateRunLocker
345 {
346 public:
wxLuaStateRunLocker(int & is_running)347     wxLuaStateRunLocker(int &is_running) : m_is_running(++is_running) {}
~wxLuaStateRunLocker()348     ~wxLuaStateRunLocker() { m_is_running = wxMax(0, m_is_running-1); } // DebugHookBreak sets to 0.
349 
350     int &m_is_running;
351 };
352 
353 //----------------------------------------------------------------------------
354 // wxLuaStateData
355 //----------------------------------------------------------------------------
356 
wxLuaStateData()357 wxLuaStateData::wxLuaStateData()
358                :m_is_running(0),
359                 m_is_closing(false),
360                 m_lua_debug_hook_count(100), m_lua_debug_hook_yield(50),
361                 m_lua_debug_hook(0), m_lua_debug_hook_send_evt(false),
362                 m_last_debug_hook_time(0), m_debug_hook_break(false),
363                 m_debug_hook_break_msg(wxT("Break")),
364                 m_evtHandler(NULL),
365                 m_id(wxID_ANY)
366 {
367 }
368 
~wxLuaStateData()369 wxLuaStateData::~wxLuaStateData()
370 {
371     // no events here, the handler may already be gone
372     m_evtHandler = NULL;
373 }
374 
375 //----------------------------------------------------------------------------
376 // wxLuaStateRefData
377 //----------------------------------------------------------------------------
378 
wxLuaStateRefData(bool create_data)379 wxLuaStateRefData::wxLuaStateRefData(bool create_data)
380                   :m_lua_State(NULL),
381                    m_lua_State_static(false),
382                    m_lua_State_coroutine(false),
383                    m_wxlStateData(NULL),
384                    m_own_stateData(false)
385 {
386     if (create_data)
387     {
388         m_wxlStateData = new wxLuaStateData();
389         m_own_stateData = true;
390     }
391 }
392 
~wxLuaStateRefData()393 wxLuaStateRefData::~wxLuaStateRefData()
394 {
395     wxCHECK_RET((m_lua_State_static == true) || (m_lua_State == NULL),
396                 wxT("You must ALWAYS call wxLuaState::Destroy and not wxObject::UnRef"));
397 
398     // only close the state if it's not static,
399     // as when it's static (wx is loaded as a library), it will be closed somewhere else
400     if (!m_lua_State_static)
401         CloseLuaState(true);
402 
403     if (m_own_stateData)
404         delete m_wxlStateData;
405 }
406 
CloseLuaState(bool force,bool collectGarbage)407 bool wxLuaStateRefData::CloseLuaState(bool force, bool collectGarbage)
408 {
409     if ((m_lua_State == NULL) || m_wxlStateData->m_is_closing || m_lua_State_coroutine)
410         return true;
411 
412     if (lua_status(m_lua_State) != 0) // lua state is not LUA_OK
413         return true;
414 
415     m_wxlStateData->m_is_closing = true;
416 
417     //wxCHECK_MSG(m_lua_State, false, wxT("Interpreter not created"));
418     // wxCHECK_MSG(!m_is_running, false, wxT("Interpreter still running, can't destroy"));  FIXME
419 
420     // remove deleted windows first
421     wxLuaCleanupWindows(m_lua_State, true);
422 
423     // are there still windows? ask to abort deleting them if !force
424     bool tlwindows_open = false;
425     lua_pushlightuserdata(m_lua_State, &wxlua_lreg_topwindows_key); // push key
426     lua_rawget(m_lua_State, LUA_REGISTRYINDEX);                     // pop key, push value (table)
427 
428     lua_pushnil(m_lua_State);
429     if (lua_next(m_lua_State, -2))
430     {
431         tlwindows_open = true;
432         lua_pop(m_lua_State, 3); // pop key, value, table
433     }
434     else
435         lua_pop(m_lua_State, 1); // pop table
436 
437     if (tlwindows_open)
438     {
439         int ret = wxOK;
440 
441         if (!force)
442         {
443             ret = wxMessageBox(wxT("Windows are still open, would you like to delete them?"),
444                                wxT("Delete existing windows?"), wxOK|wxCANCEL|wxICON_QUESTION);
445         }
446 
447         if (ret == wxCANCEL)
448         {
449             m_wxlStateData->m_is_closing = false;
450             return false;
451         }
452 
453         //wxPrintf(wxT("Deleting windows\n"));
454 
455         // delete windows and their eventhandler since they delete the wxLuaEventCallbacks
456         //  which require a lua_State
457         wxLuaCleanupWindows(m_lua_State, false);
458         // wait for wxWindow::Destroy() to really delete the windows
459         //wxYieldIfNeeded();
460     }
461 
462     // clear the wxlua_lreg_wxluastatedata_key which we test for in the debug hook
463     // to know if the lua_State is being closed
464     lua_pushlightuserdata(m_lua_State, &wxlua_lreg_wxluastatedata_key);
465     lua_pushnil(m_lua_State);
466     lua_rawset( m_lua_State, LUA_REGISTRYINDEX ); // pop key, push bool
467 
468     ClearCallbacks();
469 
470     // remove refs table to try to clear memory gracefully
471     wxlua_lreg_createtable(m_lua_State, &wxlua_lreg_refs_key);
472     wxlua_lreg_createtable(m_lua_State, &wxlua_lreg_debug_refs_key);
473     //wxlua_lreg_createtable(m_lua_State, &wxlua_lreg_derivedmethods_key); // gc will delete them
474 
475     if (collectGarbage)
476         lua_gc(m_lua_State, LUA_GCCOLLECT, 0); // round up dead refs
477 
478     if (!m_lua_State_static)
479         lua_close(m_lua_State);
480 
481     // Clear out the wxLuaState we hashed, note it's not refed so we have
482     // NULL its ref data.
483     // Note: even though the lua_State is closed the pointer value is still good.
484     // The wxLuaState we pushed into the reg table is a light userdata so
485     // it didn't get deleted.
486     wxHashMapLuaState::iterator it = wxLuaState::s_wxHashMapLuaState.find(m_lua_State);
487     if (it != wxLuaState::s_wxHashMapLuaState.end())
488     {
489         wxLuaState* wxlState = it->second;
490         wxlState->SetRefData(NULL);
491         delete wxlState;
492         wxLuaState::s_wxHashMapLuaState.erase(m_lua_State);
493     }
494 
495     m_lua_State = NULL;
496 
497     return true;
498 }
499 
ClearCallbacks()500 void wxLuaStateRefData::ClearCallbacks()
501 {
502     wxCHECK_RET(m_lua_State, wxT("Invalid lua_State"));
503 
504     lua_State* L = m_lua_State;
505 
506     lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key
507     lua_rawget(L, LUA_REGISTRYINDEX);                       // pop key, push value (table)
508 
509     lua_pushnil(L);
510     while (lua_next(L, -2) != 0)
511     {
512         // value = -1, key = -2, table = -3
513         wxLuaEventCallback* cb = (wxLuaEventCallback*)lua_touserdata(L, -2);
514         cb->ClearwxLuaState();
515 
516         lua_pop(L, 1);               // pop value, lua_next will pop key at end
517     }
518 
519     lua_pop(L, 1); // pop table
520 
521     wxlua_lreg_createtable(m_lua_State, &wxlua_lreg_evtcallbacks_key);
522 
523     // ----------------------------------------------------------------------
524     // These should already be gone from wxLuaCleanupWindows, make sure...
525 
526     lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key
527     lua_rawget(L, LUA_REGISTRYINDEX);                              // pop key, push value (table)
528 
529     lua_pushnil(L);
530     while (lua_next(L, -2) != 0)
531     {
532         // value = -1, key = -2, table = -3
533         wxLuaWinDestroyCallback* cb = (wxLuaWinDestroyCallback*)lua_touserdata(L, -1);
534         cb->ClearwxLuaState();
535 
536         lua_pop(L, 1);               // pop value, lua_next will pop key at end
537     }
538 
539     lua_pop(L, 1); // pop table
540 
541     wxlua_lreg_createtable(m_lua_State, &wxlua_lreg_windestroycallbacks_key);
542 }
543 
544 //----------------------------------------------------------------------------
545 // wxLuaState
546 //----------------------------------------------------------------------------
547 
548 IMPLEMENT_DYNAMIC_CLASS(wxLuaState, wxObject)
549 
550 wxHashMapLuaState wxLuaState::s_wxHashMapLuaState;
551 bool wxLuaState::sm_wxAppMainLoop_will_run = false;
552 
553 
554 #define M_WXLSTATEDATA ((wxLuaStateRefData*)m_refData)
555 
CreateRefData() const556 wxObjectRefData *wxLuaState::CreateRefData() const
557 {
558     return new wxLuaStateRefData;
559 }
560 //wxObjectRefData *wxLuaState::CloneRefData(const wxObjectRefData *data) const
561 //{
562 //    return new wxLuaStateRefData(*(const wxLuaStateRefData *)data);
563 //}
564 
Create(const wxLuaState & wxlState)565 void wxLuaState::Create( const wxLuaState& wxlState )
566 {
567     Destroy();
568     Ref(wxlState);
569 }
570 
Create(wxEvtHandler * handler,wxWindowID id)571 bool wxLuaState::Create(wxEvtHandler *handler, wxWindowID id)
572 {
573     Destroy();
574 
575     lua_State* L = luaL_newstate();
576     // load some useful libraries, loads all of them
577     luaL_openlibs(L);
578 
579     bool ok = Create(L, wxLUASTATE_SETSTATE|wxLUASTATE_OPENBINDINGS);
580 
581     M_WXLSTATEDATA->m_wxlStateData->m_evtHandler = handler;
582     M_WXLSTATEDATA->m_wxlStateData->m_id = id;
583 
584     // alert people that we've been created so they can finish setting us up
585     wxLuaEvent event(wxEVT_LUA_CREATION, GetId(), *this);
586     SendEvent( event );
587 
588     return ok;
589 }
590 
Create(lua_State * L,int state_type)591 bool wxLuaState::Create(lua_State* L, int state_type)
592 {
593     wxCHECK_MSG(L != NULL, false, wxT("Invalid lua_State"));
594     Destroy();
595 
596     if (WXLUA_HASBIT(state_type, wxLUASTATE_GETSTATE))
597     {
598         // returns an invalid, wxNullLuaState on failure
599         Ref(wxLuaState::GetwxLuaState(L, WXLUA_HASBIT(state_type, wxLUASTATE_ROOTSTATE)));
600     }
601     else if (WXLUA_HASBIT(state_type, wxLUASTATE_SETSTATE))
602     {
603         m_refData = new wxLuaStateRefData();
604 
605         M_WXLSTATEDATA->m_lua_State = L;
606         M_WXLSTATEDATA->m_lua_State_static = WXLUA_HASBIT(state_type, wxLUASTATE_STATICSTATE);
607 
608         // Make the GC a little more aggressive since we push void* data
609         // that may be quite large. The upshot is that Lua runs faster.
610         // Empirically found by timing: "for i = 1, 1E6 do local p = wx.wxPoint() end"
611         lua_gc(L, LUA_GCSETPAUSE, 120);
612         lua_gc(L, LUA_GCSETSTEPMUL, 400);
613 
614         // Create a new state to push into Lua, the last wxLuaStateRefData will delete it.
615         // Note: we call SetRefData() so that we don't increase the ref count.
616         wxLuaState* hashState = new wxLuaState(false);
617         hashState->SetRefData(m_refData);
618         wxLuaState::s_wxHashMapLuaState[L] = hashState;
619 
620         // Stick us into the Lua registry table - push key, value
621         lua_pushlightuserdata(L, &wxlua_lreg_wxluastate_key);
622         lua_pushlightuserdata( L, (void*)hashState );
623         lua_rawset( L, LUA_REGISTRYINDEX ); // set the value
624 
625         // start off not in an event
626         wxlua_setwxeventtype(L, wxEVT_NULL);
627 
628         // Push our wxLuaStateData
629         lua_pushlightuserdata(L, &wxlua_lreg_wxluastatedata_key);
630         lua_pushlightuserdata(L, M_WXLSTATEDATA->m_wxlStateData);
631         lua_rawset(L, LUA_REGISTRYINDEX); // set the value
632 
633         // These tables are expected to exist no matter what.
634         // They're in the registry so even if they're not used they
635         // shouldn't bother anyone.
636 
637         lua_pushlightuserdata(L, &wxlua_lreg_regtable_key);
638         lua_newtable(L);      // main table
639           lua_newtable(L);    // metatable
640           lua_pushlstring(L, "__mode", 6);
641           lua_pushlstring(L, "kv", 2);
642           lua_rawset(L, -3);                  // set mode of main table
643           lua_setmetatable(L, -2);            // via the metatable
644         lua_rawset(L, LUA_REGISTRYINDEX); // set the value
645 
646         // create the types table in registry
647         wxlua_lreg_createtable(L, &wxlua_lreg_types_key);
648 
649         // create the refs table in registry
650         wxlua_lreg_createtable(L, &wxlua_lreg_refs_key);
651 
652         // create the debug refs table in registry
653         wxlua_lreg_createtable(L, &wxlua_lreg_debug_refs_key);
654 
655         // create the wxLuaBindClasses table in the registry
656         wxlua_lreg_createtable(L, &wxlua_lreg_classes_key);
657 
658         // Create a table for overridden methods for C++ userdata objects
659         wxlua_lreg_createtable(L, &wxlua_lreg_derivedmethods_key);
660 
661         // Create a table for the wxLuaBindings we've installed
662         wxlua_lreg_createtable(L, &wxlua_lreg_wxluabindings_key);
663 
664         // Create a table for the userdata that we've pushed into Lua
665         wxlua_lreg_createtable(L, &wxlua_lreg_weakobjects_key);
666 
667         // Create a table for objects to delete
668         wxlua_lreg_createtable(L, &wxlua_lreg_gcobjects_key);
669 
670         // Create a table for wxLuaEventCallbacks
671         wxlua_lreg_createtable(L, &wxlua_lreg_evtcallbacks_key);
672 
673         // Create a table for wxLuaWinDestroyCallbacks
674         wxlua_lreg_createtable(L, &wxlua_lreg_windestroycallbacks_key);
675 
676         // Create a table for top level wxWindows
677         wxlua_lreg_createtable(L, &wxlua_lreg_topwindows_key);
678 
679         // copy Lua's print function in case someone wants to use it
680         lua_getglobal(L, "print");
681 #if LUA_VERSION_NUM < 502
682         lua_pushlstring(L, "print_lua", 9);
683         lua_pushvalue(L, -2);               // copy print function
684         lua_rawset(L, LUA_GLOBALSINDEX);    // set t[key] = value, pops key and value
685 #else
686         lua_pushglobaltable(L);
687         lua_pushlstring(L, "print_lua", 9);
688         lua_pushvalue(L, -3);               // copy print function
689         lua_rawset(L, -3);                  // set t[key] = value, pops key and value
690         lua_pop(L, 1);                      // pop the global table
691 #endif // LUA_VERSION_NUM < 502
692 
693         lua_pushlstring(L, "print_lua", 9); // also keep a permanent copy in registry
694         lua_pushvalue(L, -2);               // copy print function
695         lua_rawset(L, LUA_REGISTRYINDEX);   // set t[key] = value, pops key and value
696 
697         lua_pop(L, 1);                      // pop the print function
698 
699         // register wxLua's print handler to send events, replaces Lua's print function
700         RegisterFunction(wxlua_printFunction, "print");
701 
702         // register our NULL type
703         //wxluatype_NULL = wxluaT_newmetatable(L, wxluatype_NULL);
704         wxLuaBinding::InstallClassMetatable(L, &wxLuaBindClass_NULL);
705 
706         // now register bindings
707         if (WXLUA_HASBIT(state_type, wxLUASTATE_OPENBINDINGS))
708         {
709             // load the bit lib, this is the accepted way, see luaL_openlibs(L)
710             lua_pushcfunction(L, luaopen_bit);
711             lua_pushstring(L, "bit");
712             lua_call(L, 1, 0);
713 
714 #if (LUA_VERSION_NUM < 502)
715             lua_pushcfunction(L, luaopen_bit32);
716             lua_pushstring(L, "bit32");
717             lua_call(L, 1, 0);
718 #endif // (LUA_VERSION_NUM < 502)
719 
720             RegisterBindings();
721         }
722     }
723     else
724         wxFAIL_MSG(wxT("Unknown state_type for wxLuaState::Create()"));
725 
726     return Ok();
727 }
728 
729 // --------------------------------------------------------------------------
730 
IsOk() const731 bool wxLuaState::IsOk() const
732 {
733     return (m_refData != NULL) && (M_WXLSTATEDATA->m_lua_State != NULL);
734 }
735 
736 // --------------------------------------------------------------------------
737 
Destroy()738 void wxLuaState::Destroy()
739 {
740     if (m_refData == NULL || M_WXLSTATEDATA->m_lua_State_static) return;
741 
742     // we don't want recursion in UnRef and wxlua_garbageCollect
743     if (GetRefData()->GetRefCount() == 1)
744         M_WXLSTATEDATA->CloseLuaState(true);
745 
746     UnRef();
747 }
748 
CloseLuaState(bool force,bool collectGarbage)749 bool wxLuaState::CloseLuaState(bool force, bool collectGarbage)
750 {
751     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
752     if (M_WXLSTATEDATA->m_lua_State_static) return true;
753 
754     return M_WXLSTATEDATA->CloseLuaState(force, collectGarbage);
755 }
756 
IsClosing() const757 bool wxLuaState::IsClosing() const
758 {
759     wxCHECK_MSG(m_refData && M_WXLSTATEDATA->m_wxlStateData, false, wxT("Invalid wxLuaState"));
760     return M_WXLSTATEDATA->m_wxlStateData->m_is_closing;
761 }
762 
763 // --------------------------------------------------------------------------
764 
GetLuaState() const765 lua_State* wxLuaState::GetLuaState() const
766 {
767     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
768     return M_WXLSTATEDATA->m_lua_State;
769 }
770 
GetLuaStateData() const771 wxLuaStateData* wxLuaState::GetLuaStateData() const
772 {
773     wxCHECK_MSG(m_refData != NULL, NULL, wxT("Invalid wxLuaState, missing ref data"));
774     return M_WXLSTATEDATA->m_wxlStateData;
775 }
776 
GetwxLuaState(lua_State * L,bool get_root_state)777 wxLuaState wxLuaState::GetwxLuaState(lua_State* L, bool get_root_state) // static function
778 {
779     if (!get_root_state)
780     {
781         // try our hashtable for faster lookup
782         wxHashMapLuaState::iterator it = s_wxHashMapLuaState.find(L);
783         if (it != s_wxHashMapLuaState.end())
784             return wxLuaState(*it->second);
785     }
786 
787     // else it's a coroutine? look up the state data from Lua
788     wxLuaState* wxlState = NULL;
789 
790     // try to get the state we've stored
791     lua_pushlightuserdata(L, &wxlua_lreg_wxluastate_key);
792     lua_rawget( L, LUA_REGISTRYINDEX );
793 
794     // if nothing was returned or it wasn't a ptr, abort
795     if ( lua_islightuserdata(L, -1) )
796         wxlState = (wxLuaState*)lua_touserdata( L, -1 );
797 
798     lua_pop(L, 1); // pop the wxLuaState or nil on failure
799 
800     if (!wxlState)
801         return wxNullLuaState;
802 
803     if (get_root_state || (wxlState->GetLuaState() == L))
804     {
805         return wxLuaState(*wxlState); // Ref it
806     }
807     else
808     {
809         // Create a new wxLuaState for the coroutine and set the wxLuaStateData
810         //  to the original wxLuaState's data
811         wxLuaStateRefData* refData = new wxLuaStateRefData(false);
812         refData->m_lua_State = L;
813         refData->m_lua_State_static = true;
814         refData->m_lua_State_coroutine = true;
815 
816         refData->m_wxlStateData = wxlState->GetLuaStateData();
817         refData->m_own_stateData = false;
818 
819         wxLuaState wxlState2(false);
820         wxlState2.SetRefData(refData);
821         return wxlState2;
822     }
823 
824     return wxNullLuaState;
825 }
826 
827 // --------------------------------------------------------------------------
828 
SetEventHandler(wxEvtHandler * evtHandler)829 void wxLuaState::SetEventHandler(wxEvtHandler *evtHandler)
830 {
831     wxCHECK_RET(m_refData && M_WXLSTATEDATA->m_wxlStateData, wxT("Invalid wxLuaState"));
832     M_WXLSTATEDATA->m_wxlStateData->m_evtHandler = evtHandler;
833 }
GetEventHandler() const834 wxEvtHandler *wxLuaState::GetEventHandler() const
835 {
836     wxCHECK_MSG(m_refData && M_WXLSTATEDATA->m_wxlStateData, NULL, wxT("Invalid wxLuaState"));
837     return M_WXLSTATEDATA->m_wxlStateData->m_evtHandler;
838 }
839 
SetId(wxWindowID id)840 void wxLuaState::SetId(wxWindowID id)
841 {
842     wxCHECK_RET(m_refData && M_WXLSTATEDATA->m_wxlStateData, wxT("Invalid wxLuaState"));
843     M_WXLSTATEDATA->m_wxlStateData->m_id = id;
844 }
GetId() const845 wxWindowID  wxLuaState::GetId() const
846 {
847     wxCHECK_MSG(m_refData && M_WXLSTATEDATA->m_wxlStateData, wxID_ANY, wxT("Invalid wxLuaState"));
848     return M_WXLSTATEDATA->m_wxlStateData->m_id;
849 }
850 
SendEvent(wxLuaEvent & event) const851 bool wxLuaState::SendEvent( wxLuaEvent &event ) const
852 {
853     wxCHECK_MSG(m_refData && M_WXLSTATEDATA->m_wxlStateData, false, wxT("Invalid wxLuaState"));
854 
855     if (M_WXLSTATEDATA->m_wxlStateData->m_evtHandler)
856     {
857         event.SetEventObject( (wxObject*)this );
858         return M_WXLSTATEDATA->m_wxlStateData->m_evtHandler->ProcessEvent(event);
859     }
860 
861     return false;
862 }
863 
864 // ----------------------------------------------------------------------------
865 
RunFile(const wxString & filename,int nresults)866 int wxLuaState::RunFile(const wxString &filename, int nresults)
867 {
868     wxCHECK_MSG(Ok(), LUA_ERRRUN, wxT("Lua interpreter not created"));
869     //wxCHECK_MSG(!M_WXLSTATEDATA->m_wxlStateData->m_is_running, LUA_ERRRUN, wxT("Lua interpreter is already running"));
870 
871     M_WXLSTATEDATA->m_wxlStateData->m_debug_hook_break = false;
872     wxLuaStateRunLocker runLocker(M_WXLSTATEDATA->m_wxlStateData->m_is_running);
873 
874     int top = lua_GetTop();
875     int status = luaL_LoadFile(wx2lua(filename));
876     if (status == 0)
877         status = LuaPCall(0, nresults); // no args and nresults
878     else
879         SendLuaErrorEvent(status, top); // compilation error
880 
881     if (nresults == 0)
882         lua_SetTop(top); // restore original top (removes err msg)
883 
884     M_WXLSTATEDATA->m_wxlStateData->m_debug_hook_break = false;
885 
886     return status;
887 }
888 
RunString(const wxString & script,const wxString & name,int nresults)889 int wxLuaState::RunString(const wxString &script, const wxString& name, int nresults)
890 {
891     wxLuaCharBuffer buf(script);
892     return RunBuffer(buf.GetData(), buf.Length(), name, nresults);
893 }
894 
RunBuffer(const char buf[],size_t size,const wxString & name,int nresults)895 int wxLuaState::RunBuffer(const char buf[], size_t size, const wxString &name, int nresults)
896 {
897     wxCHECK_MSG(Ok(), LUA_ERRRUN, wxT("Invalid wxLuaState"));
898     //wxCHECK_MSG(!M_WXLSTATEDATA->m_wxlStateData->m_is_running, LUA_ERRRUN, wxT("Lua interpreter is already running"));
899 
900     M_WXLSTATEDATA->m_wxlStateData->m_debug_hook_break = false;
901     wxLuaStateRunLocker runLocker(M_WXLSTATEDATA->m_wxlStateData->m_is_running);
902 
903     int top = lua_GetTop();
904     int status = luaL_LoadBuffer(buf, size, wx2lua(name));
905     if (status == 0)
906         status = LuaPCall(0, nresults); // no args and nresults
907     else
908         SendLuaErrorEvent(status, top); // compilation error
909 
910     if (nresults == 0)
911         lua_SetTop(top); // restore original top (removes err msg)
912 
913     M_WXLSTATEDATA->m_wxlStateData->m_debug_hook_break = false;
914 
915     return status;
916 }
917 
IsRunning() const918 bool wxLuaState::IsRunning() const
919 {
920     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
921     return M_WXLSTATEDATA->m_wxlStateData->m_is_running > 0;
922 }
923 
924 // this function taken from lua.c, the lua executable
wxlua_traceback(lua_State * L)925 static int LUACALL wxlua_traceback (lua_State *L) {
926   if (!lua_isstring(L, 1))  /* 'message' not a string? */
927     return 1;  /* keep it intact */
928   lua_getglobal(L, "debug");
929   if (!lua_istable(L, -1)) {
930     lua_pop(L, 1);
931   }
932   lua_getfield(L, -1, "traceback");
933   if (!lua_isfunction(L, -1)) {
934     lua_pop(L, 2);
935     return 1;
936   }
937   lua_pushvalue(L, 1);      /* pass error message */
938   lua_pushinteger(L, 2);    /* skip this function and traceback */
939   lua_call(L, 2, 1);        /* call debug.traceback */
940   return 1;
941 }
942 
LuaPCall(int narg,int nresults)943 int wxLuaState::LuaPCall(int narg, int nresults)
944 {
945     wxCHECK_MSG(Ok(), LUA_ERRRUN, wxT("Invalid wxLuaState"));
946     lua_State* L = M_WXLSTATEDATA->m_lua_State;
947 
948     int status = 0;
949     int top  = lua_gettop(L);
950     int base = top - narg;                  // function index
951 
952     lua_pushcfunction(L, wxlua_traceback);  // push our traceback function
953 
954     lua_insert(L, base);                    // put it under chunk and args
955     status = lua_pcall(L, narg, nresults, base);
956     lua_remove(L, base);                    // remove traceback function
957 
958     if (status != 0)
959     {
960         SendLuaErrorEvent(status, top - (narg + 1));
961         lua_settop(L, top); // restore original top (removes err msg)
962     }
963 
964     return status;
965 }
966 
SendLuaErrorEvent(int status,int top)967 bool wxLuaState::SendLuaErrorEvent(int status, int top)
968 {
969     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
970     wxString errorMsg;
971     int line_num = -1;
972 
973     wxlua_errorinfo(GetLuaState(), status, top, &errorMsg, &line_num);
974 
975     wxLuaEvent event(wxEVT_LUA_ERROR, GetId(), *this);
976     event.SetString(errorMsg);
977     event.SetInt(line_num);
978     return SendEvent(event);
979 }
980 
GetInEventType() const981 wxEventType wxLuaState::GetInEventType() const
982 {
983     wxCHECK_MSG(Ok(), wxEVT_NULL, wxT("Invalid wxLuaState"));
984     return wxlua_getwxeventtype(M_WXLSTATEDATA->m_lua_State);
985 }
986 
SetInEventType(wxEventType eventType)987 void wxLuaState::SetInEventType(wxEventType eventType)
988 {
989     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
990     wxlua_setwxeventtype(M_WXLSTATEDATA->m_lua_State, eventType);
991 }
992 
CompileString(const wxString & script,const wxString & name,wxString * errMsg_,int * line_num_)993 int wxLuaState::CompileString(const wxString &script, const wxString& name, wxString* errMsg_, int* line_num_)
994 {
995     wxLuaCharBuffer buf(script);
996     return CompileBuffer(buf.GetData(), buf.Length(), name, errMsg_, line_num_);
997 }
CompileBuffer(const char buf[],size_t size,const wxString & name,wxString * errMsg_,int * line_num_)998 int wxLuaState::CompileBuffer(const char buf[], size_t size, const wxString &name, wxString* errMsg_, int* line_num_)
999 {
1000     // create a new lua_State so we don't mess up our own
1001     lua_State *L = luaL_newstate();
1002     luaL_openlibs(L); // load some useful libraries, loads all of them
1003     int top = lua_gettop(L);
1004     int status = luaL_loadbuffer(L, (const char*)buf, size, wx2lua(name));
1005     wxlua_errorinfo(L, status, top, errMsg_, line_num_);
1006     lua_close(L);
1007     return status;
1008 }
1009 
DebugHookBreak(const wxString & msg)1010 void wxLuaState::DebugHookBreak(const wxString &msg)
1011 {
1012     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1013     //wxCHECK_RET(M_WXLSTATEDATA->m_wxlStateData->m_is_running, wxT("Lua interpreter not running"));
1014 
1015     // Lua likes to be stopped within the debug hook, you get funny wxYield
1016     //  recursion asserts if you call wxlua_Error() within another wxYield, i.e. from a gui button
1017 
1018     M_WXLSTATEDATA->m_wxlStateData->m_debug_hook_break_msg = msg;
1019     M_WXLSTATEDATA->m_wxlStateData->m_debug_hook_break = true;
1020     lua_sethook(GetLuaState(), wxlua_debugHookFunction, LUA_MASKCALL|LUA_MASKRET|LUA_MASKLINE|LUA_MASKCOUNT, 1);
1021     M_WXLSTATEDATA->m_wxlStateData->m_is_running = 0;
1022 }
1023 
ClearDebugHookBreak()1024 void wxLuaState::ClearDebugHookBreak()
1025 {
1026     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1027 
1028     M_WXLSTATEDATA->m_wxlStateData->m_debug_hook_break = false;
1029     SetLuaDebugHook(GetLuaDebugHook(),
1030                     GetLuaDebugHookCount(),
1031                     GetLuaDebugHookYield(),
1032                     GetLuaDebugHookSendEvt());
1033 }
1034 
GetDebugHookBreak() const1035 bool wxLuaState::GetDebugHookBreak() const
1036 {
1037     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1038     return M_WXLSTATEDATA->m_wxlStateData->m_debug_hook_break;
1039 }
GetDebugHookBreakMessage() const1040 wxString wxLuaState::GetDebugHookBreakMessage() const
1041 {
1042     wxCHECK_MSG(Ok(), wxEmptyString, wxT("Invalid wxLuaState"));
1043     return M_WXLSTATEDATA->m_wxlStateData->m_debug_hook_break_msg;
1044 }
1045 
1046 // ----------------------------------------------------------------------------
1047 
SetLuaDebugHook(int hook,int count,int yield_ms,bool send_debug_evt)1048 void wxLuaState::SetLuaDebugHook(int hook, int count, int yield_ms, bool send_debug_evt)
1049 {
1050     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1051 
1052     M_WXLSTATEDATA->m_wxlStateData->m_lua_debug_hook = hook;
1053     M_WXLSTATEDATA->m_wxlStateData->m_lua_debug_hook_count = count;
1054     M_WXLSTATEDATA->m_wxlStateData->m_lua_debug_hook_yield = yield_ms;
1055     M_WXLSTATEDATA->m_wxlStateData->m_lua_debug_hook_send_evt = send_debug_evt;
1056 
1057     // These are the various hooks you can install
1058     //LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE, and LUA_MASKCOUNT
1059     lua_sethook(M_WXLSTATEDATA->m_lua_State, wxlua_debugHookFunction, hook, count);
1060 }
1061 
GetLuaDebugHook() const1062 int wxLuaState::GetLuaDebugHook() const
1063 {
1064     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1065     return M_WXLSTATEDATA->m_wxlStateData->m_lua_debug_hook;
1066 }
GetLuaDebugHookCount() const1067 int wxLuaState::GetLuaDebugHookCount() const
1068 {
1069     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1070     return M_WXLSTATEDATA->m_wxlStateData->m_lua_debug_hook_count;
1071 }
GetLuaDebugHookYield() const1072 int wxLuaState::GetLuaDebugHookYield() const
1073 {
1074     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1075     return M_WXLSTATEDATA->m_wxlStateData->m_lua_debug_hook_yield;
1076 }
GetLuaDebugHookSendEvt() const1077 bool wxLuaState::GetLuaDebugHookSendEvt() const
1078 {
1079     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1080     return M_WXLSTATEDATA->m_wxlStateData->m_lua_debug_hook_send_evt;
1081 }
1082 
GetLastLuaDebugHookTime() const1083 unsigned long wxLuaState::GetLastLuaDebugHookTime() const
1084 {
1085     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1086     return M_WXLSTATEDATA->m_wxlStateData->m_last_debug_hook_time;
1087 }
SetLastLuaDebugHookTime(unsigned long t)1088 void wxLuaState::SetLastLuaDebugHookTime(unsigned long t)
1089 {
1090     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1091     M_WXLSTATEDATA->m_wxlStateData->m_last_debug_hook_time = t;
1092 }
1093 
1094 // ----------------------------------------------------------------------------
1095 
RegisterFunction(lua_CFunction func,const char * funcName)1096 void wxLuaState::RegisterFunction(lua_CFunction func, const char* funcName)
1097 {
1098     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1099     lua_register( M_WXLSTATEDATA->m_lua_State, funcName, func );
1100 }
1101 
RegisterBinding(wxLuaBinding * binding)1102 bool wxLuaState::RegisterBinding(wxLuaBinding* binding)
1103 {
1104     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1105     wxCHECK_MSG(binding, false, wxT("Invalid wxLuaState"));
1106 
1107     wxLuaBinding::InitAllBindings(); // only runs the first time through
1108 
1109     bool ret = binding->RegisterBinding(*this);
1110     if (ret) lua_Pop(1);
1111 
1112     return ret;
1113 }
1114 
RegisterBindings()1115 bool wxLuaState::RegisterBindings()
1116 {
1117     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1118 
1119     return wxLuaBinding::RegisterBindings(*this);
1120 }
1121 
GetLuaBinding(const wxString & bindingName) const1122 wxLuaBinding* wxLuaState::GetLuaBinding(const wxString& bindingName) const
1123 {
1124     wxCHECK_MSG(GetRefData() != NULL, NULL, wxT("Invalid wxLuaState"));
1125     return wxLuaBinding::GetLuaBinding(bindingName);
1126 }
1127 
GetBindClass(int wxluatype) const1128 const wxLuaBindClass* wxLuaState::GetBindClass(int wxluatype) const
1129 {
1130     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1131 
1132     // try to get the wxLuaBindClass from the Lua registry table first
1133     const wxLuaBindClass* wxlClass = wxluaT_getclass(M_WXLSTATEDATA->m_lua_State, wxluatype);
1134 
1135     // we shouldn't ever need this code
1136     if (wxlClass == NULL)
1137         wxlClass = wxLuaBinding::FindBindClass(wxluatype);
1138 
1139     return wxlClass;
1140 }
GetBindClass(const char * className) const1141 const wxLuaBindClass* wxLuaState::GetBindClass(const char* className) const
1142 {
1143     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1144     return wxluaT_getclass(M_WXLSTATEDATA->m_lua_State, className);
1145 }
GetBindClass(const wxLuaBindMethod * wxlMethod) const1146 const wxLuaBindClass* wxLuaState::GetBindClass(const wxLuaBindMethod* wxlMethod) const
1147 {
1148     wxCHECK_MSG(GetRefData() != NULL, NULL, wxT("Invalid wxLuaState"));
1149     return wxLuaBinding::FindBindClass(wxlMethod);
1150 }
GetBindClass(const wxLuaBindCFunc * wxlClass) const1151 const wxLuaBindClass* wxLuaState::GetBindClass(const wxLuaBindCFunc* wxlClass) const
1152 {
1153     wxCHECK_MSG(GetRefData() != NULL, NULL, wxT("Invalid wxLuaState"));
1154     return wxLuaBinding::FindBindClass(wxlClass);
1155 }
1156 
IsDerivedType(int wxl_type,int base_wxl_type,int * baseclass_n) const1157 int wxLuaState::IsDerivedType(int wxl_type, int base_wxl_type, int* baseclass_n) const
1158 {
1159     wxCHECK_MSG(Ok(), -1, wxT("Invalid wxLuaState"));
1160     return wxluaT_isderivedtype(M_WXLSTATEDATA->m_lua_State, wxl_type, base_wxl_type, baseclass_n);
1161 }
1162 
SetCallBaseClassFunction(bool call_base)1163 void wxLuaState::SetCallBaseClassFunction(bool call_base)
1164 {
1165     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1166     wxlua_setcallbaseclassfunction(M_WXLSTATEDATA->m_lua_State, call_base);
1167 }
GetCallBaseClassFunction()1168 bool wxLuaState::GetCallBaseClassFunction()
1169 {
1170     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1171     return wxlua_getcallbaseclassfunction(M_WXLSTATEDATA->m_lua_State);
1172 }
1173 
1174 // ----------------------------------------------------------------------------
1175 // memory tracking functions
1176 
AddGCObject(void * obj_ptr,int wxl_type)1177 void wxLuaState::AddGCObject(void* obj_ptr, int wxl_type)
1178 {
1179     wxCHECK_RET(Ok() && obj_ptr, wxT("Invalid wxLuaState or wxObject to track"));
1180     wxluaO_addgcobject(M_WXLSTATEDATA->m_lua_State, obj_ptr, wxl_type);
1181 }
1182 
DeleteGCObject(int stack_idx,int flags)1183 bool wxLuaState::DeleteGCObject(int stack_idx, int flags)
1184 {
1185     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState or object"));
1186     return wxluaO_deletegcobject(M_WXLSTATEDATA->m_lua_State, stack_idx, flags);
1187 }
1188 
IsGCObject(void * obj_ptr) const1189 bool wxLuaState::IsGCObject(void *obj_ptr) const
1190 {
1191     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1192     return wxluaO_isgcobject(M_WXLSTATEDATA->m_lua_State, obj_ptr);
1193 }
1194 
GetGCObjectInfo() const1195 wxArrayString wxLuaState::GetGCObjectInfo() const
1196 {
1197     wxCHECK_MSG(Ok(), wxArrayString(), wxT("Invalid wxLuaState"));
1198     return wxluaO_getgcobjectinfo(M_WXLSTATEDATA->m_lua_State);
1199 }
1200 
AddTrackedWindow(wxObject * obj)1201 void wxLuaState::AddTrackedWindow(wxObject *obj)
1202 {
1203     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1204     wxluaW_addtrackedwindow(M_WXLSTATEDATA->m_lua_State, obj);
1205 }
1206 
RemoveTrackedWindow(wxWindow * win)1207 void wxLuaState::RemoveTrackedWindow(wxWindow *win)
1208 {
1209     wxCHECK_RET(Ok() && win, wxT("Invalid wxLuaState or wxWindow"));
1210     wxluaW_removetrackedwindow(M_WXLSTATEDATA->m_lua_State, win);
1211 }
1212 
IsTrackedWindow(wxWindow * win,bool check_parents) const1213 bool wxLuaState::IsTrackedWindow(wxWindow *win, bool check_parents) const
1214 {
1215     wxCHECK_MSG(Ok() && win, false, wxT("Invalid wxLuaState or wxWindow"));
1216     return wxluaW_istrackedwindow(M_WXLSTATEDATA->m_lua_State, win, check_parents);
1217 }
1218 
GetTrackedWindowInfo() const1219 wxArrayString wxLuaState::GetTrackedWindowInfo() const
1220 {
1221     wxCHECK_MSG(Ok(), wxArrayString(), wxT("Invalid wxLuaState"));
1222     return wxluaW_gettrackedwindowinfo(M_WXLSTATEDATA->m_lua_State);
1223 }
1224 
GarbageCollectWindows(bool closeWindows)1225 void wxLuaState::GarbageCollectWindows(bool closeWindows)
1226 {
1227     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1228     // remove deleted windows
1229     wxLuaCleanupWindows(M_WXLSTATEDATA->m_lua_State, !closeWindows);
1230 }
1231 
AddTrackedEventCallback(wxLuaEventCallback * callback)1232 void wxLuaState::AddTrackedEventCallback(wxLuaEventCallback* callback)
1233 {
1234     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1235     lua_State* L = M_WXLSTATEDATA->m_lua_State;
1236 
1237     lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key
1238     lua_rawget(L, LUA_REGISTRYINDEX);                       // pop key, push value (table)
1239 
1240     lua_pushlightuserdata(L, callback);                  // push key
1241     lua_pushlightuserdata(L, callback->GetEvtHandler()); // push value
1242     lua_rawset(L, -3); // set t[key] = value; pops key and value
1243 
1244     lua_pop(L, 1);     // pop table
1245 }
RemoveTrackedEventCallback(wxLuaEventCallback * callback)1246 bool wxLuaState::RemoveTrackedEventCallback(wxLuaEventCallback* callback)
1247 {
1248     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1249     lua_State* L = M_WXLSTATEDATA->m_lua_State;
1250 
1251     lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key
1252     lua_rawget(L, LUA_REGISTRYINDEX);                       // pop key, push value (table)
1253 
1254     lua_pushlightuserdata(L, callback); // push key
1255     lua_pushnil(L);                     // push value
1256     lua_rawset(L, -3); // set t[key] = value; pops key and value
1257 
1258     lua_pop(L, 1);     // pop table
1259 
1260     return true; // FIXME return a real value
1261 }
1262 
GetTrackedEventCallbackInfo() const1263 wxArrayString wxLuaState::GetTrackedEventCallbackInfo() const
1264 {
1265     wxArrayString names;
1266 
1267     wxCHECK_MSG(Ok(), names, wxT("Invalid wxLuaState"));
1268     lua_State* L = M_WXLSTATEDATA->m_lua_State;
1269 
1270     lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key
1271     lua_rawget(L, LUA_REGISTRYINDEX);                       // pop key, push value (table)
1272 
1273     lua_pushnil(L);
1274     while (lua_next(L, -2) != 0)
1275     {
1276         // value = -1, key = -2, table = -3
1277         wxLuaEventCallback* wxlCallback = (wxLuaEventCallback*)lua_touserdata(L, -2);
1278         wxCHECK_MSG(wxlCallback, names, wxT("Invalid wxLuaEventCallback"));
1279 
1280         names.Add(wxlCallback->GetInfo());
1281 
1282         lua_pop(L, 1); // pop value, lua_next will pop key at end
1283     }
1284 
1285     lua_pop(L, 1); // pop table
1286 
1287     names.Sort();
1288     return names;
1289 }
1290 
AddTrackedWinDestroyCallback(wxLuaWinDestroyCallback * callback)1291 void wxLuaState::AddTrackedWinDestroyCallback(wxLuaWinDestroyCallback* callback)
1292 {
1293     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1294     lua_State* L = M_WXLSTATEDATA->m_lua_State;
1295 
1296     lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key
1297     lua_rawget(L, LUA_REGISTRYINDEX);                              // pop key, push value (table)
1298 
1299     lua_pushlightuserdata(L, callback->GetWindow()); // push key
1300     lua_pushlightuserdata(L, callback);              // push value
1301     lua_rawset(L, -3); // set t[key] = value; pops key and value
1302 
1303     lua_pop(L, 1);     // pop table
1304 }
RemoveTrackedWinDestroyCallback(wxLuaWinDestroyCallback * callback)1305 bool wxLuaState::RemoveTrackedWinDestroyCallback(wxLuaWinDestroyCallback* callback)
1306 {
1307     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1308     lua_State* L = M_WXLSTATEDATA->m_lua_State;
1309 
1310     lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key
1311     lua_rawget(L, LUA_REGISTRYINDEX);                              // pop key, push value (table)
1312 
1313     lua_pushlightuserdata(L, callback->GetWindow()); // push key
1314     lua_pushnil(L);                                  // push value
1315     lua_rawset(L, -3); // set t[key] = value; pops key and value
1316 
1317     lua_pop(L, 1);     // pop table
1318 
1319     return true; // FIXME return if it was here or not
1320 }
1321 
GetTrackedWinDestroyCallbackInfo() const1322 wxArrayString wxLuaState::GetTrackedWinDestroyCallbackInfo() const
1323 {
1324     wxArrayString names;
1325 
1326     wxCHECK_MSG(Ok(), names, wxT("Invalid wxLuaState"));
1327     lua_State* L = M_WXLSTATEDATA->m_lua_State;
1328 
1329     lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key
1330     lua_rawget(L, LUA_REGISTRYINDEX);                              // pop key, push value (table)
1331 
1332     lua_pushnil(L);
1333     while (lua_next(L, -2) != 0)
1334     {
1335         // value = -1, key = -2, table = -3
1336         wxLuaWinDestroyCallback* wxlDestroyCallBack = (wxLuaWinDestroyCallback*)lua_touserdata(L, -1);
1337         wxCHECK_MSG(wxlDestroyCallBack, names, wxT("Invalid wxLuaWinDestroyCallback"));
1338 
1339         names.Add(wxlDestroyCallBack->GetInfo());
1340 
1341         lua_pop(L, 1); // pop value, lua_next will pop key at end
1342     }
1343 
1344     names.Sort();
1345     return names;
1346 }
1347 
1348 // ----------------------------------------------------------------------------
1349 
wxlua_Error(const char * errorMsg) const1350 void wxLuaState::wxlua_Error(const char *errorMsg) const
1351 {
1352     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1353     wxlua_error(M_WXLSTATEDATA->m_lua_State, errorMsg);
1354 }
1355 
wxlua_ToUserdata(int stack_idx,bool reset) const1356 void* wxLuaState::wxlua_ToUserdata(int stack_idx, bool reset /* = false*/) const
1357 {
1358     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1359     return wxlua_touserdata(M_WXLSTATEDATA->m_lua_State, stack_idx, reset);
1360 }
1361 
1362 // ----------------------------------------------------------------------------
1363 // wxLua Lua Registry Table Functions
1364 
wxluaR_Ref(int stack_idx,void * lightuserdata_reg_key)1365 int wxLuaState::wxluaR_Ref(int stack_idx, void* lightuserdata_reg_key)
1366 {
1367     wxCHECK_MSG(Ok(), LUA_REFNIL, wxT("Invalid wxLuaState"));
1368     return wxluaR_ref(M_WXLSTATEDATA->m_lua_State, stack_idx, lightuserdata_reg_key);
1369 }
1370 
wxluaR_Unref(int wxlref_index,void * lightuserdata_reg_key)1371 bool wxLuaState::wxluaR_Unref(int wxlref_index, void* lightuserdata_reg_key)
1372 {
1373     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1374     return wxluaR_unref(M_WXLSTATEDATA->m_lua_State, wxlref_index, lightuserdata_reg_key);
1375 }
1376 
wxluaR_GetRef(int wxlref_index,void * lightuserdata_reg_key)1377 bool wxLuaState::wxluaR_GetRef(int wxlref_index, void* lightuserdata_reg_key)
1378 {
1379     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1380     return wxluaR_getref(M_WXLSTATEDATA->m_lua_State, wxlref_index, lightuserdata_reg_key);
1381 }
1382 
1383 // ----------------------------------------------------------------------------
1384 
wxluaT_NewMetatable(int wxl_type)1385 int wxLuaState::wxluaT_NewMetatable(int wxl_type)
1386 {
1387     wxCHECK_MSG(Ok(), WXLUA_TUNKNOWN, wxT("Invalid wxLuaState"));
1388     return wxluaT_newmetatable(M_WXLSTATEDATA->m_lua_State, wxl_type);
1389 }
1390 
wxluaT_SetMetatable(int wxl_type)1391 bool wxLuaState::wxluaT_SetMetatable(int wxl_type)
1392 {
1393     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1394     return wxluaT_setmetatable(M_WXLSTATEDATA->m_lua_State, wxl_type);
1395 }
1396 
wxluaT_Type(int stack_idx) const1397 int wxLuaState::wxluaT_Type(int stack_idx) const
1398 {
1399     wxCHECK_MSG(Ok(), WXLUA_TUNKNOWN, wxT("Invalid wxLuaState"));
1400     return wxluaT_type(M_WXLSTATEDATA->m_lua_State, stack_idx);
1401 }
1402 
wxluaT_PushUserDataType(const void * obj_ptr,int wxl_type,bool track)1403 bool wxLuaState::wxluaT_PushUserDataType(const void *obj_ptr, int wxl_type, bool track)
1404 {
1405     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1406     return wxluaT_pushuserdatatype(M_WXLSTATEDATA->m_lua_State, obj_ptr, wxl_type, track);
1407 }
1408 
1409 // ----------------------------------------------------------------------------
1410 // wxLua get data type
1411 
IswxLuaType(int luatype,int wxl_type) const1412 int wxLuaState::IswxLuaType(int luatype, int wxl_type) const
1413 {
1414     wxCHECK_MSG(Ok(), -1, wxT("Invalid wxLuaState"));
1415     return wxlua_iswxluatype(luatype, wxl_type, M_WXLSTATEDATA->m_lua_State);
1416 }
1417 
IsUserDataType(int stack_idx,int wxl_type) const1418 bool wxLuaState::IsUserDataType(int stack_idx, int wxl_type) const
1419 {
1420     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1421     return wxluaT_isuserdatatype(M_WXLSTATEDATA->m_lua_State, stack_idx, wxl_type);
1422 }
1423 
GetUserDataType(int stack_idx,int wxl_type) const1424 void* wxLuaState::GetUserDataType(int stack_idx, int wxl_type) const
1425 {
1426     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1427     return wxluaT_getuserdatatype(M_WXLSTATEDATA->m_lua_State, stack_idx, wxl_type);
1428 }
1429 
GetStringType(int stack_idx)1430 const char* wxLuaState::GetStringType(int stack_idx)
1431 {
1432     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1433     return wxlua_getstringtype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1434 }
GetwxStringType(int stack_idx)1435 wxString wxLuaState::GetwxStringType(int stack_idx)
1436 {
1437     wxCHECK_MSG(Ok(), wxEmptyString, wxT("Invalid wxLuaState"));
1438     return wxlua_getwxStringtype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1439 }
GetBooleanType(int stack_idx)1440 bool wxLuaState::GetBooleanType(int stack_idx)
1441 {
1442     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1443     return wxlua_getbooleantype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1444 }
GetIntegerType(int stack_idx)1445 long wxLuaState::GetIntegerType(int stack_idx)
1446 {
1447     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1448     return wxlua_getintegertype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1449 }
GetNumberType(int stack_idx)1450 double wxLuaState::GetNumberType(int stack_idx)
1451 {
1452     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1453     return wxlua_getnumbertype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1454 }
1455 
IsStringType(int stack_idx) const1456 bool wxLuaState::IsStringType(int stack_idx) const
1457 {
1458     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1459     return wxlua_isstringtype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1460 }
1461 
IswxStringType(int stack_idx) const1462 bool wxLuaState::IswxStringType(int stack_idx) const
1463 {
1464     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1465     return wxlua_iswxstringtype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1466 }
1467 
IsBooleanType(int stack_idx) const1468 bool wxLuaState::IsBooleanType(int stack_idx) const
1469 {
1470     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1471     return wxlua_isbooleantype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1472 }
IsIntegerType(int stack_idx) const1473 bool wxLuaState::IsIntegerType(int stack_idx) const
1474 {
1475     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1476     return wxlua_isintegertype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1477 }
IsNumberType(int stack_idx) const1478 bool wxLuaState::IsNumberType(int stack_idx) const
1479 {
1480     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1481     return wxlua_isnumbertype(M_WXLSTATEDATA->m_lua_State, stack_idx);
1482 }
1483 
GetwxStringArray(int stack_idx,int & count)1484 wxString* wxLuaState::GetwxStringArray(int stack_idx, int &count)
1485 {
1486     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1487     return wxlua_getwxStringarray(M_WXLSTATEDATA->m_lua_State, stack_idx, count);
1488 }
1489 
GetwxArrayString(int stack_idx)1490 wxLuaSmartwxArrayString wxLuaState::GetwxArrayString(int stack_idx)
1491 {
1492     wxCHECK_MSG(Ok(), wxLuaSmartwxArrayString(NULL, true), wxT("Invalid wxLuaState"));
1493     return wxlua_getwxArrayString(M_WXLSTATEDATA->m_lua_State, stack_idx);
1494 }
1495 
GetCharArray(int stack_idx,int & count)1496 const char** wxLuaState::GetCharArray(int stack_idx, int &count)
1497 {
1498     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1499     return wxlua_getchararray(M_WXLSTATEDATA->m_lua_State, stack_idx, count);
1500 }
1501 
PushwxArrayStringTable(const wxArrayString & strArray)1502 int wxLuaState::PushwxArrayStringTable(const wxArrayString &strArray)
1503 {
1504     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1505     return wxlua_pushwxArrayStringtable(M_WXLSTATEDATA->m_lua_State, strArray);
1506 }
1507 
PushwxArrayIntTable(const wxArrayInt & intArray)1508 int wxLuaState::PushwxArrayIntTable(const wxArrayInt &intArray)
1509 {
1510     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1511     return wxlua_pushwxArrayInttable(M_WXLSTATEDATA->m_lua_State, intArray);
1512 }
1513 
GetIntArray(int stack_idx,int & count)1514 int* wxLuaState::GetIntArray(int stack_idx, int &count)
1515 {
1516     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1517     return wxlua_getintarray(M_WXLSTATEDATA->m_lua_State, stack_idx, count);
1518 }
1519 
GetwxArrayInt(int stack_idx)1520 wxLuaSmartwxArrayInt wxLuaState::GetwxArrayInt(int stack_idx)
1521 {
1522     wxCHECK_MSG(Ok(), wxLuaSmartwxArrayInt(NULL, true), wxT("Invalid wxLuaState"));
1523     return wxlua_getwxArrayInt(M_WXLSTATEDATA->m_lua_State, stack_idx);
1524 }
1525 
GetwxLuaTypeName(int wxl_type) const1526 wxString wxLuaState::GetwxLuaTypeName(int wxl_type) const
1527 {
1528     wxCHECK_MSG(Ok(), wxEmptyString, wxT("Invalid wxLuaState"));
1529     return wxluaT_typename(M_WXLSTATEDATA->m_lua_State, wxl_type);
1530 }
1531 
SetDerivedMethod(void * obj_ptr,const char * method_name,wxLuaObject * wxlObj)1532 bool wxLuaState::SetDerivedMethod(void *obj_ptr, const char *method_name, wxLuaObject* wxlObj)
1533 {
1534     wxCHECK_MSG(Ok() && obj_ptr, false, wxT("Invalid wxLuaState or object to set derived method for."));
1535     return wxlua_setderivedmethod(M_WXLSTATEDATA->m_lua_State, obj_ptr, method_name, wxlObj);
1536 }
1537 
HasDerivedMethod(const void * obj_ptr,const char * method_name,bool push_method) const1538 bool wxLuaState::HasDerivedMethod(const void *obj_ptr, const char *method_name, bool push_method) const
1539 {
1540     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1541     return wxlua_hasderivedmethod(M_WXLSTATEDATA->m_lua_State, obj_ptr, method_name, push_method);
1542 }
1543 
RemoveDerivedMethods(void * obj_ptr) const1544 bool wxLuaState::RemoveDerivedMethods(void *obj_ptr) const
1545 {
1546     wxCHECK_MSG(Ok() && obj_ptr, false, wxT("Invalid wxLuaState or object to remove."));
1547     return wxlua_removederivedmethods(M_WXLSTATEDATA->m_lua_State, obj_ptr);
1548 }
1549 
GetDerivedMethodState(void * obj_ptr,const char * method_name)1550 wxLuaState wxLuaState::GetDerivedMethodState(void *obj_ptr, const char *method_name)
1551 {
1552     wxCHECK_MSG(obj_ptr, wxNullLuaState, wxT("Invalid object to wxLuaState::GetDerivedMethod"));
1553 
1554     wxHashMapLuaState::iterator it;
1555     for (it = wxLuaState::s_wxHashMapLuaState.begin();
1556          it != wxLuaState::s_wxHashMapLuaState.end(); ++it)
1557     {
1558         wxLuaState wxlState(*(wxLuaState*)it->second);
1559         if (wxlState.HasDerivedMethod(obj_ptr, method_name, false))
1560             return wxlState;
1561     }
1562 
1563     return wxNullLuaState;
1564 }
1565 
1566 // ----------------------------------------------------------------------------
1567 // Raw basic Lua stack functions.
1568 
lua_GetTop() const1569 int wxLuaState::lua_GetTop() const
1570 {
1571     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1572     return lua_gettop(M_WXLSTATEDATA->m_lua_State);
1573 }
lua_SetTop(int index)1574 void wxLuaState::lua_SetTop(int index)
1575 {
1576     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1577     lua_settop(M_WXLSTATEDATA->m_lua_State, index);
1578 }
lua_PushValue(int index)1579 void wxLuaState::lua_PushValue(int index)
1580 {
1581     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1582     lua_pushvalue(M_WXLSTATEDATA->m_lua_State, index);
1583 }
lua_Remove(int index)1584 void wxLuaState::lua_Remove(int index)
1585 {
1586     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1587     lua_remove(M_WXLSTATEDATA->m_lua_State, index);
1588 }
lua_Pop(int count) const1589 void wxLuaState::lua_Pop(int count) const
1590 {
1591     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1592     lua_pop(M_WXLSTATEDATA->m_lua_State, count);
1593 }
lua_Insert(int index)1594 void wxLuaState::lua_Insert(int index)
1595 {
1596     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1597     lua_insert(M_WXLSTATEDATA->m_lua_State, index);
1598 }
lua_Replace(int index)1599 void wxLuaState::lua_Replace(int index)
1600 {
1601     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1602     lua_replace(M_WXLSTATEDATA->m_lua_State, index);
1603 }
lua_CheckStack(int size)1604 int wxLuaState::lua_CheckStack(int size)
1605 {
1606     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1607     return lua_checkstack(M_WXLSTATEDATA->m_lua_State, size);
1608 }
lua_XMove(const wxLuaState & to,int n)1609 void wxLuaState::lua_XMove(const wxLuaState& to, int n)
1610 {
1611     wxCHECK_RET(Ok() && to.Ok(), wxT("Invalid wxLuaState"));
1612     lua_xmove(M_WXLSTATEDATA->m_lua_State, to.GetLuaState(), n);
1613 }
1614 
1615 // ----------------------------------------------------------------------------
1616 // access functions (stack -> C)
1617 
lua_IsNumber(int index) const1618 bool wxLuaState::lua_IsNumber(int index) const
1619 {
1620     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1621     return lua_isnumber(M_WXLSTATEDATA->m_lua_State, index) != 0;
1622 }
lua_IsString(int index) const1623 bool wxLuaState::lua_IsString(int index) const
1624 {
1625     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1626     return lua_isstring(M_WXLSTATEDATA->m_lua_State, index) != 0;
1627 }
lua_IsCFunction(int index) const1628 bool wxLuaState::lua_IsCFunction(int index) const
1629 {
1630     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1631     return lua_iscfunction(M_WXLSTATEDATA->m_lua_State, index) != 0;
1632 }
lua_IsUserdata(int index) const1633 bool wxLuaState::lua_IsUserdata(int index) const
1634 {
1635     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1636     return lua_isuserdata(M_WXLSTATEDATA->m_lua_State, index) != 0;
1637 }
lua_Type(int index) const1638 int wxLuaState::lua_Type(int index) const
1639 {
1640     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1641     return lua_type(M_WXLSTATEDATA->m_lua_State, index);
1642 }
lua_TypeName(int type) const1643 wxString wxLuaState::lua_TypeName(int type) const
1644 {
1645     wxCHECK_MSG(Ok(), wxEmptyString, wxT("Invalid wxLuaState"));
1646     return lua2wx(lua_typename(M_WXLSTATEDATA->m_lua_State, type));
1647 }
1648 
lua_Equal(int index1,int index2) const1649 int wxLuaState::lua_Equal(int index1, int index2) const
1650 {
1651     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1652     return lua_equal(M_WXLSTATEDATA->m_lua_State, index1, index2);
1653 }
lua_RawEqual(int index1,int index2) const1654 int wxLuaState::lua_RawEqual(int index1, int index2) const
1655 {
1656     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1657     return lua_rawequal(M_WXLSTATEDATA->m_lua_State, index1, index2);
1658 }
lua_LessThan(int index1,int index2) const1659 int wxLuaState::lua_LessThan(int index1, int index2) const
1660 {
1661     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1662     return lua_lessthan(M_WXLSTATEDATA->m_lua_State, index1, index2);
1663 }
1664 
lua_ToNumber(int index) const1665 double wxLuaState::lua_ToNumber(int index) const
1666 {
1667     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1668     return lua_tonumber(M_WXLSTATEDATA->m_lua_State, index);
1669 }
lua_ToInteger(int index) const1670 int wxLuaState::lua_ToInteger(int index) const
1671 {
1672     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1673     return lua_tointeger(M_WXLSTATEDATA->m_lua_State, index);
1674 }
lua_ToBoolean(int index) const1675 int wxLuaState::lua_ToBoolean(int index) const
1676 {
1677     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1678     return lua_toboolean(M_WXLSTATEDATA->m_lua_State, index);
1679 }
lua_ToString(int index) const1680 const char* wxLuaState::lua_ToString(int index) const
1681 {
1682     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1683     return lua_tostring(M_WXLSTATEDATA->m_lua_State, index);
1684 }
lua_TowxString(int index) const1685 wxString wxLuaState::lua_TowxString(int index) const
1686 {
1687     wxCHECK_MSG(Ok(), wxEmptyString, wxT("Invalid wxLuaState"));
1688     return lua2wx(lua_tostring(M_WXLSTATEDATA->m_lua_State, index));
1689 }
lua_StrLen(int index) const1690 size_t wxLuaState::lua_StrLen(int index) const
1691 {
1692     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1693     return lua_strlen(M_WXLSTATEDATA->m_lua_State, index);
1694 }
luaL_ObjLen(int t) const1695 size_t wxLuaState::luaL_ObjLen(int t) const
1696 {
1697     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1698     return lua_objlen(M_WXLSTATEDATA->m_lua_State, t);
1699 }
lua_ToCFunction(int index) const1700 lua_CFunction wxLuaState::lua_ToCFunction(int index) const
1701 {
1702     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1703     return lua_tocfunction(M_WXLSTATEDATA->m_lua_State, index);
1704 }
lua_ToUserdata(int index) const1705 void *wxLuaState::lua_ToUserdata(int index) const
1706 {
1707     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1708     return lua_touserdata(M_WXLSTATEDATA->m_lua_State, index);
1709 }
lua_ToThread(int index) const1710 wxLuaState wxLuaState::lua_ToThread(int index) const
1711 {
1712     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1713     return wxLuaState(lua_tothread(M_WXLSTATEDATA->m_lua_State, index));
1714 }
lua_ToPointer(int index) const1715 const void* wxLuaState::lua_ToPointer(int index) const
1716 {
1717     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1718     return lua_topointer(M_WXLSTATEDATA->m_lua_State, index);
1719 }
1720 
1721 // ----------------------------------------------------------------------------
1722 // Raw Lua push functions (C -> stack)
1723 
lua_PushNil()1724 void wxLuaState::lua_PushNil()
1725 {
1726     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1727     lua_pushnil(M_WXLSTATEDATA->m_lua_State);
1728 }
lua_PushNumber(lua_Number n)1729 void wxLuaState::lua_PushNumber(lua_Number n)
1730 {
1731     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1732     lua_pushnumber(M_WXLSTATEDATA->m_lua_State, n);
1733 }
lua_PushInteger(lua_Integer n)1734 void wxLuaState::lua_PushInteger(lua_Integer n)
1735 {
1736     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1737     lua_pushinteger(M_WXLSTATEDATA->m_lua_State, n);
1738 }
lua_PushLString(const char * s,size_t len)1739 void wxLuaState::lua_PushLString(const char* s, size_t len)
1740 {
1741     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1742     lua_pushlstring(M_WXLSTATEDATA->m_lua_State, s, len);
1743 }
lua_PushString(const char * s)1744 void wxLuaState::lua_PushString(const char* s)
1745 {
1746     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1747     lua_pushstring(M_WXLSTATEDATA->m_lua_State, s);
1748 }
lua_PushCClosure(lua_CFunction fn,int n)1749 void wxLuaState::lua_PushCClosure(lua_CFunction fn, int n)
1750 {
1751     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1752     lua_pushcclosure(M_WXLSTATEDATA->m_lua_State, fn, n);
1753 }
lua_PushBoolean(bool b)1754 void wxLuaState::lua_PushBoolean(bool b)
1755 {
1756     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1757     lua_pushboolean(M_WXLSTATEDATA->m_lua_State, b ? 1 : 0);
1758 }
lua_PushLightUserdata(void * p)1759 void wxLuaState::lua_PushLightUserdata(void* p)
1760 {
1761     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1762     lua_pushlightuserdata(M_WXLSTATEDATA->m_lua_State, p);
1763 }
1764 
1765 // ----------------------------------------------------------------------------
1766 // Raw Lua get functions (Lua -> stack)
1767 
lua_GetTable(int idx)1768 void wxLuaState::lua_GetTable(int idx)
1769 {
1770     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1771     lua_gettable(M_WXLSTATEDATA->m_lua_State, idx);
1772 }
lua_GetField(int idx,const char * k)1773 void wxLuaState::lua_GetField(int idx, const char* k)
1774 {
1775     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1776     lua_getfield(M_WXLSTATEDATA->m_lua_State, idx, k);
1777 }
lua_RawGet(int idx)1778 void wxLuaState::lua_RawGet(int idx)
1779 {
1780     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1781     lua_rawget(M_WXLSTATEDATA->m_lua_State, idx);
1782 }
lua_RawGeti(int idx,int n)1783 void wxLuaState::lua_RawGeti(int idx, int n)
1784 {
1785     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1786     lua_rawgeti(M_WXLSTATEDATA->m_lua_State, idx, n);
1787 }
lua_CreateTable(int narr,int nrec)1788 void wxLuaState::lua_CreateTable(int narr, int nrec)
1789 {
1790     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1791     lua_createtable(M_WXLSTATEDATA->m_lua_State, narr, nrec);
1792 }
lua_NewTable()1793 void wxLuaState::lua_NewTable()
1794 {
1795     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1796     lua_newtable(M_WXLSTATEDATA->m_lua_State);
1797 }
lua_NewUserdata(size_t sz)1798 void* wxLuaState::lua_NewUserdata(size_t sz)
1799 {
1800     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
1801     return lua_newuserdata(M_WXLSTATEDATA->m_lua_State, sz);
1802 }
lua_GetMetatable(int objindex)1803 int wxLuaState::lua_GetMetatable(int objindex)
1804 {
1805     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1806     return lua_getmetatable(M_WXLSTATEDATA->m_lua_State, objindex);
1807 }
1808 
1809 #if LUA_VERSION_NUM < 502
lua_GetFenv(int idx)1810 void wxLuaState::lua_GetFenv(int idx)
1811 {
1812     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1813     lua_getfenv(M_WXLSTATEDATA->m_lua_State, idx);
1814 }
1815 #endif // LUA_VERSION_NUM < 502
1816 
1817 // -----------------------------------------------------------------------
1818 // Raw Lua set functions (stack -> Lua)
1819 
lua_SetTable(int idx)1820 void wxLuaState::lua_SetTable(int idx)
1821 {
1822     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1823     lua_settable(M_WXLSTATEDATA->m_lua_State, idx);
1824 }
lua_SetField(int idx,const char * k)1825 void wxLuaState::lua_SetField(int idx, const char* k)
1826 {
1827     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1828     lua_setfield(M_WXLSTATEDATA->m_lua_State, idx, k);
1829 }
lua_RawSet(int idx)1830 void wxLuaState::lua_RawSet(int idx)
1831 {
1832     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1833     lua_rawset(M_WXLSTATEDATA->m_lua_State, idx);
1834 }
lua_RawSeti(int idx,int n)1835 void wxLuaState::lua_RawSeti(int idx, int n)
1836 {
1837     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1838     lua_rawseti(M_WXLSTATEDATA->m_lua_State, idx, n);
1839 }
lua_SetMetatable(int objindex)1840 int wxLuaState::lua_SetMetatable(int objindex)
1841 {
1842     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1843     return lua_setmetatable(M_WXLSTATEDATA->m_lua_State, objindex);
1844 }
1845 
1846 #if LUA_VERSION_NUM < 502
lua_SetFenv(int idx)1847 int wxLuaState::lua_SetFenv(int idx)
1848 {
1849     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1850     return lua_setfenv(M_WXLSTATEDATA->m_lua_State, idx);
1851 }
1852 #endif // LUA_VERSION_NUM < 502
1853 
1854 // ----------------------------------------------------------------------------
1855 // Raw Lua `load' and `call' functions (load and run Lua code)
1856 
lua_Call(int nargs,int nresults)1857 void wxLuaState::lua_Call(int nargs, int nresults)
1858 {
1859     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1860     lua_call(M_WXLSTATEDATA->m_lua_State, nargs, nresults);
1861 }
lua_PCall(int nargs,int nresults,int errfunc)1862 int wxLuaState::lua_PCall(int nargs, int nresults, int errfunc)
1863 {
1864     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1865     return lua_pcall(M_WXLSTATEDATA->m_lua_State, nargs, nresults, errfunc);
1866 }
lua_CPCall(lua_CFunction func,void * ud)1867 int wxLuaState::lua_CPCall(lua_CFunction func, void *ud)
1868 {
1869     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1870 #if LUA_VERSION_NUM >= 503
1871     lua_pushcfunction(M_WXLSTATEDATA->m_lua_State, func);
1872     lua_pushlightuserdata(M_WXLSTATEDATA->m_lua_State, ud);
1873     return lua_pcall(M_WXLSTATEDATA->m_lua_State, 1, 0, 0);
1874 #else
1875     return lua_cpcall(M_WXLSTATEDATA->m_lua_State, func, ud);
1876 #endif
1877 }
1878 #if LUA_VERSION_NUM < 502
lua_Load(lua_Reader reader,void * dt,const char * chunkname)1879 int  wxLuaState::lua_Load(lua_Reader reader, void *dt, const char* chunkname)
1880 {
1881     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1882     return lua_load(M_WXLSTATEDATA->m_lua_State, reader, dt, chunkname);
1883 }
1884 #else
lua_Load(lua_Reader reader,void * dt,const char * chunkname,const char * mode)1885 int  wxLuaState::lua_Load(lua_Reader reader, void *dt, const char* chunkname, const char* mode)
1886 {
1887     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1888     return lua_load(M_WXLSTATEDATA->m_lua_State, reader, dt, chunkname, mode);
1889 }
1890 #endif // LUA_VERSION_NUM < 502
lua_Dump(lua_Writer writer,void * data)1891 int wxLuaState::lua_Dump(lua_Writer writer, void *data)
1892 {
1893     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1894     return lua_dump(M_WXLSTATEDATA->m_lua_State, writer, data
1895     // Lua 5.3+ requires additional parameter `int strip`
1896 #if LUA_VERSION_NUM >= 503
1897       , 0
1898 #endif
1899     );
1900 }
1901 
1902 // ----------------------------------------------------------------------------
1903 // Raw Lua coroutine functions
1904 
lua_Yield(int nresults)1905 int wxLuaState::lua_Yield(int nresults)
1906 {
1907     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1908     return lua_yield(M_WXLSTATEDATA->m_lua_State, nresults);
1909 }
1910 
1911 #if LUA_VERSION_NUM < 502
lua_Resume(int narg)1912 int wxLuaState::lua_Resume(int narg)
1913 {
1914     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1915     return lua_resume(M_WXLSTATEDATA->m_lua_State, narg);
1916 }
1917 #endif // LUA_VERSION_NUM < 502
1918 
lua_Status()1919 int wxLuaState::lua_Status()
1920 {
1921     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1922     return lua_status(M_WXLSTATEDATA->m_lua_State);
1923 }
1924 
1925 // ----------------------------------------------------------------------------
1926 // Raw Lua garbage-collection functions
1927 
lua_GC(int what,int data)1928 int wxLuaState::lua_GC(int what, int data)
1929 {
1930     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1931     return lua_gc(M_WXLSTATEDATA->m_lua_State, what, data);
1932 }
1933 
1934 // ----------------------------------------------------------------------------
1935 // Raw Lua miscellaneous functions
1936 
lua_Version() const1937 wxString wxLuaState::lua_Version() const
1938 {
1939     return lua2wx(LUA_VERSION);
1940 }
lua_Error()1941 int wxLuaState::lua_Error()
1942 {
1943     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1944     return lua_error(M_WXLSTATEDATA->m_lua_State);
1945 }
lua_Next(int idx)1946 int wxLuaState::lua_Next(int idx)
1947 {
1948     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
1949     return lua_next(M_WXLSTATEDATA->m_lua_State, idx);
1950 }
lua_Concat(int n)1951 void wxLuaState::lua_Concat(int n)
1952 {
1953     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1954     lua_concat(M_WXLSTATEDATA->m_lua_State, n);
1955 }
1956 
1957 // -----------------------------------------------------------------------
1958 // Raw Lua some useful "macros", lua.h
1959 
lua_Register(const char * funcName,lua_CFunction f)1960 void wxLuaState::lua_Register(const char* funcName, lua_CFunction f)
1961 {
1962     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1963     lua_register(M_WXLSTATEDATA->m_lua_State, funcName, f);
1964 }
lua_PushCFunction(lua_CFunction f)1965 void wxLuaState::lua_PushCFunction(lua_CFunction f)
1966 {
1967     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
1968     lua_pushcfunction(M_WXLSTATEDATA->m_lua_State, f);
1969 }
1970 
lua_IsFunction(int idx) const1971 bool wxLuaState::lua_IsFunction(int idx) const
1972 {
1973     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1974     return lua_isfunction(M_WXLSTATEDATA->m_lua_State, idx);
1975 }
lua_IsTable(int idx) const1976 bool wxLuaState::lua_IsTable(int idx) const
1977 {
1978     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1979     return lua_istable(M_WXLSTATEDATA->m_lua_State, idx);
1980 }
lua_IsLightUserdata(int idx) const1981 bool wxLuaState::lua_IsLightUserdata(int idx) const
1982 {
1983     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1984     return lua_islightuserdata(M_WXLSTATEDATA->m_lua_State, idx);
1985 }
lua_IsNil(int idx) const1986 bool wxLuaState::lua_IsNil(int idx) const
1987 {
1988     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1989     return lua_isnil(M_WXLSTATEDATA->m_lua_State, idx);
1990 }
lua_IsBoolean(int idx) const1991 bool wxLuaState::lua_IsBoolean(int idx) const
1992 {
1993     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1994     return lua_isboolean(M_WXLSTATEDATA->m_lua_State, idx);
1995 }
lua_IsThread(int idx) const1996 bool wxLuaState::lua_IsThread(int idx) const
1997 {
1998     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
1999     return lua_isthread(M_WXLSTATEDATA->m_lua_State, idx);
2000 }
lua_IsNone(int idx) const2001 bool wxLuaState::lua_IsNone(int idx) const
2002 {
2003     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
2004     return lua_isnone(M_WXLSTATEDATA->m_lua_State, idx);
2005 }
lua_IsNoneOrNil(int idx) const2006 bool wxLuaState::lua_IsNoneOrNil(int idx) const
2007 {
2008     wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState"));
2009     return lua_isnoneornil(M_WXLSTATEDATA->m_lua_State, idx);
2010 }
2011 
lua_SetGlobal(const char * s)2012 void wxLuaState::lua_SetGlobal(const char* s)
2013 {
2014     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2015     lua_setglobal(M_WXLSTATEDATA->m_lua_State, s);
2016 }
lua_GetGlobal(const char * s)2017 void wxLuaState::lua_GetGlobal(const char* s)
2018 {
2019     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2020     lua_getglobal(M_WXLSTATEDATA->m_lua_State, s);
2021 }
2022 
2023 // ----------------------------------------------------------------------------
2024 // Raw Lua Debug functions, lua.h
2025 
lua_GetStack(int level,lua_Debug * ar)2026 int wxLuaState::lua_GetStack(int level, lua_Debug* ar)
2027 {
2028     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2029     return lua_getstack(M_WXLSTATEDATA->m_lua_State, level, ar);
2030 }
lua_GetInfo(const char * what,lua_Debug * ar)2031 int wxLuaState::lua_GetInfo(const char* what, lua_Debug* ar)
2032 {
2033     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2034     return lua_getinfo(M_WXLSTATEDATA->m_lua_State, what, ar);
2035 }
lua_GetLocal(const lua_Debug * ar,int n)2036 const char* wxLuaState::lua_GetLocal(const lua_Debug* ar, int n)
2037 {
2038     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
2039     return lua_getlocal(M_WXLSTATEDATA->m_lua_State, ar, n);
2040 }
lua_SetLocal(const lua_Debug * ar,int n)2041 const char* wxLuaState::lua_SetLocal(const lua_Debug* ar, int n)
2042 {
2043     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
2044     return lua_setlocal(M_WXLSTATEDATA->m_lua_State, ar, n);
2045 }
lua_GetUpvalue(int funcindex,int n)2046 const char* wxLuaState::lua_GetUpvalue(int funcindex, int n)
2047 {
2048     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
2049     return lua_getupvalue(M_WXLSTATEDATA->m_lua_State, funcindex, n);
2050 }
lua_SetUpvalue(int funcindex,int n)2051 const char* wxLuaState::lua_SetUpvalue(int funcindex, int n)
2052 {
2053     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
2054     return lua_setupvalue(M_WXLSTATEDATA->m_lua_State, funcindex, n);
2055 }
2056 
lua_SetHook(lua_Hook func,int mask,int count)2057 void wxLuaState::lua_SetHook(lua_Hook func, int mask, int count)
2058 {
2059     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2060     lua_sethook(M_WXLSTATEDATA->m_lua_State, func, mask, count);
2061     // lua_sethook returns 1 for lua 5.1 & 5.2
2062     // lua_sethook is void in 5.3+
2063 }
2064 
lua_GetHook()2065 lua_Hook wxLuaState::lua_GetHook()
2066 {
2067     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2068     return lua_gethook(M_WXLSTATEDATA->m_lua_State);
2069 }
lua_GetHookMask()2070 int wxLuaState::lua_GetHookMask()
2071 {
2072     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2073     return lua_gethookmask(M_WXLSTATEDATA->m_lua_State);
2074 }
lua_GetHookCount()2075 int wxLuaState::lua_GetHookCount()
2076 {
2077     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2078     return lua_gethookcount(M_WXLSTATEDATA->m_lua_State);
2079 }
2080 
2081 // ----------------------------------------------------------------------------
2082 // Raw Lua auxlib functions, lauxlib.h
2083 
2084 #if LUA_VERSION_NUM >= 503
2085 extern "C" {
create_table(lua_State * L)2086     static int create_table(lua_State *L) {
2087         lua_newtable(L);
2088         return 1;
2089     }
2090 }
2091 #endif
luaL_Register(lua_State * L,const char * libname,const luaL_Reg * l)2092 void wxLuaState::luaL_Register(lua_State *L, const char *libname, const luaL_Reg *l)
2093 {
2094 #if LUA_VERSION_NUM >= 503
2095     // Do NOT use luaL_requiref with lua5.2, because with lua5.2 luaL_requiref always creates new module!
2096     // lua5.3 luaL_requiref creates new modul only if modname is not already present in package.loaded
2097     // call luaL_requiref with glb=true -> stores the module into global modname for backwards compatibility.
2098     luaL_requiref(L, libname, create_table, 1);
2099     luaL_setfuncs(L, l, 0);
2100 #else
2101     luaL_register(L, libname, l);
2102 #endif
2103 }
luaL_Register(const char * libname,const luaL_Reg * l)2104 void wxLuaState::luaL_Register(const char *libname, const luaL_Reg *l)
2105 {
2106     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2107 
2108     wxLuaState::luaL_Register(M_WXLSTATEDATA->m_lua_State, libname, l);
2109 }
luaL_GetMetafield(int obj,const char * e)2110 int wxLuaState::luaL_GetMetafield(int obj, const char *e)
2111 {
2112     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2113     return luaL_getmetafield(M_WXLSTATEDATA->m_lua_State, obj, e);
2114 }
luaL_CallMeta(int obj,const char * e)2115 int wxLuaState::luaL_CallMeta(int obj, const char *e)
2116 {
2117     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2118     return luaL_callmeta(M_WXLSTATEDATA->m_lua_State, obj, e);
2119 }
2120 #if LUA_VERSION_NUM < 502
luaL_TypeError(int narg,const char * tname)2121 int wxLuaState::luaL_TypeError(int narg, const char *tname)
2122 {
2123     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2124     return luaL_typerror(M_WXLSTATEDATA->m_lua_State, narg, tname);
2125 }
2126 #endif // LUA_VERSION_NUM < 502
luaL_ArgError(int numarg,const char * extramsg)2127 int wxLuaState::luaL_ArgError(int numarg, const char *extramsg)
2128 {
2129     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2130     return luaL_argerror(M_WXLSTATEDATA->m_lua_State, numarg, extramsg);
2131 }
luaL_CheckLString(int numArg,size_t * l)2132 const char* wxLuaState::luaL_CheckLString(int numArg, size_t *l)
2133 {
2134     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
2135     return luaL_checklstring(M_WXLSTATEDATA->m_lua_State, numArg, l);
2136 }
luaL_OptLString(int numArg,const char * def,size_t * l)2137 const char* wxLuaState::luaL_OptLString(int numArg, const char *def, size_t *l)
2138 {
2139     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
2140     return luaL_optlstring(M_WXLSTATEDATA->m_lua_State, numArg, def, l);
2141 }
luaL_CheckNumber(int numArg)2142 lua_Number wxLuaState::luaL_CheckNumber(int numArg)
2143 {
2144     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2145     return luaL_checknumber(M_WXLSTATEDATA->m_lua_State, numArg);
2146 }
luaL_OptNumber(int nArg,lua_Number def)2147 lua_Number wxLuaState::luaL_OptNumber(int nArg, lua_Number def)
2148 {
2149     wxCHECK_MSG(Ok(), def, wxT("Invalid wxLuaState"));
2150     return luaL_optnumber(M_WXLSTATEDATA->m_lua_State, nArg, def);
2151 }
luaL_CheckInteger(int numArg)2152 lua_Integer wxLuaState::luaL_CheckInteger(int numArg)
2153 {
2154     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2155     return luaL_checkinteger(M_WXLSTATEDATA->m_lua_State, numArg);
2156 }
luaL_OptInteger(int nArg,lua_Integer def)2157 lua_Integer wxLuaState::luaL_OptInteger(int nArg, lua_Integer def)
2158 {
2159     wxCHECK_MSG(Ok(), def, wxT("Invalid wxLuaState"));
2160     return luaL_optinteger(M_WXLSTATEDATA->m_lua_State, nArg, def);
2161 }
2162 
luaL_CheckStack(int sz,const char * msg)2163 void wxLuaState::luaL_CheckStack(int sz, const char *msg)
2164 {
2165     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2166     luaL_checkstack(M_WXLSTATEDATA->m_lua_State, sz, msg);
2167 }
luaL_CheckType(int narg,int t)2168 void wxLuaState::luaL_CheckType(int narg, int t)
2169 {
2170     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2171     luaL_checktype(M_WXLSTATEDATA->m_lua_State, narg, t);
2172 }
luaL_CheckAny(int narg)2173 void wxLuaState::luaL_CheckAny(int narg)
2174 {
2175     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2176     luaL_checkany(M_WXLSTATEDATA->m_lua_State, narg);
2177 }
2178 
luaL_NewMetatable(const char * tname)2179 int   wxLuaState::luaL_NewMetatable(const char *tname)
2180 {
2181     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2182     return luaL_newmetatable(M_WXLSTATEDATA->m_lua_State, tname);
2183 }
luaL_GetMetatable(const char * tname)2184 void  wxLuaState::luaL_GetMetatable(const char *tname)
2185 {
2186     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2187     luaL_getmetatable(M_WXLSTATEDATA->m_lua_State, tname);
2188 }
luaL_CheckUdata(int ud,const char * tname)2189 void* wxLuaState::luaL_CheckUdata(int ud, const char *tname)
2190 {
2191     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
2192     return luaL_checkudata(M_WXLSTATEDATA->m_lua_State, ud, tname);
2193 }
2194 
luaL_Where(int lvl)2195 void wxLuaState::luaL_Where(int lvl)
2196 {
2197     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2198     luaL_where(M_WXLSTATEDATA->m_lua_State, lvl);
2199 }
luaL_Error(const char * fmt,...)2200 int wxLuaState::luaL_Error(const char *fmt, ...)
2201 {
2202     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2203     return luaL_error(M_WXLSTATEDATA->m_lua_State, fmt);
2204 }
2205 
luaL_CheckOption(int narg,const char * def,const char * const lst[])2206 int wxLuaState::luaL_CheckOption(int narg, const char *def, const char *const lst[])
2207 {
2208     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2209     return luaL_checkoption(M_WXLSTATEDATA->m_lua_State, narg, def, lst);
2210 }
2211 
luaL_Ref(int t)2212 int wxLuaState::luaL_Ref(int t)
2213 {
2214     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2215     return luaL_ref(M_WXLSTATEDATA->m_lua_State, t);
2216 }
luaL_Unref(int t,int ref)2217 void wxLuaState::luaL_Unref(int t, int ref)
2218 {
2219     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2220     luaL_unref(M_WXLSTATEDATA->m_lua_State, t, ref);
2221 }
2222 
luaL_LoadFile(const char * filename)2223 int wxLuaState::luaL_LoadFile(const char *filename)
2224 {
2225     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2226     return luaL_loadfile(M_WXLSTATEDATA->m_lua_State, filename);
2227 }
luaL_LoadBuffer(const char * buff,size_t sz,const char * name)2228 int wxLuaState::luaL_LoadBuffer(const char *buff, size_t sz, const char *name)
2229 {
2230     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2231     return luaL_loadbuffer(M_WXLSTATEDATA->m_lua_State, buff, sz, name);
2232 }
luaL_LoadString(const char * s)2233 int wxLuaState::luaL_LoadString(const char *s)
2234 {
2235     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2236     return luaL_loadstring(M_WXLSTATEDATA->m_lua_State, s);
2237 }
2238 
luaL_ArgCheck(bool condition,int numarg,const char * extramsg)2239 void wxLuaState::luaL_ArgCheck(bool condition, int numarg, const char* extramsg)
2240 {
2241     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2242     luaL_argcheck(M_WXLSTATEDATA->m_lua_State, condition, numarg, extramsg);
2243 }
luaL_CheckString(int numArg)2244 const char* wxLuaState::luaL_CheckString(int numArg)
2245 {
2246     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
2247     return luaL_checkstring(M_WXLSTATEDATA->m_lua_State, numArg);
2248 }
luaL_OptString(int numArg,const char * def)2249 const char* wxLuaState::luaL_OptString(int numArg, const char* def)
2250 {
2251     wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState"));
2252     return luaL_optstring(M_WXLSTATEDATA->m_lua_State, numArg, def);
2253 }
luaL_CheckInt(int numArg)2254 int wxLuaState::luaL_CheckInt(int numArg)
2255 {
2256     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2257 #if LUA_VERSION_NUM >= 502
2258     return (int)luaL_checkinteger(M_WXLSTATEDATA->m_lua_State, numArg);
2259 #else
2260     return (int)luaL_checkint(M_WXLSTATEDATA->m_lua_State, numArg);
2261 #endif
2262 }
luaL_OptInt(int numArg,int def)2263 int wxLuaState::luaL_OptInt(int numArg, int def)
2264 {
2265     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2266 #if LUA_VERSION_NUM >= 502
2267     return (int)luaL_optinteger(M_WXLSTATEDATA->m_lua_State, numArg, def);
2268 #else
2269     return (int)luaL_optint(M_WXLSTATEDATA->m_lua_State, numArg, def);
2270 #endif
2271 }
luaL_CheckLong(int numArg)2272 long wxLuaState::luaL_CheckLong(int numArg)
2273 {
2274     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2275 #if LUA_VERSION_NUM >= 502
2276     return (long)luaL_checkinteger(M_WXLSTATEDATA->m_lua_State, numArg);
2277 #else
2278     return (long)luaL_checklong(M_WXLSTATEDATA->m_lua_State, numArg);
2279 #endif
2280 }
luaL_OptLong(int numArg,int def)2281 long wxLuaState::luaL_OptLong(int numArg, int def)
2282 {
2283     wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState"));
2284 #if LUA_VERSION_NUM >= 502
2285     return (long)luaL_optinteger(M_WXLSTATEDATA->m_lua_State, numArg, def);
2286 #else
2287     return (long)luaL_optlong(M_WXLSTATEDATA->m_lua_State, numArg, def);
2288 #endif
2289 }
2290 
2291 // ----------------------------------------------------------------------------
2292 // others
2293 
GetGlobals()2294 void wxLuaState::GetGlobals()
2295 {
2296     wxCHECK_RET(Ok(), wxT("Invalid wxLuaState"));
2297     lua_pushglobaltable(M_WXLSTATEDATA->m_lua_State);
2298 }
2299 
2300 #define LUA_PATH "LUA_PATH"
2301 
2302 // get LUA_PATH
GetLuaPath()2303 wxString wxLuaState::GetLuaPath()
2304 {
2305     wxCHECK_MSG(Ok(), wxEmptyString, wxT("Invalid wxLuaState"));
2306     lua_GetGlobal(LUA_PATH);
2307     wxString path = lua_TowxString(-1);
2308     lua_Pop(1);
2309 
2310     return path;
2311 }
2312 
2313 // add path list to LUA_PATH
AddLuaPath(const wxPathList & pathlist)2314 void wxLuaState::AddLuaPath(const wxPathList& pathlist)
2315 {
2316     size_t i, count = pathlist.GetCount();
2317     for (i = 0; i < count; ++i)
2318     {
2319         wxFileName fname(pathlist[i]);
2320         AddLuaPath(fname);
2321     }
2322 }
2323 
2324 // add filename path to LUA_PATH
AddLuaPath(const wxFileName & filename)2325 void wxLuaState::AddLuaPath(const wxFileName& filename)
2326 {
2327     wxFileName fname = filename;
2328     fname.SetName(wxT("?"));
2329     fname.SetExt(wxT("lua"));
2330 
2331     wxString path    = fname.GetFullPath();
2332     wxString luapath = GetLuaPath();
2333 
2334     // check if path
2335     wxStringTokenizer tkz(luapath, wxT(";"));
2336     while (tkz.HasMoreTokens())
2337     {
2338         wxString token = tkz.GetNextToken();
2339 
2340         if ((token == path) || (!wxFileName::IsCaseSensitive() && token.CmpNoCase(path) == 0))
2341             return;
2342     }
2343 
2344     // append separator
2345     if (!luapath.IsEmpty() && (luapath.Last() != wxT(';')))
2346         luapath += wxT(';');
2347 
2348     // append path
2349     luapath += path + wxT(';');
2350 
2351     lua_PushString(luapath.c_str());
2352     lua_SetGlobal(LUA_PATH);
2353 }
2354 
2355 //-----------------------------------------------------------------------------
2356 // wxLuaEvent
2357 //-----------------------------------------------------------------------------
2358 
2359 #if wxCHECK_VERSION(3,0,0)
2360 wxDEFINE_EVENT(wxEVT_LUA_CREATION, wxLuaEvent);
2361 wxDEFINE_EVENT(wxEVT_LUA_PRINT, wxLuaEvent);
2362 wxDEFINE_EVENT(wxEVT_LUA_ERROR, wxLuaEvent);
2363 wxDEFINE_EVENT(wxEVT_LUA_DEBUG_HOOK, wxLuaEvent);
2364 #else
2365 DEFINE_LOCAL_EVENT_TYPE(wxEVT_LUA_CREATION)
DEFINE_LOCAL_EVENT_TYPE(wxEVT_LUA_PRINT)2366 DEFINE_LOCAL_EVENT_TYPE(wxEVT_LUA_PRINT)
2367 DEFINE_LOCAL_EVENT_TYPE(wxEVT_LUA_ERROR)
2368 DEFINE_LOCAL_EVENT_TYPE(wxEVT_LUA_DEBUG_HOOK)
2369 //DEFINE_LOCAL_EVENT_TYPE(wxEVT_LUA_INIT)
2370 //DEFINE_LOCAL_EVENT_TYPE(wxEVT_LUA_DEBUGGERATTACHED)
2371 #endif
2372 
2373 wxLuaEvent::wxLuaEvent(wxEventType commandType, wxWindowID id, const wxLuaState& wxlState)
2374            :wxNotifyEvent(commandType, id),  m_wxlState(wxlState),
2375             m_debug_hook_break(false),
2376             m_lua_Debug(NULL)
2377 {
2378 }
2379 
wxLuaEvent(const wxLuaEvent & event)2380 wxLuaEvent::wxLuaEvent( const wxLuaEvent &event )
2381            :wxNotifyEvent(event), m_wxlState(event.m_wxlState),
2382             m_debug_hook_break(event.m_debug_hook_break),
2383             m_lua_Debug(event.m_lua_Debug)
2384 {
2385 }
2386