1 /* 2 * Copyright (c) 2012-2016, Bruno Levy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * * Neither the name of the ALICE Project-Team nor the names of its 14 * contributors may be used to endorse or promote products derived from this 15 * software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * If you modify this software, you should include a notice giving the 30 * name of the person performing the modification, the date of modification, 31 * and the reason for such modification. 32 * 33 * Contact: Bruno Levy 34 * 35 * Bruno.Levy@inria.fr 36 * http://www.loria.fr/~levy 37 * 38 * ALICE Project 39 * LORIA, INRIA Lorraine, 40 * Campus Scientifique, BP 239 41 * 54506 VANDOEUVRE LES NANCY CEDEX 42 * FRANCE 43 * 44 */ 45 46 #ifndef GEOGRAM_LUA_LUA_WRAP 47 48 #include <geogram/basic/common.h> 49 #include <geogram/basic/assert.h> 50 #include <geogram/basic/numeric.h> 51 #include <geogram/basic/string.h> 52 #include <geogram/basic/memory.h> 53 54 extern "C" { 55 #include <geogram/third_party/lua/lua.h> 56 #include <geogram/third_party/lua/lauxlib.h> 57 #include <geogram/third_party/lua/lualib.h> 58 } 59 60 /** 61 * \file geogram/lua/lua_wrap.h 62 * \brief Utilities to write lua bindings. 63 */ 64 65 namespace GEO { 66 67 /** 68 * \brief A pointer to a LUA function to test an argument 69 * in the LUA stack. 70 */ 71 typedef int (*lua_test_func)(lua_State* L, int idx); 72 73 74 /** 75 * \brief Tests whether a LUA variable is a boolean. 76 * \details lua_isboolean() is a macro, and we needed 77 * a true function here (to be passed to lua_check_type()). 78 * \param[in] L a pointer to the LUA state 79 * \param[in] idx an index in the LUA stack 80 * \retval a non-zero integer if the variable 81 * at index \p idx in the LUA 82 * state \p L is a boolean. 83 * \retval 0 otherwise. 84 */ my_lua_isboolean(lua_State * L,int idx)85 inline int my_lua_isboolean(lua_State* L, int idx) { 86 return lua_isboolean(L,idx); 87 } 88 89 /** 90 * \brief Tests whether a LUA variable is a light user data. 91 * \details lua_isuserdata() is a macro, and we needed 92 * a true function here (to be passed to lua_check_type()). 93 * \param[in] L a pointer to the LUA state 94 * \param[in] idx an index in the LUA stack 95 * \retval a non-zero integer if the variable 96 * at index \p idx in the LUA 97 * state \p L is a light user data. 98 * \retval 0 otherwise. 99 */ my_lua_islightuserdata(lua_State * L,int idx)100 inline int my_lua_islightuserdata(lua_State* L, int idx) { 101 return lua_islightuserdata(L,idx); 102 } 103 104 /** 105 * \brief Tests whether a LUA variable is a positive integer. 106 * \param[in] L a pointer to the LUA state 107 * \param[in] idx an index in the LUA stack 108 * \retval a non-zero integer if the variable 109 * at index \p idx in the LUA 110 * state \p L is a positive integer. 111 * \retval 0 otherwise. 112 */ my_lua_ispositiveinteger(lua_State * L,int idx)113 inline int my_lua_ispositiveinteger(lua_State* L, int idx) { 114 if(!lua_isinteger(L,idx)) { 115 return 0; 116 } 117 lua_Integer x = lua_tointeger(L,idx); 118 return (x > 0) ? 1 : 0; 119 } 120 121 /** 122 * \brief Memorizes an error message in LUA registry. 123 * \details This is used by C++/LUA interoperability 124 * functions to memorize an error. The error message 125 * can be passed back to LUA when exiting a wrapper. 126 * \param[in] L a pointer to the LUA state. 127 * \param[in] error the error message. It will be copied. 128 */ lua_set_error(lua_State * L,const char * error)129 inline void lua_set_error(lua_State* L, const char* error) { 130 lua_pushstring(L, error); 131 lua_setfield(L,LUA_REGISTRYINDEX,"last_geogram_error"); 132 } 133 134 /** 135 * \brief Memorizes an error message in LUA registry. 136 * \details This is used by C++/LUA interoperability 137 * functions to memorize an error. The error message 138 * can be passed back to LUA when exiting a wrapper. 139 * \param[in] L a pointer to the LUA state. 140 * \param[in] error the error message. It will be copied. 141 */ lua_set_error(lua_State * L,const std::string & error)142 inline void lua_set_error(lua_State* L, const std::string& error) { 143 lua_set_error(L,error.c_str()); 144 } 145 146 /** 147 * \brief Clears the last error message in LUA registry. 148 * \param[in] L a pointer to the LUA state. 149 */ lua_clear_error(lua_State * L)150 inline void lua_clear_error(lua_State* L) { 151 lua_pushnil(L); 152 lua_setfield(L,LUA_REGISTRYINDEX,"last_geogram_error"); 153 } 154 155 /** 156 * \brief Tests whether an error message was memorized in the 157 * registry. 158 * \param[in] L a pointer to the LUA state. 159 */ lua_has_error(lua_State * L)160 inline bool lua_has_error(lua_State* L) { 161 lua_getfield(L,LUA_REGISTRYINDEX,"last_geogram_error"); 162 bool result = !lua_isnil(L,-1); 163 lua_pop(L,1); 164 return result; 165 } 166 167 /** 168 * \brief Tests whether a LUA variable has the correct type. 169 * \details If the LUA variable does not have the correct type, 170 * then an error message is memorized in the registry. 171 * \param[in] L a pointer to the LUA state 172 * \param[in] idx the index of the variable 173 * \param[in] test a function to test the type, taking as argument 174 * \p L and \p idx, and returning 1 if the type of the argument 175 * is correct and 0 otherwise. 176 * \retval true if the type is corret 177 * \retval false otherwise 178 */ lua_check_type(lua_State * L,int idx,lua_test_func test)179 inline bool lua_check_type(lua_State* L, int idx, lua_test_func test) { 180 if(!test(L,idx)) { 181 std::string error = std::string("Argument ") + 182 String::to_string(idx) + ": wrong argument type (" + 183 "got " + lua_typename(L,lua_type(L,idx)) + ")"; 184 lua_set_error(L, error.c_str()); 185 return false; 186 } 187 return true; 188 } 189 190 /** 191 * \brief Tests whether the expected number of arguments was pushed 192 * onto the stack. 193 * \details If the number of elements on the stack does not match 194 * the expected number of arguments, then an error message is 195 * memorized in the registry. 196 * \param[in] L a pointer to the LUA state 197 * \param[in] expected_nb_args the expected number of arguments 198 * \retval true if the expected number of arguments were pushed onto 199 * the stack 200 * \retval false otherwise 201 */ lua_check_nb_args(lua_State * L,int expected_nb_args)202 inline bool lua_check_nb_args(lua_State* L, int expected_nb_args) { 203 if(lua_gettop(L) != expected_nb_args) { 204 std::string error = 205 "Expected " + String::to_string(expected_nb_args) 206 + " arg(s), got " + String::to_string(lua_gettop(L)); 207 lua_set_error(L,error.c_str()); 208 return false; 209 } 210 return true; 211 } 212 213 /** 214 * \brief Takes the last error message memorized in the registry 215 * and sends it back to LUA. 216 * \details This function is called by wrappers right before returning 217 * each time an error is detected. 218 * \retval the return value supposed to be returned by the wrapper, 219 * as follows: 220 * \code 221 * if(error occured) { 222 * return lua_notify_last_error(L); 223 * } 224 * \endcode 225 */ lua_notify_last_error(lua_State * L)226 inline int lua_notify_last_error(lua_State* L) { 227 std::string error; 228 lua_getfield(L,LUA_REGISTRYINDEX,"last_geogram_error"); 229 if(lua_isstring(L,-1)) { 230 error += lua_tostring(L,-1); 231 } 232 lua_pop(L,1); 233 lua_clear_error(L); 234 return luaL_error(L,error.c_str()); 235 } 236 237 /**********************************************************************/ 238 239 /** 240 * \brief Converts LUA variables to C++ variables. 241 * \details This version is a placeholder, the actual implementation 242 * is done in the template specializations. 243 */ 244 template <class T> class lua_to { 245 public: 246 /** 247 * \brief lua_to constructor. 248 * \details Does the actual conversion. The converted variable 249 * is memorized in a member. It can be accesed by a conversion 250 * operator. Supposing that my_function() takes a std::string and 251 * an int as arguments, it can be called as follows: 252 * \code 253 * my_function(lua_to<std::string>(L,1), lua_to<int>(L,2)); 254 * \endcode 255 * \param[in] L a pointer to the LUA state. 256 * \param[in] idx the index of the variable to be converted. 257 */ lua_to(lua_State * L,int idx)258 lua_to(lua_State* L, int idx) { 259 geo_argused(L); 260 geo_argused(idx); 261 geo_assert_not_reached; 262 } 263 264 /** 265 * \brief Tests whether a LUA variable can be converted to 266 * a C++ variable. 267 * \note It would have been possible to make the constructor throw 268 * an exception on conversion error, but exceptions are not well 269 * supported by Emscripten so we have separated validity check from 270 * conversion. 271 * \param[in] L a pointer to the LUA state. 272 * \param[in] idx the index of the variable to be converted. 273 * \retval true if the LUA variable can be converted to a C++ variable. 274 * \retval false otherwise. 275 */ can_convert(lua_State * L,int idx)276 static bool can_convert(lua_State* L, int idx) { 277 geo_argused(L); 278 geo_argused(idx); 279 geo_assert_not_reached; 280 } 281 282 /** 283 * \brief Gets the converted value. 284 * \return the converted value. 285 */ T()286 operator T() const { 287 geo_assert_not_reached; 288 } 289 protected: 290 T x_; 291 }; 292 293 /** 294 * \brief lua_to specialization for int. 295 */ 296 template<> class lua_to<int> { 297 public: lua_to(lua_State * L,int idx)298 lua_to(lua_State* L, int idx) { 299 x_ = int(lua_tointeger(L,idx)); 300 } can_convert(lua_State * L,int idx)301 static bool can_convert(lua_State* L, int idx) { 302 return lua_check_type(L, idx, lua_isinteger); 303 } 304 operator int() const { 305 return x_; 306 } 307 private: 308 int x_; 309 }; 310 311 /** 312 * \brief lua_to specialization for Numeric::uint32. 313 */ 314 template<> class lua_to<Numeric::uint32> { 315 public: lua_to(lua_State * L,int idx)316 lua_to(lua_State* L, int idx) { 317 x_ = Numeric::uint32(lua_tointeger(L,idx)); 318 } can_convert(lua_State * L,int idx)319 static bool can_convert(lua_State* L, int idx) { 320 return lua_check_type(L, idx, my_lua_ispositiveinteger); 321 } uint32()322 operator Numeric::uint32() const { 323 return x_; 324 } 325 private: 326 Numeric::uint32 x_; 327 }; 328 329 /** 330 * \brief lua_to specialization for Numeric::uint64. 331 */ 332 template<> class lua_to<Numeric::uint64> { 333 public: lua_to(lua_State * L,int idx)334 lua_to(lua_State* L, int idx) { 335 x_ = Numeric::uint64(lua_tointeger(L,idx)); 336 } can_convert(lua_State * L,int idx)337 static bool can_convert(lua_State* L, int idx) { 338 return lua_check_type(L, idx, my_lua_ispositiveinteger); 339 } uint64()340 operator Numeric::uint64() const { 341 return x_; 342 } 343 private: 344 Numeric::uint64 x_; 345 }; 346 347 348 /** 349 * \brief lua_to specialization for Numeric::int64. 350 */ 351 template<> class lua_to<Numeric::int64> { 352 public: lua_to(lua_State * L,int idx)353 lua_to(lua_State* L, int idx) { 354 x_ = Numeric::int64(lua_tointeger(L,idx)); 355 } can_convert(lua_State * L,int idx)356 static bool can_convert(lua_State* L, int idx) { 357 return lua_check_type(L, idx, lua_isinteger); 358 } int64()359 operator Numeric::int64() const { 360 return x_; 361 } 362 private: 363 Numeric::int64 x_; 364 }; 365 366 /** 367 * \brief lua_to specialization for float. 368 */ 369 template<> class lua_to<float> { 370 public: lua_to(lua_State * L,int idx)371 lua_to(lua_State* L, int idx) { 372 x_ = float(lua_tonumber(L,idx)); 373 } can_convert(lua_State * L,int idx)374 static bool can_convert(lua_State* L, int idx) { 375 return lua_check_type(L, idx, lua_isnumber); 376 } 377 operator float() const { 378 return x_; 379 } 380 private: 381 float x_; 382 }; 383 384 /** 385 * \brief lua_to specialization for double. 386 */ 387 template<> class lua_to<double> { 388 public: lua_to(lua_State * L,int idx)389 lua_to(lua_State* L, int idx) { 390 x_ = double(lua_tonumber(L,idx)); 391 } can_convert(lua_State * L,int idx)392 static bool can_convert(lua_State* L, int idx) { 393 return lua_check_type(L, idx, lua_isnumber); 394 } 395 operator double() const { 396 return x_; 397 } 398 private: 399 double x_; 400 }; 401 402 /** 403 * \brief lua_to specialization for bool. 404 */ 405 template<> class lua_to<bool> { 406 public: lua_to(lua_State * L,int idx)407 lua_to(lua_State* L, int idx) { 408 x_ = (lua_toboolean(L,idx) != 0); 409 } can_convert(lua_State * L,int idx)410 static bool can_convert(lua_State* L, int idx) { 411 return lua_check_type(L, idx, my_lua_isboolean); 412 } 413 operator bool() const { 414 return x_; 415 } 416 private: 417 bool x_; 418 }; 419 420 /** 421 * \brief lua_to specialization for raw string (const char*). 422 */ 423 template<> class lua_to<const char*> { 424 public: lua_to(lua_State * L,int idx)425 lua_to(lua_State* L, int idx) { 426 x_ = lua_tostring(L,idx); 427 } can_convert(lua_State * L,int idx)428 static bool can_convert(lua_State* L, int idx) { 429 return lua_check_type(L, idx, lua_isstring); 430 } 431 operator const char*() const { 432 return x_; 433 } 434 private: 435 const char* x_; 436 }; 437 438 /** 439 * \brief lua_to specialization for reference to std::string. 440 */ 441 template<> class lua_to<const std::string&> { 442 public: lua_to(lua_State * L,int idx)443 lua_to(lua_State* L, int idx) { 444 x_ = lua_tostring(L,idx); 445 } can_convert(lua_State * L,int idx)446 static bool can_convert(lua_State* L, int idx) { 447 return lua_check_type(L, idx, lua_isstring); 448 } 449 operator const std::string&() const { 450 return x_; 451 } 452 private: 453 std::string x_; 454 }; 455 456 /** 457 * \brief lua_to specialization for std::string. 458 */ 459 template<> class lua_to<std::string> { 460 public: lua_to(lua_State * L,int idx)461 lua_to(lua_State* L, int idx) { 462 x_ = lua_tostring(L,idx); 463 } can_convert(lua_State * L,int idx)464 static bool can_convert(lua_State* L, int idx) { 465 return lua_check_type(L, idx, lua_isstring); 466 } string()467 operator std::string() const { 468 return x_; 469 } 470 private: 471 std::string x_; 472 }; 473 474 /**********************************************************************/ 475 476 /** 477 * \brief Converts and pushes a C++ variable onto the LUA stack. 478 * \details This version is a placeholder. The actual implementation 479 * is done in the specializations. 480 * \note Just using function overloading (instead of template partializations) 481 * works with gcc, but does not work with clang and MSVC. 482 * \param[in] L a pointer to the LUA state. 483 * \param[in] x the variable to be pushed. 484 */ lua_push(lua_State * L,T x)485 template<class T> inline void lua_push(lua_State* L, T x) { 486 geo_argused(L); 487 geo_argused(x); 488 geo_assert_not_reached; 489 } 490 491 /** 492 * \brief Specialization of lua_push() for int. 493 */ lua_push(lua_State * L,int x)494 template<> inline void lua_push(lua_State* L, int x) { 495 lua_pushinteger(L,lua_Integer(x)); 496 } 497 498 499 /** 500 * \brief Specialization of lua_push() for Numeric::uint32. 501 */ lua_push(lua_State * L,Numeric::uint32 x)502 template<> inline void lua_push(lua_State* L, Numeric::uint32 x) { 503 lua_pushinteger(L,lua_Integer(x)); 504 } 505 506 /** 507 * \brief Specialization of lua_push() for Numeric::uint64. 508 */ lua_push(lua_State * L,Numeric::uint64 x)509 template<> inline void lua_push(lua_State* L, Numeric::uint64 x) { 510 lua_pushinteger(L,lua_Integer(x)); 511 } 512 513 /** 514 * \brief Specialization of lua_push() for Numeric::int64. 515 */ lua_push(lua_State * L,Numeric::int64 x)516 template<> inline void lua_push(lua_State* L, Numeric::int64 x) { 517 lua_pushinteger(L,lua_Integer(x)); 518 } 519 520 /** 521 * \brief Specialization of lua_push() for float. 522 */ lua_push(lua_State * L,float x)523 template<> inline void lua_push(lua_State* L, float x) { 524 lua_pushnumber(L,lua_Number(x)); 525 } 526 527 /** 528 * \brief Specialization of lua_push() for double. 529 */ lua_push(lua_State * L,double x)530 template<> inline void lua_push(lua_State* L, double x) { 531 lua_pushnumber(L,lua_Number(x)); 532 } 533 534 /** 535 * \brief Specialization of lua_push() for bool. 536 */ lua_push(lua_State * L,bool x)537 template<> inline void lua_push(lua_State* L, bool x) { 538 lua_pushboolean(L,x?1:0); 539 } 540 541 /** 542 * \brief Specialization of lua_push() for raw string (const char*). 543 */ lua_push(lua_State * L,const char * x)544 template<> inline void lua_push(lua_State* L, const char* x) { 545 lua_pushstring(L,x); 546 } 547 548 /** 549 * \brief Specialization of lua_push() for reference to std::string. 550 */ lua_push(lua_State * L,const std::string & x)551 template<> inline void lua_push(lua_State* L, const std::string& x) { 552 lua_pushstring(L,x.c_str()); 553 } 554 555 /** 556 * \brief Specialization of lua_push() for std::string. 557 */ lua_push(lua_State * L,std::string x)558 template<> inline void lua_push(lua_State* L, std::string x) { 559 lua_pushstring(L,x.c_str()); 560 } 561 562 /** 563 * \brief Specialization of lua_push() for vectors. 564 * \details It pushes a table, indexed by integers, from 1 to n (rather than 565 * 0 to n-1, following LUA indexing convention). 566 */ lua_push(lua_State * L,const std::vector<T> & x)567 template<class T> inline void lua_push( 568 lua_State* L, const std::vector<T>& x 569 ) { 570 lua_newtable(L); 571 for(size_t i=0; i<x.size(); ++i) { 572 lua_push(L,x[i]); 573 lua_seti(L,-2,lua_Integer(i+1)); 574 } 575 } 576 577 /** 578 * \brief Declares a new enum type that can be used by LUA wrappers. 579 * \details enum types that can be used in wrapped functions need to be 580 * explicitely declared before using lua_bindwrapper() and 581 * lua_bindwrapperglobal(). This will be no longer the case when we will 582 * switch to C++11 (but for now, geogram needs to remain compatible with 583 * C++98). 584 * \note LUA_DECLAREENUMTYPE cannot be done from within a function. 585 * \param[in] T the C++ type name of the enum. 586 */ 587 #define LUA_DECLAREENUMTYPE(T) \ 588 template<> inline void lua_push(lua_State* L, T x) { \ 589 lua_push(L, int(x)); \ 590 } \ 591 \ 592 template<> class lua_to<T> : public GEO::lua_to<int> { \ 593 public: \ 594 lua_to(lua_State* L, int idx) : lua_to<int>(L,idx) { \ 595 } \ 596 operator T() const { \ 597 return T(lua_to<int>::operator int()); \ 598 } \ 599 } 600 601 /**********************************************************************/ 602 603 /** 604 * \brief Calls a C++ function from LUA. 605 * \details The arguments are converted from the LUA stack, and the 606 * return value pushed onto the LUA stack. Whenever an error occurs, 607 * (invalid number of arguments or type error), it is captured and 608 * an error message is returned to the caller. 609 */ lua_wrap(lua_State * L,R (* fptr)(void))610 template <class R> inline int lua_wrap(lua_State* L, R (*fptr)(void)) { 611 if(!lua_check_nb_args(L,0)) { 612 return lua_notify_last_error(L); 613 } 614 R retval = fptr(); 615 lua_push(L,retval); 616 return 1; 617 } 618 619 /** 620 * \brief Calls a C++ function from LUA. 621 * \details The arguments are converted from the LUA stack, and the 622 * return value pushed onto the LUA stack. Whenever an error occurs, 623 * (invalid number of arguments or type error), it is captured and 624 * an error message is returned to the caller. 625 */ lua_wrap(lua_State * L,R (* fptr)(T1))626 template <class R, class T1> inline int lua_wrap( 627 lua_State* L, R (*fptr)(T1) 628 ) { 629 if( 630 !lua_check_nb_args(L,1) || 631 !lua_to<T1>::can_convert(L,1) 632 ) { 633 return lua_notify_last_error(L); 634 } 635 R retval = fptr( 636 lua_to<T1>(L,1) 637 ); 638 lua_push(L,retval); 639 return 1; 640 } 641 642 /** 643 * \brief Calls a C++ function from LUA. 644 * \details The arguments are converted from the LUA stack, and the 645 * return value pushed onto the LUA stack. Whenever an error occurs, 646 * (invalid number of arguments or type error), it is captured and 647 * an error message is returned to the caller. 648 */ lua_wrap(lua_State * L,R (* fptr)(T1,T2))649 template <class R, class T1, class T2> inline int lua_wrap( 650 lua_State* L, R (*fptr)(T1,T2) 651 ) { 652 if( 653 !lua_check_nb_args(L,2) || 654 !lua_to<T1>::can_convert(L,1) || 655 !lua_to<T2>::can_convert(L,2) 656 ) { 657 return lua_notify_last_error(L); 658 } 659 R retval = fptr( 660 lua_to<T1>(L,1), 661 lua_to<T2>(L,2) 662 ); 663 lua_push(L,retval); 664 return 1; 665 } 666 667 /** 668 * \brief Calls a C++ function from LUA. 669 * \details The arguments are converted from the LUA stack, and the 670 * return value pushed onto the LUA stack. Whenever an error occurs, 671 * (invalid number of arguments or type error), it is captured and 672 * an error message is returned to the caller. 673 */ lua_wrap(lua_State * L,R (* fptr)(T1,T2,T3))674 template <class R, class T1, class T2, class T3> inline int lua_wrap( 675 lua_State* L, R (*fptr)(T1,T2,T3) 676 ) { 677 if( 678 !lua_check_nb_args(L,3) || 679 !lua_to<T1>::can_convert(L,1) || 680 !lua_to<T2>::can_convert(L,2) || 681 !lua_to<T3>::can_convert(L,3) 682 ) { 683 return lua_notify_last_error(L); 684 } 685 R retval = fptr( 686 lua_to<T1>(L,1), 687 lua_to<T2>(L,2), 688 lua_to<T3>(L,3) 689 ); 690 lua_push(L,retval); 691 return 1; 692 } 693 694 /** 695 * \brief Calls a C++ function from LUA. 696 * \details The arguments are converted from the LUA stack, and the 697 * return value pushed onto the LUA stack. Whenever an error occurs, 698 * (invalid number of arguments or type error), it is captured and 699 * an error message is returned to the caller. 700 */ 701 template <class R, class T1, class T2, class T3, class T4> lua_wrap(lua_State * L,R (* fptr)(T1,T2,T3,T4))702 inline int lua_wrap(lua_State* L, R (*fptr)(T1,T2,T3,T4)) { 703 if( 704 !lua_check_nb_args(L,4) || 705 !lua_to<T1>::can_convert(L,1) || 706 !lua_to<T2>::can_convert(L,2) || 707 !lua_to<T3>::can_convert(L,3) || 708 !lua_to<T4>::can_convert(L,4) 709 ) { 710 return lua_notify_last_error(L); 711 } 712 R retval = fptr( 713 lua_to<T1>(L,1), 714 lua_to<T2>(L,2), 715 lua_to<T3>(L,3), 716 lua_to<T4>(L,4) 717 ); 718 lua_push(L,retval); 719 return 1; 720 } 721 722 /*************************************************************************/ 723 724 /** 725 * \brief Calls a C++ function from LUA. 726 * \details The arguments are converted from the LUA stack. 727 * Whenever an error occurs, (invalid number of arguments or type error), 728 * it is captured and an error message is returned to the caller. 729 */ lua_wrap(lua_State * L,void (* fptr)(void))730 template <> inline int lua_wrap(lua_State* L, void (*fptr)(void)) { 731 if(!lua_check_nb_args(L,0)) { 732 return lua_notify_last_error(L); 733 } 734 fptr(); 735 return 0; 736 } 737 738 /** 739 * \brief Calls a C++ function from LUA. 740 * \details The arguments are converted from the LUA stack. 741 * Whenever an error occurs, (invalid number of arguments or type error), 742 * it is captured and an error message is returned to the caller. 743 */ lua_wrap(lua_State * L,void (* fptr)(T1))744 template <class T1> inline int lua_wrap(lua_State* L, void (*fptr)(T1)) { 745 if( 746 !lua_check_nb_args(L,1) || 747 !lua_to<T1>::can_convert(L,1) 748 ) { 749 return lua_notify_last_error(L); 750 } 751 fptr( 752 lua_to<T1>(L,1) 753 ); 754 return 0; 755 } 756 757 /** 758 * \brief Calls a C++ function from LUA. 759 * \details The arguments are converted from the LUA stack. 760 * Whenever an error occurs, (invalid number of arguments or type error), 761 * it is captured and an error message is returned to the caller. 762 */ lua_wrap(lua_State * L,void (* fptr)(T1,T2))763 template <class T1, class T2> inline int lua_wrap( 764 lua_State* L, void (*fptr)(T1,T2) 765 ) { 766 if( 767 !lua_check_nb_args(L,2) || 768 !lua_to<T1>::can_convert(L,1) || 769 !lua_to<T2>::can_convert(L,2) 770 ) { 771 return lua_notify_last_error(L); 772 } 773 fptr( 774 lua_to<T1>(L,1), 775 lua_to<T2>(L,2) 776 ); 777 return 0; 778 } 779 780 /** 781 * \brief Calls a C++ function from LUA. 782 * \details The arguments are converted from the LUA stack. 783 * Whenever an error occurs, (invalid number of arguments or type error), 784 * it is captured and an error message is returned to the caller. 785 */ 786 template <class T1, class T2, class T3> lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3))787 inline int lua_wrap(lua_State* L, void (*fptr)(T1,T2,T3)) { 788 if( 789 !lua_check_nb_args(L,3) || 790 !lua_to<T1>::can_convert(L,1) || 791 !lua_to<T2>::can_convert(L,2) || 792 !lua_to<T3>::can_convert(L,3) 793 ) { 794 return lua_notify_last_error(L); 795 } 796 fptr( 797 lua_to<T1>(L,1), 798 lua_to<T2>(L,2), 799 lua_to<T3>(L,3) 800 ); 801 return 0; 802 } 803 804 /** 805 * \brief Calls a C++ function from LUA. 806 * \details The arguments are converted from the LUA stack. 807 * Whenever an error occurs, (invalid number of arguments or type error), 808 * it is captured and an error message is returned to the caller. 809 */ 810 template <class T1, class T2, class T3, class T4> lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4))811 inline int lua_wrap(lua_State* L, void (*fptr)(T1,T2,T3,T4)) { 812 if( 813 !lua_check_nb_args(L,4) || 814 !lua_to<T1>::can_convert(L,1) || 815 !lua_to<T2>::can_convert(L,2) || 816 !lua_to<T3>::can_convert(L,3) || 817 !lua_to<T4>::can_convert(L,4) 818 ) { 819 return lua_notify_last_error(L); 820 } 821 fptr( 822 lua_to<T1>(L,1), 823 lua_to<T2>(L,2), 824 lua_to<T3>(L,3), 825 lua_to<T4>(L,4) 826 ); 827 return 0; 828 } 829 830 /** 831 * \brief Calls a C++ function from LUA. 832 * \details The arguments are converted from the LUA stack. 833 * Whenever an error occurs, (invalid number of arguments or type error), 834 * it is captured and an error message is returned to the caller. 835 */ 836 template < 837 class T1, class T2, class T3, class T4, class T5 838 > lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4,T5))839 inline int lua_wrap( 840 lua_State* L, void (*fptr)(T1,T2,T3,T4,T5) 841 ) { 842 if( 843 !lua_check_nb_args(L,5) || 844 !lua_to<T1>::can_convert(L,1) || 845 !lua_to<T2>::can_convert(L,2) || 846 !lua_to<T3>::can_convert(L,3) || 847 !lua_to<T4>::can_convert(L,4) || 848 !lua_to<T5>::can_convert(L,5) 849 ) { 850 return lua_notify_last_error(L); 851 } 852 fptr( 853 lua_to<T1>(L,1), 854 lua_to<T2>(L,2), 855 lua_to<T3>(L,3), 856 lua_to<T4>(L,4), 857 lua_to<T5>(L,5) 858 ); 859 return 0; 860 } 861 862 /** 863 * \brief Calls a C++ function from LUA. 864 * \details The arguments are converted from the LUA stack. 865 * Whenever an error occurs, (invalid number of arguments or type error), 866 * it is captured and an error message is returned to the caller. 867 */ 868 template < 869 class T1, class T2, class T3, class T4, class T5, class T6 870 > lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4,T5,T6))871 inline int lua_wrap( 872 lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6) 873 ) { 874 if( 875 !lua_check_nb_args(L,6) || 876 !lua_to<T1>::can_convert(L,1) || 877 !lua_to<T2>::can_convert(L,2) || 878 !lua_to<T3>::can_convert(L,3) || 879 !lua_to<T4>::can_convert(L,4) || 880 !lua_to<T5>::can_convert(L,5) || 881 !lua_to<T6>::can_convert(L,6) 882 ) { 883 return lua_notify_last_error(L); 884 } 885 fptr( 886 lua_to<T1>(L,1), 887 lua_to<T2>(L,2), 888 lua_to<T3>(L,3), 889 lua_to<T4>(L,4), 890 lua_to<T5>(L,5), 891 lua_to<T6>(L,6) 892 ); 893 return 0; 894 } 895 896 /** 897 * \brief Calls a C++ function from LUA. 898 * \details The arguments are converted from the LUA stack. 899 * Whenever an error occurs, (invalid number of arguments or type error), 900 * it is captured and an error message is returned to the caller. 901 */ 902 template < 903 class T1, class T2, class T3, class T4, class T5, 904 class T6, class T7 905 > lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4,T5,T6,T7))906 inline int lua_wrap( 907 lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7) 908 ) { 909 if( 910 !lua_check_nb_args(L,7) || 911 !lua_to<T1>::can_convert(L,1) || 912 !lua_to<T2>::can_convert(L,2) || 913 !lua_to<T3>::can_convert(L,3) || 914 !lua_to<T4>::can_convert(L,4) || 915 !lua_to<T5>::can_convert(L,5) || 916 !lua_to<T6>::can_convert(L,6) || 917 !lua_to<T7>::can_convert(L,7) 918 ) { 919 return lua_notify_last_error(L); 920 } 921 fptr( 922 lua_to<T1>(L,1), 923 lua_to<T2>(L,2), 924 lua_to<T3>(L,3), 925 lua_to<T4>(L,4), 926 lua_to<T5>(L,5), 927 lua_to<T6>(L,6), 928 lua_to<T7>(L,7) 929 ); 930 return 0; 931 } 932 933 934 /** 935 * \brief Calls a C++ function from LUA. 936 * \details The arguments are converted from the LUA stack. 937 * Whenever an error occurs, (invalid number of arguments or type error), 938 * it is captured and an error message is returned to the caller. 939 */ 940 template < 941 class T1, class T2, class T3, class T4, class T5, 942 class T6, class T7, class T8 943 > lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4,T5,T6,T7,T8))944 inline int lua_wrap( 945 lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8) 946 ) { 947 if( 948 !lua_check_nb_args(L,8) || 949 !lua_to<T1>::can_convert(L,1) || 950 !lua_to<T2>::can_convert(L,2) || 951 !lua_to<T3>::can_convert(L,3) || 952 !lua_to<T4>::can_convert(L,4) || 953 !lua_to<T5>::can_convert(L,5) || 954 !lua_to<T6>::can_convert(L,6) || 955 !lua_to<T7>::can_convert(L,7) || 956 !lua_to<T8>::can_convert(L,8) 957 ) { 958 return lua_notify_last_error(L); 959 } 960 fptr( 961 lua_to<T1>(L,1), 962 lua_to<T2>(L,2), 963 lua_to<T3>(L,3), 964 lua_to<T4>(L,4), 965 lua_to<T5>(L,5), 966 lua_to<T6>(L,6), 967 lua_to<T7>(L,7), 968 lua_to<T8>(L,8) 969 ); 970 return 0; 971 } 972 973 974 /** 975 * \brief Calls a C++ function from LUA. 976 * \details The arguments are converted from the LUA stack. 977 * Whenever an error occurs, (invalid number of arguments or type error), 978 * it is captured and an error message is returned to the caller. 979 */ 980 template < 981 class T1, class T2, class T3, class T4, class T5, 982 class T6, class T7, class T8, class T9 983 > lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9))984 inline int lua_wrap( 985 lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9) 986 ) { 987 if( 988 !lua_check_nb_args(L,9) || 989 !lua_to<T1>::can_convert(L,1) || 990 !lua_to<T2>::can_convert(L,2) || 991 !lua_to<T3>::can_convert(L,3) || 992 !lua_to<T4>::can_convert(L,4) || 993 !lua_to<T5>::can_convert(L,5) || 994 !lua_to<T6>::can_convert(L,6) || 995 !lua_to<T7>::can_convert(L,7) || 996 !lua_to<T8>::can_convert(L,8) || 997 !lua_to<T9>::can_convert(L,9) 998 ) { 999 return lua_notify_last_error(L); 1000 } 1001 fptr( 1002 lua_to<T1>(L,1), 1003 lua_to<T2>(L,2), 1004 lua_to<T3>(L,3), 1005 lua_to<T4>(L,4), 1006 lua_to<T5>(L,5), 1007 lua_to<T6>(L,6), 1008 lua_to<T7>(L,7), 1009 lua_to<T8>(L,8), 1010 lua_to<T9>(L,9) 1011 ); 1012 return 0; 1013 } 1014 1015 1016 /** 1017 * \brief Calls a C++ function from LUA. 1018 * \details The arguments are converted from the LUA stack. 1019 * Whenever an error occurs, (invalid number of arguments or type error), 1020 * it is captured and an error message is returned to the caller. 1021 */ 1022 template < 1023 class T1, class T2, class T3, class T4, class T5, 1024 class T6, class T7, class T8, class T9, class T10 1025 > lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10))1026 inline int lua_wrap( 1027 lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10) 1028 ) { 1029 if( 1030 !lua_check_nb_args(L,10) || 1031 !lua_to<T1>::can_convert(L,1) || 1032 !lua_to<T2>::can_convert(L,2) || 1033 !lua_to<T3>::can_convert(L,3) || 1034 !lua_to<T4>::can_convert(L,4) || 1035 !lua_to<T5>::can_convert(L,5) || 1036 !lua_to<T6>::can_convert(L,6) || 1037 !lua_to<T7>::can_convert(L,7) || 1038 !lua_to<T8>::can_convert(L,8) || 1039 !lua_to<T9>::can_convert(L,9) || 1040 !lua_to<T10>::can_convert(L,10) 1041 ) { 1042 return lua_notify_last_error(L); 1043 } 1044 fptr( 1045 lua_to<T1>(L,1), 1046 lua_to<T2>(L,2), 1047 lua_to<T3>(L,3), 1048 lua_to<T4>(L,4), 1049 lua_to<T5>(L,5), 1050 lua_to<T6>(L,6), 1051 lua_to<T7>(L,7), 1052 lua_to<T8>(L,8), 1053 lua_to<T9>(L,9), 1054 lua_to<T10>(L,10) 1055 ); 1056 return 0; 1057 } 1058 1059 1060 /** 1061 * \brief Calls a C++ function from LUA. 1062 * \details The arguments are converted from the LUA stack. 1063 * Whenever an error occurs, (invalid number of arguments or type error), 1064 * it is captured and an error message is returned to the caller. 1065 */ 1066 template < 1067 class T1, class T2, class T3, class T4, class T5, 1068 class T6, class T7, class T8, class T9, class T10, 1069 class T11 1070 > lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11))1071 inline int lua_wrap( 1072 lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11) 1073 ) { 1074 if( 1075 !lua_check_nb_args(L,11) || 1076 !lua_to<T1>::can_convert(L,1) || 1077 !lua_to<T2>::can_convert(L,2) || 1078 !lua_to<T3>::can_convert(L,3) || 1079 !lua_to<T4>::can_convert(L,4) || 1080 !lua_to<T5>::can_convert(L,5) || 1081 !lua_to<T6>::can_convert(L,6) || 1082 !lua_to<T7>::can_convert(L,7) || 1083 !lua_to<T8>::can_convert(L,8) || 1084 !lua_to<T9>::can_convert(L,9) || 1085 !lua_to<T10>::can_convert(L,10) || 1086 !lua_to<T11>::can_convert(L,11) 1087 ) { 1088 return lua_notify_last_error(L); 1089 } 1090 fptr( 1091 lua_to<T1>(L,1), 1092 lua_to<T2>(L,2), 1093 lua_to<T3>(L,3), 1094 lua_to<T4>(L,4), 1095 lua_to<T5>(L,5), 1096 lua_to<T6>(L,6), 1097 lua_to<T7>(L,7), 1098 lua_to<T8>(L,8), 1099 lua_to<T9>(L,9), 1100 lua_to<T10>(L,10), 1101 lua_to<T11>(L,11) 1102 ); 1103 return 0; 1104 } 1105 1106 /** 1107 * \brief Calls a C++ function from LUA. 1108 * \details The arguments are converted from the LUA stack. 1109 * Whenever an error occurs, (invalid number of arguments or type error), 1110 * it is captured and an error message is returned to the caller. 1111 */ 1112 template < 1113 class T1, class T2, class T3, class T4, class T5, 1114 class T6, class T7, class T8, class T9, class T10, 1115 class T11, class T12 1116 > lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12))1117 inline int lua_wrap( 1118 lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12) 1119 ) { 1120 if( 1121 !lua_check_nb_args(L,12) || 1122 !lua_to<T1>::can_convert(L,1) || 1123 !lua_to<T2>::can_convert(L,2) || 1124 !lua_to<T3>::can_convert(L,3) || 1125 !lua_to<T4>::can_convert(L,4) || 1126 !lua_to<T5>::can_convert(L,5) || 1127 !lua_to<T6>::can_convert(L,6) || 1128 !lua_to<T7>::can_convert(L,7) || 1129 !lua_to<T8>::can_convert(L,8) || 1130 !lua_to<T9>::can_convert(L,9) || 1131 !lua_to<T10>::can_convert(L,10) || 1132 !lua_to<T11>::can_convert(L,11) || 1133 !lua_to<T12>::can_convert(L,12) 1134 ) { 1135 return lua_notify_last_error(L); 1136 } 1137 fptr( 1138 lua_to<T1>(L,1), 1139 lua_to<T2>(L,2), 1140 lua_to<T3>(L,3), 1141 lua_to<T4>(L,4), 1142 lua_to<T5>(L,5), 1143 lua_to<T6>(L,6), 1144 lua_to<T7>(L,7), 1145 lua_to<T8>(L,8), 1146 lua_to<T9>(L,9), 1147 lua_to<T10>(L,10), 1148 lua_to<T11>(L,11), 1149 lua_to<T12>(L,12) 1150 ); 1151 return 0; 1152 } 1153 1154 1155 /** 1156 * \brief Calls a C++ function from LUA. 1157 * \details The arguments are converted from the LUA stack. 1158 * Whenever an error occurs, (invalid number of arguments or type error), 1159 * it is captured and an error message is returned to the caller. 1160 */ 1161 template < 1162 class T1, class T2, class T3, class T4, class T5, 1163 class T6, class T7, class T8, class T9, class T10, 1164 class T11, class T12, class T13 1165 > lua_wrap(lua_State * L,void (* fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13))1166 inline int lua_wrap( 1167 lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13) 1168 ) { 1169 if( 1170 !lua_check_nb_args(L,13) || 1171 !lua_to<T1>::can_convert(L,1) || 1172 !lua_to<T2>::can_convert(L,2) || 1173 !lua_to<T3>::can_convert(L,3) || 1174 !lua_to<T4>::can_convert(L,4) || 1175 !lua_to<T5>::can_convert(L,5) || 1176 !lua_to<T6>::can_convert(L,6) || 1177 !lua_to<T7>::can_convert(L,7) || 1178 !lua_to<T8>::can_convert(L,8) || 1179 !lua_to<T9>::can_convert(L,9) || 1180 !lua_to<T10>::can_convert(L,10) || 1181 !lua_to<T11>::can_convert(L,11) || 1182 !lua_to<T12>::can_convert(L,12) || 1183 !lua_to<T12>::can_convert(L,13) 1184 ) { 1185 return lua_notify_last_error(L); 1186 } 1187 fptr( 1188 lua_to<T1>(L,1), 1189 lua_to<T2>(L,2), 1190 lua_to<T3>(L,3), 1191 lua_to<T4>(L,4), 1192 lua_to<T5>(L,5), 1193 lua_to<T6>(L,6), 1194 lua_to<T7>(L,7), 1195 lua_to<T8>(L,8), 1196 lua_to<T9>(L,9), 1197 lua_to<T10>(L,10), 1198 lua_to<T11>(L,11), 1199 lua_to<T12>(L,12), 1200 lua_to<T13>(L,13) 1201 ); 1202 return 0; 1203 } 1204 1205 /** 1206 * \brief Specialization of the wrapper for functions that 1207 * are "already wrapped". 1208 * \note Normally not used, since there is a specialization of 1209 * lua_pushwrapper() for lua_CFunction. 1210 */ lua_wrap(lua_State * L,lua_CFunction fptr)1211 template<> inline int lua_wrap(lua_State* L, lua_CFunction fptr) { 1212 return fptr(L); 1213 } 1214 1215 1216 /*************************************************************************/ 1217 1218 /** 1219 * \brief Manages wrappers around C++ functions to be called from LUA. 1220 * \details This class should not be used directly by client code. 1221 * Client code will rather use the high-level macro lua_bindwrapper() 1222 * or the lower-level functions lua_bindwrapperwithname() and 1223 * lua_pushwrapper(). 1224 */ 1225 template <class FPTR> class lua_wrapper { 1226 public: 1227 1228 /** 1229 * \brief Implementation of the wrapper. 1230 * \details This is the C functions to be declared to LUA. 1231 * It is typed by the signature of the wrapped C++ function, 1232 * and the pointer to the actual wrapped C++ function is stored 1233 * in an upvalue. 1234 * \param[in] L a pointer to the LUA state. 1235 */ call(lua_State * L)1236 static int call(lua_State* L) { 1237 FPTR f = FPTR( 1238 Memory::generic_pointer_to_function_pointer( 1239 lua_touserdata(L, lua_upvalueindex(1)) 1240 ) 1241 ); 1242 return lua_wrap(L, f); 1243 } 1244 1245 /** 1246 * \brief Pushes a wrapper for a given C++ function onto the LUA stack. 1247 * \param[in] L a pointer to the LUA state. 1248 * \param[in] f a pointer to the C++ function to be pushed. It cannot be 1249 * a non-static object's member function. 1250 */ push(lua_State * L,FPTR f)1251 static void push(lua_State* L, FPTR f) { 1252 lua_pushlightuserdata( 1253 L, 1254 Memory::function_pointer_to_generic_pointer( 1255 Memory::function_pointer(f) 1256 ) 1257 ); 1258 lua_pushcclosure(L, lua_wrapper<FPTR>::call, 1); 1259 } 1260 }; 1261 1262 /**************************************************************************/ 1263 1264 /** 1265 * \brief Pushes a wrapper for a given C++ function onto the LUA stack. 1266 * \param[in] L a pointer to the LUA state. 1267 * \param[in] f a pointer to the C++ function to be pushed. It cannot be 1268 * a non-static object member function. 1269 */ lua_pushwrapper(lua_State * L,FPTR f)1270 template <class FPTR> inline void lua_pushwrapper(lua_State* L, FPTR f) { 1271 lua_wrapper<FPTR>::push(L,f); 1272 } 1273 1274 /** 1275 * \brief Specialization for lua_CFunction. 1276 * \details No need for a wrapper if it is already a LUA function. 1277 */ lua_pushwrapper(lua_State * L,lua_CFunction f)1278 template<> inline void lua_pushwrapper(lua_State* L, lua_CFunction f) { 1279 lua_pushcfunction(L,f); 1280 } 1281 1282 /**************************************************************************/ 1283 1284 /** 1285 * \brief Binds a wrapper to a name in the table at the top 1286 * of the LUA stack. 1287 * \pre the object on the top of the stack is a table. 1288 * \param[in] L a pointer to the LUA state. 1289 * \param[in] f a pointer to the C++ function to be wrapped. It cannot be 1290 * a non-static object member function. 1291 */ lua_bindwrapperwithname(lua_State * L,FPTR f,const std::string & name)1292 template <class FPTR> inline void lua_bindwrapperwithname( 1293 lua_State* L, FPTR f, const std::string& name 1294 ) { 1295 geo_assert(lua_gettop(L) > 0); 1296 geo_assert(lua_istable(L,-1)); 1297 lua_pushstring(L,name.c_str()); 1298 lua_pushwrapper(L,f); 1299 lua_settable(L,-3); 1300 } 1301 1302 1303 /** 1304 * \brief Binds a wrapper to a name in the global scole. 1305 * \param[in] L a pointer to the LUA state. 1306 * \param[in] f a pointer to the C++ function to be wrapped. It cannot be 1307 * a non-static object member function. 1308 */ lua_bindwrapperwithnameglobal(lua_State * L,FPTR f,const std::string & name)1309 template <class FPTR> inline void lua_bindwrapperwithnameglobal( 1310 lua_State* L, FPTR f, const std::string& name 1311 ) { 1312 lua_pushwrapper(L,f); 1313 lua_setglobal(L,name.c_str()); 1314 } 1315 1316 /**************************************************************************/ 1317 1318 /** 1319 * \brief Converts a C++ function name into a LUA function name. 1320 * \details Removes all namespaces from the name. 1321 * \param[in] L a pointer to the LUA state (unused). 1322 * \param[in] functionname the C++ function name. 1323 * \return a std::string with the function name with all namespaces removed. 1324 */ lua_wrappername(lua_State * L,const char * functionname)1325 inline std::string lua_wrappername(lua_State* L, const char* functionname) { 1326 geo_argused(L); 1327 std::string result(functionname); 1328 size_t pos = result.find_last_of(":"); 1329 if(pos != std::string::npos) { 1330 result = result.substr(pos+1, result.length()-pos); 1331 } 1332 return result; 1333 } 1334 1335 /**************************************************************************/ 1336 1337 /** 1338 * \brief Binds a LUA wrapper around a C++ function to the table on the top 1339 * of the LUA stack. 1340 * \details The arguments are automatically converted from the LUA stack 1341 * to the function arguments. If the function is non-void, the return 1342 * value is automatically converted to LUA and pushed onto the LUA stack. 1343 * If the function is already a LUA interface (takes a lua_State* as an 1344 * argument and returns an integer), then it will be directly called, 1345 * without any conversion. 1346 * The name of the function is obtained by removing all namespaces 1347 * from \p f. 1348 * \param[in] L a pointer to the LUA state. 1349 * \param[in] f a pointer to the C++ function to be wrapped. It cannot be 1350 * a non-static object member function. 1351 */ 1352 #define lua_bindwrapper(L, f) lua_bindwrapperwithname( \ 1353 (L),(f),GEO::lua_wrappername(L,#f) \ 1354 ) 1355 1356 /** 1357 * \brief Binds a LUA wrapper around a C++ function to the global scope. 1358 * \details The arguments are automatically converted from the LUA stack 1359 * to the function arguments. If the function is non-void, the return 1360 * value is automatically converted to LUA and pushed onto the LUA stack. 1361 * If the function is already a LUA interface (takes a lua_State* as an 1362 * argument and returns an integer), then it will be directly called, 1363 * without any conversion. 1364 * The name of the function is obtained by removing all namespaces 1365 * from \p f. 1366 * \param[in] L a pointer to the LUA state. 1367 * \param[in] f a pointer to the C++ function to be wrapped. It cannot be 1368 * a non-static object member function. 1369 */ 1370 #define lua_bindwrapperglobal(L, f) lua_bindwrapperwithnameglobal(\ 1371 (L),(f),GEO::lua_wrappername(L,#f) \ 1372 ) 1373 1374 1375 /*************************************************************************/ 1376 1377 } 1378 1379 #endif 1380