00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "wx/wxprec.h"
00011
00012 #ifdef __BORLANDC__
00013 #pragma hdrstop
00014 #endif
00015
00016 #ifndef WX_PRECOMP
00017 #include "wx/wx.h"
00018 #endif
00019
00020 #include "wxlua/include/wxlbind.h"
00021 #include "wxlua/include/wxlstate.h"
00022
00023
00024
00025 const wxLuaSmartwxArrayString wxLuaNullSmartwxArrayString(NULL, true);
00026
00027
00028 #include "wx/listimpl.cpp"
00029 WX_DEFINE_LIST(wxLuaBindingList);
00030
00031 wxLuaArgType g_wxluaargtypeArray_None[1] = {0};
00032 wxLuaBindNumber g_wxluanumberArray_None[1] = {{0, 0}};
00033
00034 int wxluatype_TNONE = WXLUA_TNONE;
00035 int wxluatype_TNIL = WXLUA_TNIL;
00036 int wxluatype_TBOOLEAN = WXLUA_TBOOLEAN;
00037 int wxluatype_TLIGHTUSERDATA = WXLUA_TLIGHTUSERDATA;
00038 int wxluatype_TNUMBER = WXLUA_TNUMBER;
00039 int wxluatype_TSTRING = WXLUA_TSTRING;
00040 int wxluatype_TTABLE = WXLUA_TTABLE;
00041 int wxluatype_TFUNCTION = WXLUA_TFUNCTION;
00042 int wxluatype_TUSERDATA = WXLUA_TUSERDATA;
00043 int wxluatype_TTHREAD = WXLUA_TTHREAD;
00044 int wxluatype_TINTEGER = WXLUA_TINTEGER;
00045 int wxluatype_TCFUNCTION = WXLUA_TCFUNCTION;
00046
00047 int wxluatype_NULL = WXLUATYPE_NULL;
00048
00049 wxLuaBindClass wxLuaBindClass_NULL =
00050 { "NULL", NULL, 0, NULL, &wxluatype_NULL, NULL, NULL, g_wxluanumberArray_None, 0, };
00051
00052 static int wxluatype_dummy = WXLUA_TUNKNOWN;
00053 int* p_wxluatype_wxEvent = &wxluatype_dummy;
00054 int* p_wxluatype_wxWindow = &wxluatype_dummy;
00055 int* p_wxluatype_wxString = &wxluatype_dummy;
00056 int* p_wxluatype_wxArrayString = &wxluatype_dummy;
00057 int* p_wxluatype_wxSortedArrayString = &wxluatype_dummy;
00058 int* p_wxluatype_wxArrayInt = &wxluatype_dummy;
00059
00060
00061
00062
00063 IMPLEMENT_ABSTRACT_CLASS(wxLuaObject, wxObject)
00064
00065 wxLuaObject::wxLuaObject(const wxLuaState& wxlState, int stack_idx)
00066 : m_wxlState(new wxLuaState(wxlState)),
00067 m_alloc_flag(wxLUAOBJECT_NONE),
00068 m_int(0)
00069
00070 {
00071
00072 m_reference = m_wxlState->wxluaR_Ref(stack_idx, &wxlua_lreg_refs_key);
00073 }
00074
00075 wxLuaObject::~wxLuaObject()
00076 {
00077 if (m_alloc_flag == wxLUAOBJECT_STRING)
00078 delete m_string;
00079 else if (m_alloc_flag == wxLUAOBJECT_ARRAYINT)
00080 delete m_arrayInt;
00081
00082
00083 if ((m_reference != LUA_NOREF) && m_wxlState->Ok() && !m_wxlState->IsClosing())
00084 m_wxlState->wxluaR_Unref(m_reference, &wxlua_lreg_refs_key);
00085
00086 delete m_wxlState;
00087 }
00088
00089 wxLuaState wxLuaObject::GetwxLuaState() const
00090 {
00091 return (m_wxlState != NULL) ? *m_wxlState : wxNullLuaState;
00092 }
00093
00094 bool wxLuaObject::GetObject()
00095 {
00096 wxCHECK_MSG(m_wxlState->Ok(), false, wxT("Invalid wxLuaState"));
00097 lua_State* L = m_wxlState->GetLuaState();
00098
00099 if (m_alloc_flag == wxLUAOBJECT_BOOL)
00100 {
00101 lua_pushboolean(L, m_bool);
00102 return true;
00103 }
00104 else if (m_alloc_flag == wxLUAOBJECT_INT)
00105 {
00106 lua_pushnumber(L, m_int);
00107 return true;
00108 }
00109 else if (m_alloc_flag == wxLUAOBJECT_STRING)
00110 {
00111 lua_pushstring(L, wx2lua(*m_string));
00112 return true;
00113 }
00114 else if (m_alloc_flag == wxLUAOBJECT_ARRAYINT)
00115 {
00116 wxlua_pushwxArrayInttable(L, *m_arrayInt);
00117 return true;
00118 }
00119 else if (wxluaR_getref(L, m_reference, &wxlua_lreg_refs_key))
00120 return true;
00121
00122 return false;
00123 }
00124
00125 void wxLuaObject::SetObject(int stack_idx)
00126 {
00127 wxCHECK_RET(m_wxlState->Ok(), wxT("Invalid wxLuaState"));
00128
00129 if (m_reference != LUA_NOREF)
00130 m_wxlState->wxluaR_Unref(m_reference, &wxlua_lreg_refs_key);
00131
00132 m_reference = m_wxlState->wxluaR_Ref(stack_idx, &wxlua_lreg_refs_key);
00133 }
00134
00135 bool *wxLuaObject::GetBoolPtr()
00136 {
00137 wxCHECK_MSG(m_wxlState->Ok(), 0, wxT("Invalid wxLuaState"));
00138 wxCHECK_MSG(m_alloc_flag == wxLUAOBJECT_NONE, 0, wxT("wxLuaObject already initialized in wxLuaObject::GetBoolPtr"));
00139
00140 if ((m_reference != LUA_NOREF) && GetObject())
00141 {
00142 m_bool = (m_wxlState->lua_ToBoolean(-1) != 0);
00143 m_alloc_flag = wxLUAOBJECT_BOOL;
00144 m_wxlState->lua_Pop(1);
00145 }
00146 return &m_bool;
00147 }
00148
00149 int *wxLuaObject::GetIntPtr()
00150 {
00151 wxCHECK_MSG(m_wxlState->Ok(), false, wxT("Invalid wxLuaState"));
00152 wxCHECK_MSG(m_alloc_flag == wxLUAOBJECT_NONE, 0, wxT("wxLuaObject already initialized in wxLuaObject::GetIntPtr"));
00153
00154 if ((m_reference != LUA_NOREF) && GetObject())
00155 {
00156 m_int = (int)m_wxlState->lua_ToNumber(-1);
00157 m_alloc_flag = wxLUAOBJECT_INT;
00158 m_wxlState->lua_Pop(1);
00159 }
00160 return &m_int;
00161 }
00162
00163 wxString *wxLuaObject::GetStringPtr()
00164 {
00165 wxCHECK_MSG(m_wxlState->Ok(), false, wxT("Invalid wxLuaState"));
00166 wxCHECK_MSG(m_alloc_flag == wxLUAOBJECT_NONE, 0, wxT("wxLuaObject already initialized in wxLuaObject::GetStringPtr"));
00167
00168 m_string = new wxString();
00169
00170 if ((m_reference != LUA_NOREF) && GetObject())
00171 {
00172 *m_string = m_wxlState->lua_TowxString(-1);
00173 m_alloc_flag = wxLUAOBJECT_STRING;
00174 m_wxlState->lua_Pop(1);
00175 }
00176
00177 return m_string;
00178 }
00179
00180 wxArrayInt *wxLuaObject::GetArrayPtr()
00181 {
00182 wxCHECK_MSG(m_wxlState->Ok(), false, wxT("Invalid wxLuaState"));
00183 wxCHECK_MSG(m_alloc_flag == wxLUAOBJECT_NONE, 0, wxT("wxLuaObject already initialized in wxLuaObject::GetArrayPtr"));
00184
00185 m_arrayInt = new wxArrayInt();
00186
00187 if ((m_reference != LUA_NOREF) && GetObject())
00188 {
00189 *m_arrayInt = (wxArrayInt&)m_wxlState->GetwxArrayInt(-1);
00190 m_alloc_flag = wxLUAOBJECT_ARRAYINT;
00191 m_wxlState->lua_Pop(1);
00192 }
00193 return m_arrayInt;
00194 }
00195
00196
00197
00198
00199
00200 class wxLuaSmartwxArrayStringRefData : public wxObjectRefData
00201 {
00202 public:
00203 wxLuaSmartwxArrayStringRefData(wxArrayString* arr, int del) : m_arr(arr), m_delete(del)
00204 {
00205 if (!m_arr) { m_arr = new wxArrayString; m_delete = true; }
00206 }
00207
00208 virtual ~wxLuaSmartwxArrayStringRefData() { if (m_delete) delete m_arr; }
00209
00210 wxArrayString *m_arr;
00211 bool m_delete;
00212 };
00213
00214 wxLuaSmartwxArrayString::wxLuaSmartwxArrayString(wxArrayString *arr, bool del)
00215 {
00216 m_refData = new wxLuaSmartwxArrayStringRefData(arr, del);
00217 }
00218 wxArrayString* wxLuaSmartwxArrayString::GetArray() const
00219 {
00220 return ((wxLuaSmartwxArrayStringRefData*)m_refData)->m_arr;
00221 }
00222
00223
00224
00225
00226
00227 class wxLuaSmartwxSortedArrayStringRefData : public wxObjectRefData
00228 {
00229 public:
00230 wxLuaSmartwxSortedArrayStringRefData(wxSortedArrayString* arr, int del) : m_arr(arr), m_delete(del)
00231 {
00232 if (!m_arr) { m_arr = new wxSortedArrayString; m_delete = true; }
00233 }
00234
00235 virtual ~wxLuaSmartwxSortedArrayStringRefData() { if (m_delete) delete m_arr; }
00236
00237 wxSortedArrayString *m_arr;
00238 bool m_delete;
00239 };
00240
00241 wxLuaSmartwxSortedArrayString::wxLuaSmartwxSortedArrayString(wxSortedArrayString *arr, bool del)
00242 {
00243 m_refData = new wxLuaSmartwxSortedArrayStringRefData(arr, del);
00244 }
00245 wxSortedArrayString* wxLuaSmartwxSortedArrayString::GetArray() const
00246 {
00247 return ((wxLuaSmartwxSortedArrayStringRefData*)m_refData)->m_arr;
00248 }
00249
00250
00251
00252
00253
00254 class wxLuaSmartwxArrayIntRefData : public wxObjectRefData
00255 {
00256 public:
00257 wxLuaSmartwxArrayIntRefData(wxArrayInt* arr, int del) : m_arr(arr), m_delete(del)
00258 {
00259 if (!m_arr) { m_arr = new wxArrayInt; m_delete = true; }
00260 }
00261
00262 virtual ~wxLuaSmartwxArrayIntRefData() { if (m_delete) delete m_arr; }
00263
00264 wxArrayInt *m_arr;
00265 bool m_delete;
00266 };
00267
00268 wxLuaSmartwxArrayInt::wxLuaSmartwxArrayInt(wxArrayInt *arr, bool del)
00269 {
00270 m_refData = new wxLuaSmartwxArrayIntRefData(arr, del);
00271 }
00272
00273 wxArrayInt* wxLuaSmartwxArrayInt::GetArray() const
00274 {
00275 return ((wxLuaSmartwxArrayIntRefData*)m_refData)->m_arr;
00276 }
00277
00278
00279
00280
00281
00282 static int LUACALL wxlua_tableErrorHandler(lua_State *L)
00283 {
00284 wxlua_error(L, "Cannot modify read-only wxLua table");
00285 return 0;
00286 }
00287
00288
00289
00290
00291
00292 int LUACALL wxlua_userdata_delete(lua_State *L)
00293 {
00294 void* udata = lua_touserdata(L, 1);
00295 void* obj_ptr = wxlua_touserdata(L, 1, false);
00296
00297
00298 if ((obj_ptr != NULL) && wxluaO_deletegcobject(L, udata, obj_ptr, WXLUA_DELETE_OBJECT_ALL))
00299 {
00300 lua_pushnil(L);
00301 lua_setmetatable(L, -2);
00302 }
00303 else
00304 {
00305 wxString msg;
00306 msg.Printf(wxT("wxLua: Unable to call wxuserdata:delete() on object %p, someone else owns it."), obj_ptr);
00307
00308
00309 wxPrintf(wxString(msg + wxT("\n")).c_str());
00310 wxlua_argerrormsg(L, msg);
00311 }
00312
00313 return 0;
00314 }
00315
00316
00317
00318
00319
00320 int LUACALL wxlua_wxLuaBindClass__gc(lua_State *L)
00321 {
00322 wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1));
00323
00324 if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxluaT_type(L, 1) == *wxlClass->wxluatype))
00325 {
00326 void* udata = lua_touserdata(L, 1);
00327 void* obj_ptr = wxlua_touserdata(L, 1, true);
00328
00329
00330 wxluaO_deletegcobject(L, udata, obj_ptr, WXLUA_DELETE_OBJECT_LAST);
00331 }
00332
00333 return 0;
00334 }
00335
00336
00337
00338
00339
00340 int LUACALL wxlua_wxLuaBindClass__index(lua_State *L)
00341 {
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 wxlua_setcallbaseclassfunction(L, false);
00353
00354 bool found = false;
00355 int result = 0;
00356 wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1));
00357 wxCHECK_MSG(wxlClass, 0, wxT("Invalid wxLuaBindClass"));
00358
00359 void *obj_ptr = wxlua_touserdata(L, 1, false);
00360 const char *name = lua_tostring(L, 2);
00361
00362 if (!name)
00363 {
00364
00365 wxlua_error(L, wxString::Format(_("wxLua: Attempt to call a class method using '%s' on a '%s' wxLua type."),
00366 wxlua_luaL_typename(L, 2).c_str(), lua2wx(wxlClass->name).c_str()));
00367 }
00368 else if (wxluaT_type(L, 1) == *wxlClass->wxluatype)
00369 {
00370
00371 bool callbase = (name[0] == '_');
00372
00373 if (callbase)
00374 name++;
00375 else
00376 {
00377
00378 if (wxlua_hasderivedmethod(L, obj_ptr, name, true))
00379 {
00380 found = true;
00381 result = 1;
00382 }
00383 }
00384
00385
00386 if (!found)
00387 {
00388 wxLuaBindMethod* wxlMethod = wxLuaBinding::GetClassMethod(wxlClass, name, WXLUAMETHOD_METHOD|WXLUAMETHOD_GETPROP, true);
00389
00390 if (wxlMethod != NULL)
00391 {
00392 if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_GETPROP))
00393 {
00394 found = true;
00395 if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_STATIC))
00396 lua_pop(L, 2);
00397 else
00398 lua_pop(L, 1);
00399
00400 result = (*wxlMethod->wxluacfuncs[0].lua_cfunc)(L);
00401 }
00402 else
00403 {
00404 found = true;
00405 result = 1;
00406
00407 lua_pushlightuserdata(L, wxlMethod);
00408
00409 if ((wxlMethod->wxluacfuncs_n > 1) || (wxlMethod->basemethod))
00410 lua_pushcclosure(L, wxlua_callOverloadedFunction, 1);
00411 else
00412 lua_pushcclosure(L, wxlMethod->wxluacfuncs[0].lua_cfunc, 1);
00413 }
00414 }
00415
00416
00417 if (!found)
00418 {
00419 int len = strlen(name);
00420 wxCharBuffer buf(len + 4);
00421 char* str = buf.data();
00422 str[0] = 'G'; str[1] = 'e'; str[2] = 't';
00423 memcpy(str+3, name, len+1);
00424
00425 wxlMethod = wxLuaBinding::GetClassMethod(wxlClass, str, WXLUAMETHOD_METHOD, true);
00426
00427 if ((wxlMethod != NULL) && WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_METHOD))
00428
00429
00430 {
00431 found = true;
00432 if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_STATIC))
00433 lua_pop(L, 2);
00434 else
00435 lua_pop(L, 1);
00436
00437 result = (*wxlMethod->wxluacfuncs[0].lua_cfunc)(L);
00438 }
00439 }
00440
00441
00442 if (found && callbase) wxlua_setcallbaseclassfunction(L, true);
00443 }
00444 }
00445
00446 if (!found)
00447 {
00448 wxlua_error(L, wxString::Format(_("wxLua: Unable to call an unknown method '%s' on a '%s' type."),
00449 lua2wx(name).c_str(), lua2wx(wxlClass ? wxlClass->name : "").c_str()));
00450 }
00451
00452 return result;
00453 }
00454
00455
00456
00457
00458
00459 int LUACALL wxlua_wxLuaBindClass__newindex(lua_State *L)
00460 {
00461 wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1));
00462 wxCHECK_MSG(wxlClass, 0, wxT("Invalid wxLuaBindClass"));
00463
00464
00465
00466 const char *name = lua_tostring(L, 2);
00467 bool found = false;
00468
00469 if (!name)
00470 {
00471
00472 wxlua_error(L, wxString::Format(_("wxLua: Attempt to call or add a class method using '%s' on a '%s' type."),
00473 wxlua_luaL_typename(L, 2).c_str(), lua2wx(wxlClass->name).c_str()));
00474 }
00475 else if (wxluaT_type(L, 1) == *wxlClass->wxluatype)
00476 {
00477
00478 wxLuaBindMethod *wxlMethod = wxLuaBinding::GetClassMethod(wxlClass, name, WXLUAMETHOD_SETPROP, true);
00479
00480 if (wxlMethod != NULL)
00481 {
00482 found = true;
00483 lua_remove(L, 2);
00484 if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_STATIC))
00485 lua_remove(L, 1);
00486
00487 (*wxlMethod->wxluacfuncs[0].lua_cfunc)(L);
00488 }
00489
00490
00491 if (!found)
00492 {
00493 int len = strlen(name);
00494 wxCharBuffer buf(len + 4);
00495 char* str = buf.data();
00496 str[0] = 'S'; str[1] = 'e'; str[2] = 't';
00497 memcpy(str+3, name, len+1);
00498
00499 wxlMethod = wxLuaBinding::GetClassMethod(wxlClass, str, WXLUAMETHOD_METHOD, true);
00500 if ((wxlMethod != NULL) && WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_METHOD))
00501 {
00502 found = true;
00503 lua_remove(L, 2);
00504 if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_STATIC))
00505 lua_remove(L, 1);
00506
00507 (*wxlMethod->wxluacfuncs[0].lua_cfunc)(L);
00508 }
00509 }
00510
00511
00512 if (!found)
00513 {
00514 found = true;
00515 wxLuaState wxlState(L);
00516 wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState"));
00517
00518 void *obj_ptr = wxlua_touserdata(L, 1, false);
00519 wxLuaObject* wxlObj = new wxLuaObject(wxlState, 3);
00520 wxlua_setderivedmethod(L, obj_ptr, name, wxlObj);
00521 }
00522 }
00523
00524 if (!found)
00525 {
00526 wxlua_error(L, wxString::Format(_("wxLua: Unable to call or add an unknown method '%s' on a '%s' type."),
00527 lua2wx(name).c_str(), lua2wx(wxlClass ? wxlClass->name : "").c_str()));
00528 }
00529
00530 return 0;
00531 }
00532
00533
00534
00535
00536
00537 int LUACALL wxlua_wxLuaBindClass__tostring(lua_State *L)
00538 {
00539
00540 wxString str = wxString::Format(wxT("userdata: %p"), lua_touserdata(L, 1));
00541
00542 int wxl_type = wxluaT_type(L, 1);
00543 if (wxlua_iswxuserdatatype(wxl_type))
00544 {
00545 wxString name = wxluaT_typename(L, wxl_type);
00546 if (!name.IsEmpty())
00547 {
00548
00549 void* p = wxlua_touserdata(L, 1, false);
00550 if (p)
00551 str += wxString::Format(wxT(" [%s(%p, %d)]"), name.c_str(), p, wxl_type);
00552 else
00553 str += wxString::Format(wxT(" [%s(0x0, %d)]"), name.c_str(), wxl_type);
00554 }
00555 }
00556 else
00557 str += wxT(" [??? Unknown wxLua class type!]");
00558
00559 lua_pushstring(L, wx2lua(str));
00560 return 1;
00561 }
00562
00563
00564
00565
00566
00567 int LUACALL wxlua_wxLuaBindMethod_table__call(lua_State *L)
00568 {
00569 lua_remove(L, 1);
00570
00571 return wxlua_callOverloadedFunction(L);
00572 }
00573
00574 int LUACALL wxlua_wxLuaBindMethod_table__index(lua_State *L)
00575 {
00576
00577
00578 wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1));
00579 wxCHECK_MSG(wxlClass, 0, wxT("Invalid wxLuaBindClass"));
00580
00581 int result = 0;
00582
00583 const char* name = lua_tostring(L, 2);
00584 if (!name)
00585 {
00586
00587 wxlua_error(L, wxString::Format(_("wxLua: Attempt to call a static class method using '%s' on a '%s' type."),
00588 wxlua_luaL_typename(L, 2).c_str(), lua2wx(wxlClass->name).c_str()));
00589 return 0;
00590 }
00591
00592 wxLuaBindMethod* wxlMethod = wxLuaBinding::GetClassMethod(wxlClass, name, WXLUAMETHOD_GETPROP, true);
00593
00594 if (wxlMethod && WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_STATIC))
00595 {
00596 lua_pop(L, 2);
00597 result = (*wxlMethod->wxluacfuncs[0].lua_cfunc)(L);
00598 }
00599 else
00600 {
00601 lua_pushvalue(L, -1);
00602 lua_rawget(L, -3);
00603 result = 1;
00604 }
00605
00606 return result;
00607 }
00608
00609 int LUACALL wxlua_wxLuaBindMethod_table__newindex(lua_State *L)
00610 {
00611
00612
00613 wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1));
00614 wxCHECK_MSG(wxlClass, 0, wxT("Invalid wxLuaBindClass"));
00615
00616 const char* name = lua_tostring(L, 2);
00617 if (!name)
00618 {
00619
00620 wxlua_error(L, wxString::Format(_("wxLua: Attempt to call a static class method using '%s' on a '%s' type."),
00621 wxlua_luaL_typename(L, 2).c_str(), lua2wx(wxlClass->name).c_str()));
00622 return 0;
00623 }
00624
00625 wxLuaBindMethod* wxlMethod = wxLuaBinding::GetClassMethod(wxlClass, name, WXLUAMETHOD_SETPROP, true);
00626
00627 if (wxlMethod && WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_STATIC))
00628 {
00629 lua_remove(L, 2);
00630 lua_remove(L, 1);
00631 (*wxlMethod->wxluacfuncs[0].lua_cfunc)(L);
00632 }
00633 else
00634 {
00635 lua_pushvalue(L, -2);
00636 lua_pushvalue(L, -2);
00637 lua_rawset(L, -5);
00638 }
00639
00640 return 0;
00641 }
00642
00643
00644
00645
00646
00647 int LUACALL wxlua_callOverloadedFunction(lua_State* L)
00648 {
00649 wxLuaBindMethod* wxlMethod = (wxLuaBindMethod *)lua_touserdata(L, lua_upvalueindex(1));
00650 wxCHECK_MSG(wxlMethod, 0, wxT("Invalid wxLuaBindMethod"));
00651
00652 if ((wxlMethod->wxluacfuncs_n > 1) || (wxlMethod->basemethod))
00653 return wxlua_callOverloadedFunction(L, wxlMethod);
00654 else
00655 return (*wxlMethod->wxluacfuncs[0].lua_cfunc)(L);
00656 }
00657
00658 int LUACALL wxlua_callOverloadedFunction(lua_State* L, struct wxLuaBindMethod* wxlMethod)
00659 {
00660
00661 int i, arg, arg_lua_count = lua_gettop(L);
00662
00663
00664 wxArrayPtrVoid cfuncArray;
00665 wxLuaBindMethod* method = wxlMethod;
00666 while (method)
00667 {
00668 wxLuaBindCFunc* wxlCFunc = method->wxluacfuncs;
00669
00670 for (i = 0; i < method->wxluacfuncs_n; ++i, ++wxlCFunc)
00671 {
00672 if ((arg_lua_count >= wxlCFunc->minargs) &&
00673 (arg_lua_count <= wxlCFunc->maxargs))
00674 {
00675 cfuncArray.Add(wxlCFunc);
00676 }
00677 }
00678
00679 method = method->basemethod;
00680 }
00681
00682 wxLuaBindCFunc* bestCFunc = NULL;
00683 int invalid_lua_arg = 1;
00684 int cfunc_count = cfuncArray.GetCount();
00685
00686
00687 for (arg = 0; (arg < arg_lua_count) && (cfunc_count != 0); ++arg)
00688 {
00689 int arg_lua = arg+1;
00690 int ltype = lua_type(L, arg_lua);
00691
00692 for (i = 0; i < cfunc_count; ++i)
00693 {
00694 wxLuaBindCFunc* wxlCFunc = (wxLuaBindCFunc*)cfuncArray[i];
00695 bestCFunc = wxlCFunc;
00696 invalid_lua_arg = arg_lua;
00697
00698
00699 if (!wxlCFunc->argtypes[arg])
00700 {
00701 cfuncArray.RemoveAt(i);
00702 cfunc_count--;
00703 i--;
00704 continue;
00705 }
00706
00707
00708 int wxl_type = (int)*(wxlCFunc->argtypes[arg]);
00709
00710
00711 int is_ok = wxlua_iswxluatype(ltype, wxl_type, L);
00712
00713
00714 if ((is_ok == -1) || ((is_ok == 0) && (wxl_type == WXLUA_TSTRING)))
00715 {
00716 is_ok = (wxluaT_isuserdatatype(L, arg_lua, wxl_type) ||
00717 (wxl_type == wxluatype_NULL)) ? 1 : 0;
00718 }
00719
00720
00721 if (is_ok == 0)
00722 {
00723 cfuncArray.RemoveAt(i);
00724 cfunc_count--;
00725 i--;
00726 continue;
00727 }
00728 }
00729 }
00730
00731
00732
00733
00734 if (cfunc_count > 0)
00735 {
00736 lua_CFunction lua_cfunc = ((wxLuaBindCFunc*)cfuncArray[0])->lua_cfunc;
00737
00738
00739 return (*lua_cfunc)(L);
00740 }
00741
00742
00743
00744
00745 wxString fnCall = wxlua_getLuaArgsMsg(L, 1, arg_lua_count);
00746
00747 wxString fnOverloadList = wxString::Format(wxT("Function called: '%s'\n"), fnCall.c_str());
00748 fnOverloadList += wxlua_getBindMethodArgsMsg(L, wxlMethod);
00749
00750 wxString errmsg;
00751
00752 if (cfunc_count > 1)
00753 {
00754 errmsg = wxT("wxLua: Function call is ambiguous.\nTry coercing values to proper types using tostring/number as appropriate.\n");
00755 }
00756
00757 if (bestCFunc == NULL)
00758 errmsg += wxT("wxLua: Function call has invalid arguments.");
00759 else
00760 {
00761
00762
00763 method = wxlMethod;
00764 int i_cfunc = 0;
00765 bool found = false;
00766 while (method && !found)
00767 {
00768 for (i = 0; i < method->wxluacfuncs_n; ++i)
00769 {
00770 i_cfunc++;
00771 if (&method->wxluacfuncs[i] == bestCFunc)
00772 {
00773 found = true;
00774 break;
00775 }
00776 }
00777
00778 method = method->basemethod;
00779 }
00780
00781 errmsg += wxString::Format(wxT("wxLua: Function call has invalid argument %d on method %02d.\n"), invalid_lua_arg, i_cfunc);
00782 }
00783
00784 errmsg += wxT("\n") + fnOverloadList;
00785
00786 wxlua_error(L, errmsg);
00787
00788 return 0;
00789 }
00790
00791 wxString wxlua_getLuaArgsMsg(lua_State* L, int start_stack_idx, int end_stack_idx)
00792 {
00793 lua_Debug ar = {0};
00794
00795
00796
00797 if (lua_getstack(L, 0, &ar) == 0)
00798 return wxT("?");
00799
00800 lua_getinfo(L, "n", &ar);
00801 wxString funcName = lua2wx(ar.name);
00802
00803 wxString funcCall = funcName + wxT("(");
00804
00805 for (int arg = start_stack_idx; arg <= end_stack_idx; ++arg)
00806 {
00807 if (arg > start_stack_idx) funcCall += wxT(", ");
00808
00809 funcCall += wxluaT_gettypename(L, arg);
00810 }
00811 funcCall += wxT(")");
00812
00813 return funcCall;
00814 }
00815
00816 wxString wxlua_getBindMethodArgsMsg(lua_State* L, struct wxLuaBindMethod* wxlMethod)
00817 {
00818 wxCHECK_MSG(wxlMethod, wxEmptyString, wxT("Invalid method table"));
00819
00820 wxString overloadMethods;
00821
00822 int i_cfunc = 0;
00823 wxLuaBindMethod* method = wxlMethod;
00824
00825
00826 while (method)
00827 {
00828 wxLuaBindCFunc* wxluacfuncs = method->wxluacfuncs;
00829 int i, arg, cfuncs_count = method->wxluacfuncs_n;
00830 wxString className;
00831
00832 const wxLuaBindClass* wxlClass = wxLuaBinding::FindBindClass(method);
00833 if (wxlClass)
00834 className = lua2wx(wxlClass->name) + wxT("::");
00835
00836 for (i = 0; i < cfuncs_count; ++i)
00837 {
00838 i_cfunc++;
00839
00840 wxString funcStr = wxString::Format(wxT("%02d. %s%s("), i_cfunc, className.c_str(), lua2wx(method->name).c_str());
00841
00842 for (arg = 0; arg < wxluacfuncs[i].maxargs; ++arg)
00843 {
00844
00845 if ((wxluacfuncs[i].minargs < wxluacfuncs[i].maxargs) && (arg+1 == wxluacfuncs[i].minargs))
00846 {
00847 if (arg > 0) funcStr += wxT(" ");
00848 funcStr += wxT("[");
00849 }
00850
00851 if (arg > 0)
00852 funcStr += wxT(", ");
00853
00854 int wxl_type = (int)*(wxluacfuncs[i].argtypes[arg]);
00855 funcStr += wxluaT_typename(L, wxl_type);
00856
00857 if ((arg == 0) &&
00858 !WXLUA_HASBIT(wxluacfuncs[i].method_type, WXLUAMETHOD_STATIC) &&
00859 !WXLUA_HASBIT(wxluacfuncs[i].method_type, WXLUAMETHOD_CONSTRUCTOR) &&
00860 !WXLUA_HASBIT(wxluacfuncs[i].method_type, WXLUAMETHOD_CFUNCTION))
00861 funcStr += wxT("(self)");
00862 }
00863
00864
00865 if (wxluacfuncs[i].minargs < wxluacfuncs[i].maxargs)
00866 funcStr += wxT("]");
00867
00868 funcStr += wxT(")");
00869
00870 if (WXLUA_HASBIT(wxluacfuncs[i].method_type, WXLUAMETHOD_STATIC))
00871 funcStr += wxT(" - static");
00872
00873 if (overloadMethods.Length() > 0)
00874 overloadMethods += wxT("\n") + funcStr;
00875 else
00876 overloadMethods += funcStr;
00877 }
00878
00879 method = method->basemethod;
00880 }
00881
00882 return overloadMethods;
00883 }
00884
00885
00886
00887
00888
00889
00890 int wxLuaBindEventArrayCompareFn(const void *p1, const void *p2)
00891 {
00892 return (*((const wxLuaBindEvent*)p1)->eventType) - (*((const wxLuaBindEvent*)p2)->eventType);
00893 }
00894
00895 int wxLuaBindNumberArrayCompareFn(const void *p1, const void *p2)
00896 {
00897 return strcmp(((const wxLuaBindNumber*)p1)->name, ((const wxLuaBindNumber*)p2)->name);
00898 }
00899
00900 int wxLuaBindStringArrayCompareFn(const void *p1, const void *p2)
00901 {
00902 return strcmp(((const wxLuaBindString*)p1)->name, ((const wxLuaBindString*)p2)->name);
00903 }
00904
00905 int wxLuaBindObjectArrayCompareFn(const void *p1, const void *p2)
00906 {
00907 return strcmp(((const wxLuaBindObject*)p1)->name, ((const wxLuaBindObject*)p2)->name);
00908 }
00909
00910 int wxLuaBindMethodArrayCompareFnInit(const void *p1, const void *p2)
00911 {
00912 int v = strcmp(((const wxLuaBindMethod*)p1)->name, ((const wxLuaBindMethod*)p2)->name);
00913 if (v == 0)
00914 {
00915 int t1 = WXLUAMETHOD_SORT_MASK & ((const wxLuaBindMethod*)p1)->method_type;
00916 int t2 = WXLUAMETHOD_SORT_MASK & ((const wxLuaBindMethod*)p2)->method_type;
00917 v = t1 - t2;
00918 }
00919
00920 wxCHECK_MSG(v != 0, 0, wxT("Duplicate wxLuaBindMethod names and method_types"));
00921
00922 return v;
00923 }
00924
00925 int wxLuaBindMethodArrayCompareFnGet(const void *p1, const void *p2)
00926 {
00927 int v = strcmp(((const wxLuaBindMethod*)p1)->name, ((const wxLuaBindMethod*)p2)->name);
00928 if (v == 0)
00929 {
00930 int t1 = WXLUAMETHOD_SEARCH_MASK & ((const wxLuaBindMethod*)p1)->method_type;
00931 int t2 = WXLUAMETHOD_SEARCH_MASK & ((const wxLuaBindMethod*)p2)->method_type;
00932
00933 if ((t1 & t2) != 0) return 0;
00934
00935 v = t1 - t2;
00936 }
00937
00938 return v;
00939 }
00940
00941 int wxLuaBindClassArrayCompareFn(const void *p1, const void *p2)
00942 {
00943 return strcmp(((const wxLuaBindClass*)p1)->name, ((const wxLuaBindClass*)p2)->name);
00944 }
00945
00946 int wxLuaBindClassArrayCompareBywxLuaType(const void *p1, const void *p2)
00947 {
00948 return (*((const wxLuaBindClass*)p1)->wxluatype) - (*((const wxLuaBindClass*)p2)->wxluatype);
00949 }
00950
00951
00952
00953
00954
00955 IMPLEMENT_ABSTRACT_CLASS(wxLuaBinding, wxObject)
00956
00957 wxLuaBindingList wxLuaBinding::sm_bindingList;
00958 bool wxLuaBinding::sm_bindingList_initialized = false;
00959 int wxLuaBinding::sm_wxluatype_max = WXLUA_T_MAX+1;
00960
00961 wxLuaBinding::wxLuaBinding()
00962 :m_classCount(0), m_classArray(NULL),
00963 m_numberCount(0), m_numberArray(NULL),
00964 m_stringCount(0), m_stringArray(NULL),
00965 m_eventCount(0), m_eventArray(NULL),
00966 m_objectCount(0), m_objectArray(NULL),
00967 m_functionCount(0), m_functionArray(NULL),
00968 m_first_wxluatype(WXLUA_TUNKNOWN),
00969 m_last_wxluatype(WXLUA_TUNKNOWN)
00970 {
00971 }
00972
00973 void wxLuaBinding::InitBinding()
00974 {
00975
00976
00977 if (m_classArray && (m_classCount > 0))
00978 {
00979
00980 if (*m_classArray[0].wxluatype != WXLUA_TUNKNOWN)
00981 return;
00982
00983 qsort(m_classArray, m_classCount, sizeof(wxLuaBindClass), wxLuaBindClassArrayCompareFn);
00984
00985 wxLuaBindClass* wxlClass = m_classArray;
00986 for (size_t i = 0; i < m_classCount; ++i, ++wxlClass)
00987 {
00988 *wxlClass->wxluatype = ++wxLuaBinding::sm_wxluatype_max;
00989
00990
00991 if (wxlClass->wxluamethods && (wxlClass->wxluamethods_n > 0))
00992 qsort(wxlClass->wxluamethods, wxlClass->wxluamethods_n, sizeof(wxLuaBindMethod), wxLuaBindMethodArrayCompareFnInit);
00993
00994 if (wxlClass->enums && (wxlClass->enums_n > 0))
00995 qsort(wxlClass->enums, wxlClass->enums_n, sizeof(wxLuaBindNumber), wxLuaBindNumberArrayCompareFn);
00996 }
00997
00998
00999 m_first_wxluatype = *m_classArray[0].wxluatype;
01000 m_last_wxluatype = *m_classArray[m_classCount-1].wxluatype;
01001 }
01002
01003 if (m_numberArray && (m_numberCount > 0))
01004 qsort(m_numberArray, m_numberCount, sizeof(wxLuaBindNumber), wxLuaBindNumberArrayCompareFn);
01005
01006 if (m_stringArray && (m_stringCount > 0))
01007 qsort(m_stringArray, m_stringCount, sizeof(wxLuaBindString), wxLuaBindStringArrayCompareFn);
01008
01009
01010 if (m_eventArray && (m_eventCount > 0))
01011 qsort(m_eventArray, m_eventCount, sizeof(wxLuaBindEvent), wxLuaBindEventArrayCompareFn);
01012
01013 if (m_objectArray && (m_objectCount > 0))
01014 qsort(m_objectArray, m_objectCount, sizeof(wxLuaBindObject), wxLuaBindObjectArrayCompareFn);
01015 }
01016
01017 bool wxLuaBinding::RegisterBinding(const wxLuaState& wxlState)
01018 {
01019 wxCHECK_MSG(wxlState.Ok(), false, wxT("Invalid wxLuaState"));
01020 lua_State *L = wxlState.GetLuaState();
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030 static const luaL_Reg wxlualib[] = { {NULL, NULL} };
01031 luaI_openlib(L, wx2lua(m_nameSpace), wxlualib, 0);
01032
01033
01034
01035 if (!lua_istable(L, -1))
01036 {
01037 lua_pop(L, 1);
01038 return false;
01039 }
01040
01041
01042
01043 int luaTable_ref = -1;
01044
01045 lua_pushlightuserdata(L, &wxlua_lreg_wxluabindings_key);
01046 lua_rawget(L, LUA_REGISTRYINDEX);
01047
01048 lua_pushnil(L);
01049 while (lua_next(L, -2) != 0)
01050 {
01051
01052 wxLuaBinding* binding = (wxLuaBinding*)lua_touserdata(L, -2);
01053
01054 if (binding->GetLuaNamespace() == m_nameSpace)
01055 {
01056 luaTable_ref = (int)lua_tonumber(L, -1);
01057 lua_pop(L, 2);
01058 break;
01059 }
01060
01061 lua_pop(L, 1);
01062 }
01063
01064 lua_pop(L, 1);
01065
01066
01067
01068 if (luaTable_ref < 1)
01069 {
01070
01071 luaTable_ref = wxluaR_ref(L, -1, &wxlua_lreg_refs_key);
01072 }
01073
01074
01075 lua_pushlightuserdata(L, &wxlua_lreg_wxluabindings_key);
01076 lua_rawget(L, LUA_REGISTRYINDEX);
01077
01078 lua_pushlightuserdata(L, this);
01079 lua_pushnumber(L, luaTable_ref);
01080 lua_rawset(L, -3);
01081 lua_pop(L, 1);
01082
01083
01084 DoRegisterBinding(wxlState);
01085
01086 return true;
01087 }
01088
01089 void wxLuaBinding::DoRegisterBinding(const wxLuaState& wxlState) const
01090 {
01091 wxCHECK_RET(wxlState.Ok(), wxT("Invalid wxLuaState"));
01092 lua_State *L = wxlState.GetLuaState();
01093
01094 size_t n;
01095
01096
01097
01098 const wxLuaBindClass *wxlClass = m_classArray;
01099 for (n = 0; n < m_classCount; ++n, ++wxlClass)
01100 {
01101 InstallClassMetatable(L, wxlClass);
01102 InstallClass(L, wxlClass);
01103 }
01104
01105
01106 const wxLuaBindMethod* wxlMethod = m_functionArray;
01107 for (n = 0; n < m_functionCount; ++n, ++wxlMethod)
01108 {
01109 lua_pushstring(L, wxlMethod->name);
01110 lua_pushlightuserdata(L, (void*)wxlMethod);
01111 lua_pushcclosure(L, wxlMethod->wxluacfuncs[0].lua_cfunc, 1);
01112 lua_rawset(L, -3);
01113 }
01114
01115
01116 const wxLuaBindNumber* wxlNumber = m_numberArray;
01117 for (n = 0; n < m_numberCount; ++n, ++wxlNumber)
01118 {
01119 lua_pushstring(L, wxlNumber->name);
01120 lua_pushnumber(L, wxlNumber->value);
01121 lua_rawset(L, -3);
01122 }
01123
01124
01125 const wxLuaBindString *wxlString = m_stringArray;
01126 for (n = 0; n < m_stringCount; ++n, ++wxlString)
01127 {
01128 lua_pushstring(L, wxlString->name);
01129 lua_pushstring(L, wx2lua(wxlString->value));
01130 lua_rawset(L, -3);
01131 }
01132
01133
01134 const wxLuaBindObject *wxlObject = m_objectArray;
01135 for (n = 0; n < m_objectCount; ++n, ++wxlObject)
01136 {
01137 lua_pushstring(L, wxlObject->name);
01138
01139 if (wxlObject->objPtr != 0)
01140 wxluaT_pushuserdatatype(L, wxlObject->objPtr, *wxlObject->wxluatype, true);
01141 else
01142 wxluaT_pushuserdatatype(L, *wxlObject->pObjPtr, *wxlObject->wxluatype, true);
01143
01144 lua_rawset(L, -3);
01145 }
01146
01147
01148 const wxLuaBindEvent *wxlEvent = m_eventArray;
01149 for (n = 0; n < m_eventCount; ++n, ++wxlEvent)
01150 {
01151 lua_pushstring(L, wxlEvent->name);
01152 lua_pushnumber(L, *wxlEvent->eventType);
01153 lua_rawset(L, -3);
01154 }
01155 }
01156
01157
01158 bool wxLuaBinding::InstallClassMetatable(lua_State* L, const wxLuaBindClass* wxlClass)
01159 {
01160
01161 static const luaL_reg s_funcTable[] =
01162 {
01163 {"__gc", wxlua_wxLuaBindClass__gc },
01164 {"__index", wxlua_wxLuaBindClass__index },
01165 {"__newindex", wxlua_wxLuaBindClass__newindex },
01166 {"__tostring", wxlua_wxLuaBindClass__tostring }
01167 };
01168 static const size_t s_funcCount = sizeof(s_funcTable)/sizeof(s_funcTable[0]);
01169
01170
01171
01172 lua_pushlightuserdata(L, &wxlua_lreg_classes_key);
01173 lua_rawget(L, LUA_REGISTRYINDEX);
01174 lua_pushstring(L, wxlClass->name);
01175 lua_pushlightuserdata(L, (void *)wxlClass);
01176 lua_rawset(L, -3);
01177 lua_pop(L, 1);
01178
01179
01180
01181
01182 int wxl_type = *wxlClass->wxluatype;
01183
01184
01185 if (!wxluaT_getmetatable(L, wxl_type))
01186 wxluaT_newmetatable(L, wxl_type);
01187
01188
01189 lua_pushlightuserdata(L, &wxlua_metatable_wxluabindclass_key);
01190 lua_pushlightuserdata(L, (void *)wxlClass);
01191 lua_rawset(L, -3);
01192
01193
01194 for (size_t i_func = 0; i_func < s_funcCount; ++i_func)
01195 {
01196 lua_pushstring(L, s_funcTable[i_func].name);
01197 lua_pushlightuserdata(L, (void *)wxlClass);
01198 lua_pushcclosure(L, s_funcTable[i_func].func, 1);
01199 lua_rawset(L, -3);
01200 }
01201
01202 lua_pop(L, 1);
01203
01204 return true;
01205 }
01206
01207
01208 bool wxLuaBinding::InstallClass(lua_State* L, const wxLuaBindClass* wxlClass)
01209 {
01210
01211
01212
01213 lua_pushstring(L, wxlClass->name);
01214 lua_newtable(L);
01215
01216
01217 for (int i_enum = 0; i_enum < wxlClass->enums_n; ++i_enum)
01218 {
01219 lua_pushstring(L, wxlClass->enums[i_enum].name);
01220 lua_pushnumber(L, wxlClass->enums[i_enum].value);
01221 lua_rawset(L, -3);
01222 }
01223
01224 int method_count = wxlClass->wxluamethods_n;
01225
01226
01227 wxLuaBindMethod *wxlMethod = wxlClass->wxluamethods;
01228 for (int i_static_method = 0; i_static_method < method_count; ++i_static_method, ++wxlMethod)
01229 {
01230
01231 if (((wxlMethod->method_type & (WXLUAMETHOD_METHOD|WXLUAMETHOD_STATIC)) == (WXLUAMETHOD_METHOD|WXLUAMETHOD_STATIC)) &&
01232 (wxlMethod->wxluacfuncs_n > 0))
01233 {
01234 lua_pushstring(L, wxlMethod->name);
01235 lua_pushlightuserdata(L, wxlMethod);
01236 if (wxlMethod->wxluacfuncs_n > 1)
01237 lua_pushcclosure(L, wxlua_callOverloadedFunction, 1);
01238 else
01239 lua_pushcclosure(L, wxlMethod->wxluacfuncs[0].lua_cfunc, 1);
01240
01241 lua_rawset(L, -3);
01242 }
01243 }
01244
01245
01246 lua_newtable(L);
01247 lua_pushlstring(L, "__index", 7);
01248 lua_pushlightuserdata(L, (void*)wxlClass);
01249 lua_pushcclosure(L, wxlua_wxLuaBindMethod_table__index, 1);
01250 lua_rawset(L, -3);
01251
01252 lua_pushlstring(L, "__newindex", 10);
01253 lua_pushlightuserdata(L, (void*)wxlClass);
01254 lua_pushcclosure(L, wxlua_wxLuaBindMethod_table__newindex, 1);
01255 lua_rawset(L, -3);
01256
01257
01258
01259
01260 lua_setmetatable(L, -2);
01261
01262
01263
01264 lua_rawset(L, -3);
01265
01266
01267
01268 wxlMethod = wxlClass->wxluamethods;
01269 for (int i_method = 0; i_method < method_count; ++i_method, ++wxlMethod)
01270 {
01271 if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_CONSTRUCTOR | WXLUAMETHOD_CFUNCTION) && wxlMethod->wxluacfuncs_n)
01272 {
01273
01274
01275
01276 lua_pushstring(L, wxlMethod->name);
01277
01278 if (strcmp(wxlMethod->name, wxlClass->name) != 0)
01279 lua_newtable(L);
01280 else
01281 lua_getfield(L, -2, wxlMethod->name);
01282
01283
01284 lua_pushlstring(L, "new", 3);
01285 lua_pushlightuserdata(L, wxlMethod);
01286 lua_pushcclosure(L, wxlua_callOverloadedFunction, 1);
01287 lua_rawset(L, -3);
01288
01289
01290 bool has_meta = (lua_getmetatable(L, -1) != 0);
01291 if (!has_meta) lua_newtable(L);
01292
01293 lua_pushlstring(L, "__call", 6);
01294 lua_pushlightuserdata(L, wxlMethod);
01295 lua_pushcclosure(L, wxlua_wxLuaBindMethod_table__call, 1);
01296 lua_rawset(L, -3);
01297
01298
01299
01300
01301
01302 if (!has_meta)
01303 lua_setmetatable(L, -2);
01304 else
01305 lua_pop(L, 1);
01306
01307
01308 lua_rawset(L, -3);
01309 }
01310 }
01311
01312 return true;
01313 }
01314
01315
01316
01317 const wxLuaBindEvent* wxLuaBinding::GetBindEvent(wxEventType eventType_) const
01318 {
01319 const wxEventType eventType = eventType_;
01320 wxLuaBindEvent eventItem = { "", &eventType, NULL };
01321
01322 const wxLuaBindEvent *pLuaEvent = (wxLuaBindEvent *)bsearch(&eventItem,
01323 m_eventArray,
01324 m_eventCount,
01325 sizeof(wxLuaBindEvent),
01326 wxLuaBindEventArrayCompareFn);
01327 return pLuaEvent;
01328 }
01329
01330 wxString wxLuaBinding::GetEventTypeName(wxEventType eventType) const
01331 {
01332 const wxLuaBindEvent* wxlEvent = GetBindEvent(eventType);
01333 return (wxlEvent != NULL) ? lua2wx(wxlEvent->name) : wxString();
01334 }
01335
01336 const wxLuaBindClass* wxLuaBinding::GetBindClass(int wxluatype_) const
01337 {
01338 int wxluatype = wxluatype_;
01339 wxLuaBindClass classItem = { 0, 0, 0, 0, &wxluatype, 0, 0, 0, 0 };
01340
01341
01342
01343 const wxLuaBindClass *wxlClass = (wxLuaBindClass *)bsearch(&classItem,
01344 m_classArray,
01345 m_classCount,
01346 sizeof(wxLuaBindClass),
01347 wxLuaBindClassArrayCompareBywxLuaType);
01348
01349 return wxlClass;
01350 }
01351
01352 const wxLuaBindClass* wxLuaBinding::GetBindClass(const char* className) const
01353 {
01354 wxLuaBindClass classItem = { className, 0, 0, 0, 0, 0, 0, 0, 0 };
01355
01356
01357
01358 const wxLuaBindClass *wxlClass = (wxLuaBindClass *)bsearch(&classItem,
01359 m_classArray,
01360 m_classCount,
01361 sizeof(wxLuaBindClass),
01362 wxLuaBindClassArrayCompareFn);
01363
01364 return wxlClass;
01365 }
01366
01367 const wxLuaBindClass* wxLuaBinding::GetBindClass(const wxLuaBindMethod* wxlMethod_tofind) const
01368 {
01369 wxLuaBindClass* wxlClass = m_classArray;
01370 wxLuaBindMethod* wxlMethod = NULL;
01371
01372 for (size_t c = 0; c < m_classCount; ++c, ++wxlClass)
01373 {
01374 wxlMethod = wxlClass->wxluamethods;
01375 int m , wxluamethods_n = wxlClass->wxluamethods_n;
01376
01377 for (m = 0; m < wxluamethods_n; ++m, ++wxlMethod)
01378 {
01379 if (wxlMethod == wxlMethod_tofind)
01380 return wxlClass;
01381 }
01382 }
01383
01384 return NULL;
01385 }
01386
01387 const wxLuaBindClass* wxLuaBinding::GetBindClass(const wxLuaBindCFunc* wxlCFunc_tofind) const
01388 {
01389 size_t c, m, f, methods_n, funcs_n;
01390 wxLuaBindClass* wxlClass = m_classArray;
01391 wxLuaBindMethod* wxlMethod = NULL;
01392 wxLuaBindCFunc* wxlCFunc = NULL;
01393
01394 for (c = 0; c < m_classCount; ++c, ++wxlClass)
01395 {
01396 wxlMethod = wxlClass->wxluamethods;
01397 methods_n = wxlClass->wxluamethods_n;
01398
01399 for (m = 0; m < methods_n; ++m, ++wxlMethod)
01400 {
01401 wxlCFunc = wxlMethod->wxluacfuncs;
01402 funcs_n = wxlMethod->wxluacfuncs_n;
01403
01404 for (f = 0; f < funcs_n; ++f, ++wxlCFunc)
01405 {
01406 if (wxlCFunc == wxlCFunc_tofind)
01407 return wxlClass;
01408 }
01409 }
01410 }
01411
01412 return NULL;
01413 }
01414
01415
01416
01417
01418 wxLuaBinding* wxLuaBinding::GetLuaBinding(const wxString& bindingName)
01419 {
01420 wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst();
01421
01422 while (node)
01423 {
01424 wxLuaBinding* binding = node->GetData();
01425 if (binding->GetBindingName() == bindingName)
01426 return binding;
01427
01428 node = node->GetNext();
01429 }
01430
01431 return NULL;
01432 }
01433
01434
01435 const wxLuaBindClass* wxLuaBinding::FindBindClass(const char* className)
01436 {
01437 wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst();
01438
01439 while (node)
01440 {
01441 wxLuaBinding* binding = node->GetData();
01442 const wxLuaBindClass* wxlClass = binding->GetBindClass(className);
01443
01444 if (wxlClass)
01445 return wxlClass;
01446
01447 node = node->GetNext();
01448 }
01449
01450 return NULL;
01451 }
01452
01453
01454 const wxLuaBindClass* wxLuaBinding::FindBindClass(int wxluatype)
01455 {
01456 wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst();
01457
01458 while (node)
01459 {
01460 wxLuaBinding* binding = node->GetData();
01461 const wxLuaBindClass* wxlClass = binding->GetBindClass(wxluatype);
01462
01463 if (wxlClass)
01464 return wxlClass;
01465
01466 node = node->GetNext();
01467 }
01468
01469 return NULL;
01470 }
01471
01472
01473 const wxLuaBindClass* wxLuaBinding::FindBindClass(const wxLuaBindMethod* wxlMethod)
01474 {
01475 wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst();
01476
01477 while (node)
01478 {
01479 wxLuaBinding* binding = node->GetData();
01480 const wxLuaBindClass* wxlClass = binding->GetBindClass(wxlMethod);
01481
01482 if (wxlClass)
01483 return wxlClass;
01484
01485 node = node->GetNext();
01486 }
01487
01488 return NULL;
01489 }
01490
01491
01492 const wxLuaBindClass* wxLuaBinding::FindBindClass(const wxLuaBindCFunc* wxlCFunc)
01493 {
01494 wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst();
01495
01496 while (node)
01497 {
01498 wxLuaBinding* binding = node->GetData();
01499 const wxLuaBindClass* wxlClass = binding->GetBindClass(wxlCFunc);
01500
01501 if (wxlClass)
01502 return wxlClass;
01503
01504 node = node->GetNext();
01505 }
01506
01507 return NULL;
01508 }
01509
01510
01511 const wxLuaBindEvent* wxLuaBinding::FindBindEvent(wxEventType eventType)
01512 {
01513 wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst();
01514
01515 while (node)
01516 {
01517 wxLuaBinding* binding = node->GetData();
01518 const wxLuaBindEvent* wxlEvent = binding->GetBindEvent(eventType);
01519
01520 if (wxlEvent)
01521 return wxlEvent;
01522
01523 node = node->GetNext();
01524 }
01525
01526 return NULL;
01527 }
01528
01529
01530 wxLuaBinding* wxLuaBinding::FindMethodBinding(const wxLuaBindMethod* wxlMethod)
01531 {
01532 wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst();
01533
01534 while (node)
01535 {
01536 wxLuaBinding* binding = node->GetData();
01537 size_t n, count = binding->GetFunctionCount();
01538 wxLuaBindMethod* m = binding->GetFunctionArray();
01539
01540 for (n = 0; n < count; ++n, ++m)
01541 {
01542 if (m == wxlMethod)
01543 return binding;
01544 }
01545
01546 node = node->GetNext();
01547 }
01548
01549 return NULL;
01550 }
01551
01552
01553
01554
01555
01556 wxLuaBindMethod* wxLuaBinding::GetClassMethod(const wxLuaBindClass *wxlClass, const char *methodName, int method_type, bool search_baseclasses)
01557 {
01558 wxCHECK_MSG(wxlClass, NULL, wxT("Invalid wxLuaBindClass to find method from."));
01559
01560 #if 1
01561
01562 wxLuaBindMethod methodItem = { methodName, method_type, 0, 0, 0 };
01563
01564 wxLuaBindMethod *wxlMethod = (wxLuaBindMethod *)bsearch(&methodItem,
01565 wxlClass->wxluamethods,
01566 wxlClass->wxluamethods_n,
01567 sizeof(wxLuaBindMethod),
01568 wxLuaBindMethodArrayCompareFnGet);
01569
01570 if ((wxlMethod == NULL) && search_baseclasses && wxlClass->baseclassNames)
01571 {
01572 for (size_t i = 0; wxlClass->baseclassNames[i]; ++i)
01573 {
01574 wxlMethod = GetClassMethod(wxlClass->baseBindClasses[i], methodName, method_type, search_baseclasses);
01575 if (wxlMethod != NULL)
01576 return wxlMethod;
01577 }
01578 }
01579
01580 #else
01581
01582 wxLuaBindMethod *wxlMethod = wxlClass->wxluamethods;
01583 int i_method, method_count = wxlClass->wxluamethods_n;
01584
01585
01586 for (i_method = 0; i_method < method_count; ++i_method, ++wxlMethod)
01587 {
01588 if (WXLUA_HASBIT(wxlMethod->type, method_type)
01589 && (strcmp(wxlMethod->name, methodName) == 0))
01590 {
01591 return wxlMethod;
01592 }
01593 }
01594
01595 if (search_baseclasses && wxlClass->baseclass)
01596 return GetClassMethod(wxlClass->baseclass, methodName, method_type, search_baseclasses);
01597
01598 #endif
01599
01600 return wxlMethod;
01601 }
01602
01603
01604
01605 static void wxLuaBinding_RecurseBaseMethods(wxLuaBindClass* wxlClass, wxLuaBindMethod* wxlMethod, bool force_update)
01606 {
01607
01608
01609 if (force_update || !WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_CHECKED_OVERLOAD|WXLUAMETHOD_DELETE))
01610 {
01611 wxLuaBindMethod *parentMethod = wxlMethod;
01612
01613
01614 for (size_t i = 0; wxlClass->baseclassNames && wxlClass->baseclassNames[i]; ++i)
01615 {
01616
01617 wxLuaBindClass *baseClass = wxlClass->baseBindClasses[i];
01618 if (baseClass != NULL)
01619 {
01620 parentMethod->method_type |= WXLUAMETHOD_CHECKED_OVERLOAD;
01621
01622 wxLuaBindMethod* baseMethod = wxLuaBinding::GetClassMethod(baseClass, wxlMethod->name, WXLUAMETHOD_SEARCH_MASK, false);
01623 if (baseMethod)
01624 {
01625
01626 if (!WXLUA_HASBIT(baseMethod->method_type, WXLUAMETHOD_DELETE))
01627 {
01628 parentMethod->basemethod = baseMethod;
01629 parentMethod = baseMethod;
01630 }
01631
01632
01633 if (!WXLUA_HASBIT(baseMethod->method_type, WXLUAMETHOD_CHECKED_OVERLOAD))
01634 wxLuaBinding_RecurseBaseMethods(baseClass, parentMethod, force_update);
01635 }
01636 }
01637 }
01638 }
01639 }
01640
01641
01642 void wxLuaBinding::InitAllBindings(bool force_update)
01643 {
01644 if (sm_bindingList_initialized && !force_update) return;
01645
01646
01647 wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst();
01648 while (node)
01649 {
01650 wxLuaBinding* binding = node->GetData();
01651 binding->InitBinding();
01652
01653 node = node->GetNext();
01654 }
01655
01656
01657 node = sm_bindingList.GetFirst();
01658 while (node)
01659 {
01660 wxLuaBinding* binding = node->GetData();
01661 wxLuaBindClass* wxlClass = binding->GetClassArray();
01662 size_t i, class_count = binding->GetClassCount();
01663
01664 for (i = 0; i < class_count; ++i, ++wxlClass)
01665 {
01666 if (wxlClass->baseclassNames)
01667 {
01668
01669 for (size_t j = 0; wxlClass->baseclassNames[j]; ++j)
01670 {
01671 wxLuaBindClass* wxlBaseClass = (wxLuaBindClass*)wxLuaBinding::FindBindClass(wxlClass->baseclassNames[j]);
01672 if (wxlBaseClass)
01673 wxlClass->baseBindClasses[j] = wxlBaseClass;
01674 }
01675 }
01676 }
01677
01678 node = node->GetNext();
01679 }
01680
01681
01682
01683 node = sm_bindingList.GetFirst();
01684 while (node)
01685 {
01686 wxLuaBinding* binding = node->GetData();
01687 wxLuaBindClass* wxlClass = binding->GetClassArray();
01688 size_t i, class_count = binding->GetClassCount();
01689
01690 for (i = 0; i < class_count; ++i, ++wxlClass)
01691 {
01692 if (wxlClass->baseclassNames)
01693 {
01694 wxLuaBindMethod *wxlMethod = wxlClass->wxluamethods;
01695 size_t j, method_count = wxlClass->wxluamethods_n;
01696
01697 for (j = 0; j < method_count; ++j, ++wxlMethod)
01698 {
01699 wxLuaBinding_RecurseBaseMethods(wxlClass, wxlMethod, force_update);
01700 }
01701 }
01702 }
01703
01704 node = node->GetNext();
01705 }
01706
01707 sm_bindingList_initialized = true;
01708 }