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