├── LuaBridge ├── .gitignore ├── CHANGES ├── Doxyfile ├── LuaBridge.h ├── README.md ├── RefCountedObject.h └── RefCountedPtr.h ├── README.md ├── TestBindingCppWithLua.lua ├── TestConfig.lua ├── TestLuaExtendedbyC.lua ├── binding_cpp_with_lua.cpp ├── binding_cpp_with_lua.hpp ├── binding_cpp_with_lunafive.hpp ├── c_function_to_extend_lua.c ├── c_function_to_extend_lua.h ├── c_module_to_extend_lua.c ├── c_userdata_to_extend_lua.c ├── c_userdata_with_gc_to_extend_lua.c ├── capi_example.c ├── extend_c_app_by_lua.c ├── lua_class.lua ├── lua_hot_fix.lua ├── lunar.hpp ├── lunar_test_main.cpp ├── lunar_test_script.lua ├── permutation_by_coroutine.lua ├── simple_lua_interpreter.c ├── study_lua_bridge.lua ├── study_lua_bridge_main.cpp ├── test_binding_cpp_with_lua.hpp ├── test_extend_lua_by_c.c ├── test_general_call_lua_in_c.c ├── test_lua_class.lua ├── traversal_global_env.lua ├── util.c └── util.h /LuaBridge/.gitignore: -------------------------------------------------------------------------------- 1 | Documentation 2 | -------------------------------------------------------------------------------- /LuaBridge/CHANGES: -------------------------------------------------------------------------------- 1 | Version 1.0.2 2 | 3 | * Option to hide metatables selectable at runtime, default to true. 4 | * addStaticMethod () renamed to addStaticFunction () for consistency. 5 | * addMethod () renamed to addFunction() for consistency. 6 | * addCFunction () registrations. 7 | * Convert null pointers to and from nil. 8 | * Small performance increase in class pointer extraction. 9 | 10 | 2012-05-30 Version 1.0.1 11 | 12 | * Backward compatibility with Lua 5.1.x. 13 | 14 | 2012-05-29 Version 1.0 15 | 16 | * Explicit lifetime management models. 17 | * Generalized containers. 18 | * Single header distribution. 19 | 20 | 21 | -------------------------------------------------------------------------------- /LuaBridge/Doxyfile: -------------------------------------------------------------------------------- 1 | # Doxyfile 1.8.0 2 | 3 | # This file describes the settings to be used by the documentation system 4 | # doxygen (www.doxygen.org) for a project 5 | # 6 | # All text after a hash (#) is considered a comment and will be ignored 7 | # The format is: 8 | # TAG = value [value, ...] 9 | # For lists items can also be appended using: 10 | # TAG += value [value, ...] 11 | # Values that contain spaces should be placed between quotes (" ") 12 | 13 | #--------------------------------------------------------------------------- 14 | # Project related configuration options 15 | #--------------------------------------------------------------------------- 16 | 17 | # This tag specifies the encoding used for all characters in the config file 18 | # that follow. The default is UTF-8 which is also the encoding used for all 19 | # text before the first occurrence of this tag. Doxygen uses libiconv (or the 20 | # iconv built into libc) for the transcoding. See 21 | # http://www.gnu.org/software/libiconv for the list of possible encodings. 22 | 23 | DOXYFILE_ENCODING = UTF-8 24 | 25 | # The PROJECT_NAME tag is a single word (or sequence of words) that should 26 | # identify the project. Note that if you do not use Doxywizard you need 27 | # to put quotes around the project name if it contains spaces. 28 | 29 | PROJECT_NAME = LuaBridge 30 | 31 | # The PROJECT_NUMBER tag can be used to enter a project or revision number. 32 | # This could be handy for archiving the generated documentation or 33 | # if some version control system is used. 34 | 35 | PROJECT_NUMBER = 36 | 37 | # Using the PROJECT_BRIEF tag one can provide an optional one line description 38 | # for a project that appears at the top of each page and should give viewer 39 | # a quick idea about the purpose of the project. Keep the description short. 40 | 41 | PROJECT_BRIEF = 42 | 43 | # With the PROJECT_LOGO tag one can specify an logo or icon that is 44 | # included in the documentation. The maximum height of the logo should not 45 | # exceed 55 pixels and the maximum width should not exceed 200 pixels. 46 | # Doxygen will copy the logo to the output directory. 47 | 48 | PROJECT_LOGO = 49 | 50 | # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 51 | # base path where the generated documentation will be put. 52 | # If a relative path is entered, it will be relative to the location 53 | # where doxygen was started. If left blank the current directory will be used. 54 | 55 | OUTPUT_DIRECTORY = 56 | 57 | # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 58 | # 4096 sub-directories (in 2 levels) under the output directory of each output 59 | # format and will distribute the generated files over these directories. 60 | # Enabling this option can be useful when feeding doxygen a huge amount of 61 | # source files, where putting all generated files in the same directory would 62 | # otherwise cause performance problems for the file system. 63 | 64 | CREATE_SUBDIRS = NO 65 | 66 | # The OUTPUT_LANGUAGE tag is used to specify the language in which all 67 | # documentation generated by doxygen is written. Doxygen will use this 68 | # information to generate all constant output in the proper language. 69 | # The default language is English, other supported languages are: 70 | # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 71 | # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 72 | # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 73 | # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 74 | # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 75 | # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. 76 | 77 | OUTPUT_LANGUAGE = English 78 | 79 | # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 80 | # include brief member descriptions after the members that are listed in 81 | # the file and class documentation (similar to JavaDoc). 82 | # Set to NO to disable this. 83 | 84 | BRIEF_MEMBER_DESC = YES 85 | 86 | # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 87 | # the brief description of a member or function before the detailed description. 88 | # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 89 | # brief descriptions will be completely suppressed. 90 | 91 | REPEAT_BRIEF = NO 92 | 93 | # This tag implements a quasi-intelligent brief description abbreviator 94 | # that is used to form the text in various listings. Each string 95 | # in this list, if found as the leading text of the brief description, will be 96 | # stripped from the text and the result after processing the whole list, is 97 | # used as the annotated text. Otherwise, the brief description is used as-is. 98 | # If left blank, the following values are used ("$name" is automatically 99 | # replaced with the name of the entity): "The $name class" "The $name widget" 100 | # "The $name file" "is" "provides" "specifies" "contains" 101 | # "represents" "a" "an" "the" 102 | 103 | ABBREVIATE_BRIEF = 104 | 105 | # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 106 | # Doxygen will generate a detailed section even if there is only a brief 107 | # description. 108 | 109 | ALWAYS_DETAILED_SEC = NO 110 | 111 | # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 112 | # inherited members of a class in the documentation of that class as if those 113 | # members were ordinary class members. Constructors, destructors and assignment 114 | # operators of the base classes will not be shown. 115 | 116 | INLINE_INHERITED_MEMB = NO 117 | 118 | # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 119 | # path before files name in the file list and in the header files. If set 120 | # to NO the shortest path that makes the file name unique will be used. 121 | 122 | FULL_PATH_NAMES = NO 123 | 124 | # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 125 | # can be used to strip a user-defined part of the path. Stripping is 126 | # only done if one of the specified strings matches the left-hand part of 127 | # the path. The tag can be used to show relative paths in the file list. 128 | # If left blank the directory from which doxygen is run is used as the 129 | # path to strip. 130 | 131 | STRIP_FROM_PATH = 132 | 133 | # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 134 | # the path mentioned in the documentation of a class, which tells 135 | # the reader which header file to include in order to use a class. 136 | # If left blank only the name of the header file containing the class 137 | # definition is used. Otherwise one should specify the include paths that 138 | # are normally passed to the compiler using the -I flag. 139 | 140 | STRIP_FROM_INC_PATH = 141 | 142 | # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 143 | # (but less readable) file names. This can be useful if your file system 144 | # doesn't support long names like on DOS, Mac, or CD-ROM. 145 | 146 | SHORT_NAMES = NO 147 | 148 | # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 149 | # will interpret the first line (until the first dot) of a JavaDoc-style 150 | # comment as the brief description. If set to NO, the JavaDoc 151 | # comments will behave just like regular Qt-style comments 152 | # (thus requiring an explicit @brief command for a brief description.) 153 | 154 | JAVADOC_AUTOBRIEF = YES 155 | 156 | # If the QT_AUTOBRIEF tag is set to YES then Doxygen will 157 | # interpret the first line (until the first dot) of a Qt-style 158 | # comment as the brief description. If set to NO, the comments 159 | # will behave just like regular Qt-style comments (thus requiring 160 | # an explicit \brief command for a brief description.) 161 | 162 | QT_AUTOBRIEF = NO 163 | 164 | # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 165 | # treat a multi-line C++ special comment block (i.e. a block of //! or /// 166 | # comments) as a brief description. This used to be the default behaviour. 167 | # The new default is to treat a multi-line C++ comment block as a detailed 168 | # description. Set this tag to YES if you prefer the old behaviour instead. 169 | 170 | MULTILINE_CPP_IS_BRIEF = NO 171 | 172 | # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 173 | # member inherits the documentation from any documented member that it 174 | # re-implements. 175 | 176 | INHERIT_DOCS = YES 177 | 178 | # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 179 | # a new page for each member. If set to NO, the documentation of a member will 180 | # be part of the file/class/namespace that contains it. 181 | 182 | SEPARATE_MEMBER_PAGES = NO 183 | 184 | # The TAB_SIZE tag can be used to set the number of spaces in a tab. 185 | # Doxygen uses this value to replace tabs by spaces in code fragments. 186 | 187 | TAB_SIZE = 4 188 | 189 | # This tag can be used to specify a number of aliases that acts 190 | # as commands in the documentation. An alias has the form "name=value". 191 | # For example adding "sideeffect=\par Side Effects:\n" will allow you to 192 | # put the command \sideeffect (or @sideeffect) in the documentation, which 193 | # will result in a user-defined paragraph with heading "Side Effects:". 194 | # You can put \n's in the value part of an alias to insert newlines. 195 | 196 | ALIASES = 197 | 198 | # This tag can be used to specify a number of word-keyword mappings (TCL only). 199 | # A mapping has the form "name=value". For example adding 200 | # "class=itcl::class" will allow you to use the command class in the 201 | # itcl::class meaning. 202 | 203 | TCL_SUBST = 204 | 205 | # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 206 | # sources only. Doxygen will then generate output that is more tailored for C. 207 | # For instance, some of the names that are used will be different. The list 208 | # of all members will be omitted, etc. 209 | 210 | OPTIMIZE_OUTPUT_FOR_C = NO 211 | 212 | # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 213 | # sources only. Doxygen will then generate output that is more tailored for 214 | # Java. For instance, namespaces will be presented as packages, qualified 215 | # scopes will look different, etc. 216 | 217 | OPTIMIZE_OUTPUT_JAVA = NO 218 | 219 | # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 220 | # sources only. Doxygen will then generate output that is more tailored for 221 | # Fortran. 222 | 223 | OPTIMIZE_FOR_FORTRAN = NO 224 | 225 | # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 226 | # sources. Doxygen will then generate output that is tailored for 227 | # VHDL. 228 | 229 | OPTIMIZE_OUTPUT_VHDL = NO 230 | 231 | # Doxygen selects the parser to use depending on the extension of the files it 232 | # parses. With this tag you can assign which parser to use for a given extension. 233 | # Doxygen has a built-in mapping, but you can override or extend it using this 234 | # tag. The format is ext=language, where ext is a file extension, and language 235 | # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, 236 | # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make 237 | # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C 238 | # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions 239 | # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. 240 | 241 | EXTENSION_MAPPING = 242 | 243 | # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all 244 | # comments according to the Markdown format, which allows for more readable 245 | # documentation. See http://daringfireball.net/projects/markdown/ for details. 246 | # The output of markdown processing is further processed by doxygen, so you 247 | # can mix doxygen, HTML, and XML commands with Markdown formatting. 248 | # Disable only in case of backward compatibilities issues. 249 | 250 | MARKDOWN_SUPPORT = YES 251 | 252 | # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 253 | # to include (a tag file for) the STL sources as input, then you should 254 | # set this tag to YES in order to let doxygen match functions declarations and 255 | # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 256 | # func(std::string) {}). This also makes the inheritance and collaboration 257 | # diagrams that involve STL classes more complete and accurate. 258 | 259 | BUILTIN_STL_SUPPORT = YES 260 | 261 | # If you use Microsoft's C++/CLI language, you should set this option to YES to 262 | # enable parsing support. 263 | 264 | CPP_CLI_SUPPORT = NO 265 | 266 | # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 267 | # Doxygen will parse them like normal C++ but will assume all classes use public 268 | # instead of private inheritance when no explicit protection keyword is present. 269 | 270 | SIP_SUPPORT = NO 271 | 272 | # For Microsoft's IDL there are propget and propput attributes to indicate getter 273 | # and setter methods for a property. Setting this option to YES (the default) 274 | # will make doxygen replace the get and set methods by a property in the 275 | # documentation. This will only work if the methods are indeed getting or 276 | # setting a simple type. If this is not the case, or you want to show the 277 | # methods anyway, you should set this option to NO. 278 | 279 | IDL_PROPERTY_SUPPORT = YES 280 | 281 | # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 282 | # tag is set to YES, then doxygen will reuse the documentation of the first 283 | # member in the group (if any) for the other members of the group. By default 284 | # all members of a group must be documented explicitly. 285 | 286 | DISTRIBUTE_GROUP_DOC = NO 287 | 288 | # Set the SUBGROUPING tag to YES (the default) to allow class member groups of 289 | # the same type (for instance a group of public functions) to be put as a 290 | # subgroup of that type (e.g. under the Public Functions section). Set it to 291 | # NO to prevent subgrouping. Alternatively, this can be done per class using 292 | # the \nosubgrouping command. 293 | 294 | SUBGROUPING = YES 295 | 296 | # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and 297 | # unions are shown inside the group in which they are included (e.g. using 298 | # @ingroup) instead of on a separate page (for HTML and Man pages) or 299 | # section (for LaTeX and RTF). 300 | 301 | INLINE_GROUPED_CLASSES = NO 302 | 303 | # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and 304 | # unions with only public data fields will be shown inline in the documentation 305 | # of the scope in which they are defined (i.e. file, namespace, or group 306 | # documentation), provided this scope is documented. If set to NO (the default), 307 | # structs, classes, and unions are shown on a separate page (for HTML and Man 308 | # pages) or section (for LaTeX and RTF). 309 | 310 | INLINE_SIMPLE_STRUCTS = NO 311 | 312 | # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 313 | # is documented as struct, union, or enum with the name of the typedef. So 314 | # typedef struct TypeS {} TypeT, will appear in the documentation as a struct 315 | # with name TypeT. When disabled the typedef will appear as a member of a file, 316 | # namespace, or class. And the struct will be named TypeS. This can typically 317 | # be useful for C code in case the coding convention dictates that all compound 318 | # types are typedef'ed and only the typedef is referenced, never the tag name. 319 | 320 | TYPEDEF_HIDES_STRUCT = NO 321 | 322 | # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 323 | # determine which symbols to keep in memory and which to flush to disk. 324 | # When the cache is full, less often used symbols will be written to disk. 325 | # For small to medium size projects (<1000 input files) the default value is 326 | # probably good enough. For larger projects a too small cache size can cause 327 | # doxygen to be busy swapping symbols to and from disk most of the time 328 | # causing a significant performance penalty. 329 | # If the system has enough physical memory increasing the cache will improve the 330 | # performance by keeping more symbols in memory. Note that the value works on 331 | # a logarithmic scale so increasing the size by one will roughly double the 332 | # memory usage. The cache size is given by this formula: 333 | # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 334 | # corresponding to a cache size of 2^16 = 65536 symbols. 335 | 336 | SYMBOL_CACHE_SIZE = 0 337 | 338 | # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be 339 | # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given 340 | # their name and scope. Since this can be an expensive process and often the 341 | # same symbol appear multiple times in the code, doxygen keeps a cache of 342 | # pre-resolved symbols. If the cache is too small doxygen will become slower. 343 | # If the cache is too large, memory is wasted. The cache size is given by this 344 | # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, 345 | # corresponding to a cache size of 2^16 = 65536 symbols. 346 | 347 | LOOKUP_CACHE_SIZE = 0 348 | 349 | #--------------------------------------------------------------------------- 350 | # Build related configuration options 351 | #--------------------------------------------------------------------------- 352 | 353 | # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 354 | # documentation are documented, even if no documentation was available. 355 | # Private class members and static file members will be hidden unless 356 | # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES 357 | 358 | EXTRACT_ALL = NO 359 | 360 | # If the EXTRACT_PRIVATE tag is set to YES all private members of a class 361 | # will be included in the documentation. 362 | 363 | EXTRACT_PRIVATE = NO 364 | 365 | # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal 366 | # scope will be included in the documentation. 367 | 368 | EXTRACT_PACKAGE = NO 369 | 370 | # If the EXTRACT_STATIC tag is set to YES all static members of a file 371 | # will be included in the documentation. 372 | 373 | EXTRACT_STATIC = NO 374 | 375 | # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 376 | # defined locally in source files will be included in the documentation. 377 | # If set to NO only classes defined in header files are included. 378 | 379 | EXTRACT_LOCAL_CLASSES = NO 380 | 381 | # This flag is only useful for Objective-C code. When set to YES local 382 | # methods, which are defined in the implementation section but not in 383 | # the interface are included in the documentation. 384 | # If set to NO (the default) only methods in the interface are included. 385 | 386 | EXTRACT_LOCAL_METHODS = NO 387 | 388 | # If this flag is set to YES, the members of anonymous namespaces will be 389 | # extracted and appear in the documentation as a namespace called 390 | # 'anonymous_namespace{file}', where file will be replaced with the base 391 | # name of the file that contains the anonymous namespace. By default 392 | # anonymous namespaces are hidden. 393 | 394 | EXTRACT_ANON_NSPACES = NO 395 | 396 | # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 397 | # undocumented members of documented classes, files or namespaces. 398 | # If set to NO (the default) these members will be included in the 399 | # various overviews, but no documentation section is generated. 400 | # This option has no effect if EXTRACT_ALL is enabled. 401 | 402 | HIDE_UNDOC_MEMBERS = YES 403 | 404 | # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 405 | # undocumented classes that are normally visible in the class hierarchy. 406 | # If set to NO (the default) these classes will be included in the various 407 | # overviews. This option has no effect if EXTRACT_ALL is enabled. 408 | 409 | HIDE_UNDOC_CLASSES = YES 410 | 411 | # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 412 | # friend (class|struct|union) declarations. 413 | # If set to NO (the default) these declarations will be included in the 414 | # documentation. 415 | 416 | HIDE_FRIEND_COMPOUNDS = NO 417 | 418 | # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 419 | # documentation blocks found inside the body of a function. 420 | # If set to NO (the default) these blocks will be appended to the 421 | # function's detailed documentation block. 422 | 423 | HIDE_IN_BODY_DOCS = NO 424 | 425 | # The INTERNAL_DOCS tag determines if documentation 426 | # that is typed after a \internal command is included. If the tag is set 427 | # to NO (the default) then the documentation will be excluded. 428 | # Set it to YES to include the internal documentation. 429 | 430 | INTERNAL_DOCS = YES 431 | 432 | # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 433 | # file names in lower-case letters. If set to YES upper-case letters are also 434 | # allowed. This is useful if you have classes or files whose names only differ 435 | # in case and if your file system supports case sensitive file names. Windows 436 | # and Mac users are advised to set this option to NO. 437 | 438 | CASE_SENSE_NAMES = NO 439 | 440 | # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 441 | # will show members with their full class and namespace scopes in the 442 | # documentation. If set to YES the scope will be hidden. 443 | 444 | HIDE_SCOPE_NAMES = NO 445 | 446 | # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 447 | # will put a list of the files that are included by a file in the documentation 448 | # of that file. 449 | 450 | SHOW_INCLUDE_FILES = YES 451 | 452 | # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 453 | # will list include files with double quotes in the documentation 454 | # rather than with sharp brackets. 455 | 456 | FORCE_LOCAL_INCLUDES = YES 457 | 458 | # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 459 | # is inserted in the documentation for inline members. 460 | 461 | INLINE_INFO = NO 462 | 463 | # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 464 | # will sort the (detailed) documentation of file and class members 465 | # alphabetically by member name. If set to NO the members will appear in 466 | # declaration order. 467 | 468 | SORT_MEMBER_DOCS = NO 469 | 470 | # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 471 | # brief documentation of file, namespace and class members alphabetically 472 | # by member name. If set to NO (the default) the members will appear in 473 | # declaration order. 474 | 475 | SORT_BRIEF_DOCS = NO 476 | 477 | # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 478 | # will sort the (brief and detailed) documentation of class members so that 479 | # constructors and destructors are listed first. If set to NO (the default) 480 | # the constructors will appear in the respective orders defined by 481 | # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 482 | # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 483 | # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. 484 | 485 | SORT_MEMBERS_CTORS_1ST = NO 486 | 487 | # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 488 | # hierarchy of group names into alphabetical order. If set to NO (the default) 489 | # the group names will appear in their defined order. 490 | 491 | SORT_GROUP_NAMES = YES 492 | 493 | # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 494 | # sorted by fully-qualified names, including namespaces. If set to 495 | # NO (the default), the class list will be sorted only by class name, 496 | # not including the namespace part. 497 | # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 498 | # Note: This option applies only to the class list, not to the 499 | # alphabetical list. 500 | 501 | SORT_BY_SCOPE_NAME = YES 502 | 503 | # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to 504 | # do proper type resolution of all parameters of a function it will reject a 505 | # match between the prototype and the implementation of a member function even 506 | # if there is only one candidate or it is obvious which candidate to choose 507 | # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 508 | # will still accept a match between prototype and implementation in such cases. 509 | 510 | STRICT_PROTO_MATCHING = NO 511 | 512 | # The GENERATE_TODOLIST tag can be used to enable (YES) or 513 | # disable (NO) the todo list. This list is created by putting \todo 514 | # commands in the documentation. 515 | 516 | GENERATE_TODOLIST = YES 517 | 518 | # The GENERATE_TESTLIST tag can be used to enable (YES) or 519 | # disable (NO) the test list. This list is created by putting \test 520 | # commands in the documentation. 521 | 522 | GENERATE_TESTLIST = YES 523 | 524 | # The GENERATE_BUGLIST tag can be used to enable (YES) or 525 | # disable (NO) the bug list. This list is created by putting \bug 526 | # commands in the documentation. 527 | 528 | GENERATE_BUGLIST = YES 529 | 530 | # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 531 | # disable (NO) the deprecated list. This list is created by putting 532 | # \deprecated commands in the documentation. 533 | 534 | GENERATE_DEPRECATEDLIST= YES 535 | 536 | # The ENABLED_SECTIONS tag can be used to enable conditional 537 | # documentation sections, marked by \if sectionname ... \endif. 538 | 539 | ENABLED_SECTIONS = 540 | 541 | # The MAX_INITIALIZER_LINES tag determines the maximum number of lines 542 | # the initial value of a variable or macro consists of for it to appear in 543 | # the documentation. If the initializer consists of more lines than specified 544 | # here it will be hidden. Use a value of 0 to hide initializers completely. 545 | # The appearance of the initializer of individual variables and macros in the 546 | # documentation can be controlled using \showinitializer or \hideinitializer 547 | # command in the documentation regardless of this setting. 548 | 549 | MAX_INITIALIZER_LINES = 30 550 | 551 | # Set the SHOW_USED_FILES tag to NO to disable the list of files generated 552 | # at the bottom of the documentation of classes and structs. If set to YES the 553 | # list will mention the files that were used to generate the documentation. 554 | 555 | SHOW_USED_FILES = YES 556 | 557 | # If the sources in your project are distributed over multiple directories 558 | # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 559 | # in the documentation. The default is NO. 560 | 561 | SHOW_DIRECTORIES = YES 562 | 563 | # Set the SHOW_FILES tag to NO to disable the generation of the Files page. 564 | # This will remove the Files entry from the Quick Index and from the 565 | # Folder Tree View (if specified). The default is YES. 566 | 567 | SHOW_FILES = YES 568 | 569 | # Set the SHOW_NAMESPACES tag to NO to disable the generation of the 570 | # Namespaces page. This will remove the Namespaces entry from the Quick Index 571 | # and from the Folder Tree View (if specified). The default is YES. 572 | 573 | SHOW_NAMESPACES = YES 574 | 575 | # The FILE_VERSION_FILTER tag can be used to specify a program or script that 576 | # doxygen should invoke to get the current version for each file (typically from 577 | # the version control system). Doxygen will invoke the program by executing (via 578 | # popen()) the command , where is the value of 579 | # the FILE_VERSION_FILTER tag, and is the name of an input file 580 | # provided by doxygen. Whatever the program writes to standard output 581 | # is used as the file version. See the manual for examples. 582 | 583 | FILE_VERSION_FILTER = 584 | 585 | # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 586 | # by doxygen. The layout file controls the global structure of the generated 587 | # output files in an output format independent way. The create the layout file 588 | # that represents doxygen's defaults, run doxygen with the -l option. 589 | # You can optionally specify a file name after the option, if omitted 590 | # DoxygenLayout.xml will be used as the name of the layout file. 591 | 592 | LAYOUT_FILE = 593 | 594 | # The CITE_BIB_FILES tag can be used to specify one or more bib files 595 | # containing the references data. This must be a list of .bib files. The 596 | # .bib extension is automatically appended if omitted. Using this command 597 | # requires the bibtex tool to be installed. See also 598 | # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 599 | # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this 600 | # feature you need bibtex and perl available in the search path. 601 | 602 | CITE_BIB_FILES = 603 | 604 | #--------------------------------------------------------------------------- 605 | # configuration options related to warning and progress messages 606 | #--------------------------------------------------------------------------- 607 | 608 | # The QUIET tag can be used to turn on/off the messages that are generated 609 | # by doxygen. Possible values are YES and NO. If left blank NO is used. 610 | 611 | QUIET = YES 612 | 613 | # The WARNINGS tag can be used to turn on/off the warning messages that are 614 | # generated by doxygen. Possible values are YES and NO. If left blank 615 | # NO is used. 616 | 617 | WARNINGS = YES 618 | 619 | # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 620 | # for undocumented members. If EXTRACT_ALL is set to YES then this flag will 621 | # automatically be disabled. 622 | 623 | WARN_IF_UNDOCUMENTED = YES 624 | 625 | # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 626 | # potential errors in the documentation, such as not documenting some 627 | # parameters in a documented function, or documenting parameters that 628 | # don't exist or using markup commands wrongly. 629 | 630 | WARN_IF_DOC_ERROR = YES 631 | 632 | # The WARN_NO_PARAMDOC option can be enabled to get warnings for 633 | # functions that are documented, but have no documentation for their parameters 634 | # or return value. If set to NO (the default) doxygen will only warn about 635 | # wrong or incomplete parameter documentation, but not about the absence of 636 | # documentation. 637 | 638 | WARN_NO_PARAMDOC = YES 639 | 640 | # The WARN_FORMAT tag determines the format of the warning messages that 641 | # doxygen can produce. The string should contain the $file, $line, and $text 642 | # tags, which will be replaced by the file and line number from which the 643 | # warning originated and the warning text. Optionally the format may contain 644 | # $version, which will be replaced by the version of the file (if it could 645 | # be obtained via FILE_VERSION_FILTER) 646 | 647 | WARN_FORMAT = "$file:$line: $text" 648 | 649 | # The WARN_LOGFILE tag can be used to specify a file to which warning 650 | # and error messages should be written. If left blank the output is written 651 | # to stderr. 652 | 653 | WARN_LOGFILE = 654 | 655 | #--------------------------------------------------------------------------- 656 | # configuration options related to the input files 657 | #--------------------------------------------------------------------------- 658 | 659 | # The INPUT tag can be used to specify the files and/or directories that contain 660 | # documented source files. You may enter file names like "myfile.cpp" or 661 | # directories like "/usr/src/myproject". Separate the files or directories 662 | # with spaces. 663 | 664 | INPUT = LuaBridge.h \ 665 | RefCountedObject.h \ 666 | RefCountedPtr.h 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | # This tag can be used to specify the character encoding of the source files 681 | # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 682 | # also the default input encoding. Doxygen uses libiconv (or the iconv built 683 | # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 684 | # the list of possible encodings. 685 | 686 | INPUT_ENCODING = UTF-8 687 | 688 | # If the value of the INPUT tag contains directories, you can use the 689 | # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 690 | # and *.h) to filter out the source-files in the directories. If left 691 | # blank the following patterns are tested: 692 | # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 693 | # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 694 | # *.f90 *.f *.for *.vhd *.vhdl 695 | 696 | FILE_PATTERNS = *.c *.cpp *.h *.hpp 697 | 698 | # The RECURSIVE tag can be used to turn specify whether or not subdirectories 699 | # should be searched for input files as well. Possible values are YES and NO. 700 | # If left blank NO is used. 701 | 702 | RECURSIVE = YES 703 | 704 | # The EXCLUDE tag can be used to specify files and/or directories that should be 705 | # excluded from the INPUT source files. This way you can easily exclude a 706 | # subdirectory from a directory tree whose root is specified with the INPUT tag. 707 | # Note that relative paths are relative to the directory from which doxygen is 708 | # run. 709 | 710 | EXCLUDE = 711 | 712 | # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 713 | # directories that are symbolic links (a Unix file system feature) are excluded 714 | # from the input. 715 | 716 | EXCLUDE_SYMLINKS = NO 717 | 718 | # If the value of the INPUT tag contains directories, you can use the 719 | # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 720 | # certain files from those directories. Note that the wildcards are matched 721 | # against the file with absolute path, so to exclude all test directories 722 | # for example use the pattern \*/test/\* without the backslashes 723 | 724 | EXCLUDE_PATTERNS = 725 | 726 | # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 727 | # (namespaces, classes, functions, etc.) that should be excluded from the 728 | # output. The symbol name can be a fully qualified name, a word, or if the 729 | # wildcard * is used, a substring. Examples: ANamespace, AClass, 730 | # AClass::ANamespace, ANamespace::*Test 731 | 732 | EXCLUDE_SYMBOLS = 733 | 734 | # The EXAMPLE_PATH tag can be used to specify one or more files or 735 | # directories that contain example code fragments that are included (see 736 | # the \include command). 737 | 738 | EXAMPLE_PATH = ./ 739 | 740 | # If the value of the EXAMPLE_PATH tag contains directories, you can use the 741 | # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 742 | # and *.h) to filter out the source-files in the directories. If left 743 | # blank all files are included. 744 | 745 | EXAMPLE_PATTERNS = * 746 | 747 | # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 748 | # searched for input files to be used with the \include or \dontinclude 749 | # commands irrespective of the value of the RECURSIVE tag. 750 | # Possible values are YES and NO. If left blank NO is used. 751 | 752 | EXAMPLE_RECURSIVE = NO 753 | 754 | # The IMAGE_PATH tag can be used to specify one or more files or 755 | # directories that contain image that are included in the documentation (see 756 | # the \image command). 757 | 758 | IMAGE_PATH = 759 | 760 | # The INPUT_FILTER tag can be used to specify a program that doxygen should 761 | # invoke to filter for each input file. Doxygen will invoke the filter program 762 | # by executing (via popen()) the command , where 763 | # is the value of the INPUT_FILTER tag, and is the name of an 764 | # input file. Doxygen will then use the output that the filter program writes 765 | # to standard output. If FILTER_PATTERNS is specified, this tag will be 766 | # ignored. 767 | 768 | INPUT_FILTER = 769 | 770 | # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 771 | # basis. Doxygen will compare the file name with each pattern and apply the 772 | # filter if there is a match. The filters are a list of the form: 773 | # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 774 | # info on how filters are used. If FILTER_PATTERNS is empty or if 775 | # non of the patterns match the file name, INPUT_FILTER is applied. 776 | 777 | FILTER_PATTERNS = 778 | 779 | # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 780 | # INPUT_FILTER) will be used to filter the input files when producing source 781 | # files to browse (i.e. when SOURCE_BROWSER is set to YES). 782 | 783 | FILTER_SOURCE_FILES = NO 784 | 785 | # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 786 | # pattern. A pattern will override the setting for FILTER_PATTERN (if any) 787 | # and it is also possible to disable source filtering for a specific pattern 788 | # using *.ext= (so without naming a filter). This option only has effect when 789 | # FILTER_SOURCE_FILES is enabled. 790 | 791 | FILTER_SOURCE_PATTERNS = 792 | 793 | #--------------------------------------------------------------------------- 794 | # configuration options related to source browsing 795 | #--------------------------------------------------------------------------- 796 | 797 | # If the SOURCE_BROWSER tag is set to YES then a list of source files will 798 | # be generated. Documented entities will be cross-referenced with these sources. 799 | # Note: To get rid of all source code in the generated output, make sure also 800 | # VERBATIM_HEADERS is set to NO. 801 | 802 | SOURCE_BROWSER = YES 803 | 804 | # Setting the INLINE_SOURCES tag to YES will include the body 805 | # of functions and classes directly in the documentation. 806 | 807 | INLINE_SOURCES = NO 808 | 809 | # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 810 | # doxygen to hide any special comment blocks from generated source code 811 | # fragments. Normal C and C++ comments will always remain visible. 812 | 813 | STRIP_CODE_COMMENTS = NO 814 | 815 | # If the REFERENCED_BY_RELATION tag is set to YES 816 | # then for each documented function all documented 817 | # functions referencing it will be listed. 818 | 819 | REFERENCED_BY_RELATION = NO 820 | 821 | # If the REFERENCES_RELATION tag is set to YES 822 | # then for each documented function all documented entities 823 | # called/used by that function will be listed. 824 | 825 | REFERENCES_RELATION = NO 826 | 827 | # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 828 | # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 829 | # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 830 | # link to the source code. Otherwise they will link to the documentation. 831 | 832 | REFERENCES_LINK_SOURCE = YES 833 | 834 | # If the USE_HTAGS tag is set to YES then the references to source code 835 | # will point to the HTML generated by the htags(1) tool instead of doxygen 836 | # built-in source browser. The htags tool is part of GNU's global source 837 | # tagging system (see http://www.gnu.org/software/global/global.html). You 838 | # will need version 4.8.6 or higher. 839 | 840 | USE_HTAGS = NO 841 | 842 | # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 843 | # will generate a verbatim copy of the header file for each class for 844 | # which an include is specified. Set to NO to disable this. 845 | 846 | VERBATIM_HEADERS = NO 847 | 848 | #--------------------------------------------------------------------------- 849 | # configuration options related to the alphabetical class index 850 | #--------------------------------------------------------------------------- 851 | 852 | # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 853 | # of all compounds will be generated. Enable this if the project 854 | # contains a lot of classes, structs, unions or interfaces. 855 | 856 | ALPHABETICAL_INDEX = NO 857 | 858 | # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 859 | # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 860 | # in which this list will be split (can be a number in the range [1..20]) 861 | 862 | COLS_IN_ALPHA_INDEX = 5 863 | 864 | # In case all classes in a project start with a common prefix, all 865 | # classes will be put under the same header in the alphabetical index. 866 | # The IGNORE_PREFIX tag can be used to specify one or more prefixes that 867 | # should be ignored while generating the index headers. 868 | 869 | IGNORE_PREFIX = 870 | 871 | #--------------------------------------------------------------------------- 872 | # configuration options related to the HTML output 873 | #--------------------------------------------------------------------------- 874 | 875 | # If the GENERATE_HTML tag is set to YES (the default) Doxygen will 876 | # generate HTML output. 877 | 878 | GENERATE_HTML = YES 879 | 880 | # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 881 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 882 | # put in front of it. If left blank `html' will be used as the default path. 883 | 884 | HTML_OUTPUT = Documentation 885 | 886 | # The HTML_FILE_EXTENSION tag can be used to specify the file extension for 887 | # each generated HTML page (for example: .htm,.php,.asp). If it is left blank 888 | # doxygen will generate files with .html extension. 889 | 890 | HTML_FILE_EXTENSION = .html 891 | 892 | # The HTML_HEADER tag can be used to specify a personal HTML header for 893 | # each generated HTML page. If it is left blank doxygen will generate a 894 | # standard header. Note that when using a custom header you are responsible 895 | # for the proper inclusion of any scripts and style sheets that doxygen 896 | # needs, which is dependent on the configuration options used. 897 | # It is advised to generate a default header using "doxygen -w html 898 | # header.html footer.html stylesheet.css YourConfigFile" and then modify 899 | # that header. Note that the header is subject to change so you typically 900 | # have to redo this when upgrading to a newer version of doxygen or when 901 | # changing the value of configuration settings such as GENERATE_TREEVIEW! 902 | 903 | HTML_HEADER = 904 | 905 | # The HTML_FOOTER tag can be used to specify a personal HTML footer for 906 | # each generated HTML page. If it is left blank doxygen will generate a 907 | # standard footer. 908 | 909 | HTML_FOOTER = 910 | 911 | # The HTML_STYLESHEET tag can be used to specify a user-defined cascading 912 | # style sheet that is used by each HTML page. It can be used to 913 | # fine-tune the look of the HTML output. If the tag is left blank doxygen 914 | # will generate a default style sheet. Note that doxygen will try to copy 915 | # the style sheet file to the HTML output directory, so don't put your own 916 | # style sheet in the HTML output directory as well, or it will be erased! 917 | 918 | HTML_STYLESHEET = 919 | 920 | # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 921 | # other source files which should be copied to the HTML output directory. Note 922 | # that these files will be copied to the base HTML output directory. Use the 923 | # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these 924 | # files. In the HTML_STYLESHEET file, use the file name only. Also note that 925 | # the files will be copied as-is; there are no commands or markers available. 926 | 927 | HTML_EXTRA_FILES = 928 | 929 | # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 930 | # Doxygen will adjust the colors in the style sheet and background images 931 | # according to this color. Hue is specified as an angle on a colorwheel, 932 | # see http://en.wikipedia.org/wiki/Hue for more information. 933 | # For instance the value 0 represents red, 60 is yellow, 120 is green, 934 | # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 935 | # The allowed range is 0 to 359. 936 | 937 | HTML_COLORSTYLE_HUE = 240 938 | 939 | # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 940 | # the colors in the HTML output. For a value of 0 the output will use 941 | # grayscales only. A value of 255 will produce the most vivid colors. 942 | 943 | HTML_COLORSTYLE_SAT = 64 944 | 945 | # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 946 | # the luminance component of the colors in the HTML output. Values below 947 | # 100 gradually make the output lighter, whereas values above 100 make 948 | # the output darker. The value divided by 100 is the actual gamma applied, 949 | # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 950 | # and 100 does not change the gamma. 951 | 952 | HTML_COLORSTYLE_GAMMA = 80 953 | 954 | # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 955 | # page will contain the date and time when the page was generated. Setting 956 | # this to NO can help when comparing the output of multiple runs. 957 | 958 | HTML_TIMESTAMP = NO 959 | 960 | # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 961 | # files or namespaces will be aligned in HTML using tables. If set to 962 | # NO a bullet list will be used. 963 | 964 | HTML_ALIGN_MEMBERS = YES 965 | 966 | # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 967 | # documentation will contain sections that can be hidden and shown after the 968 | # page has loaded. For this to work a browser that supports 969 | # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 970 | # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). 971 | 972 | HTML_DYNAMIC_SECTIONS = NO 973 | 974 | # If the GENERATE_DOCSET tag is set to YES, additional index files 975 | # will be generated that can be used as input for Apple's Xcode 3 976 | # integrated development environment, introduced with OSX 10.5 (Leopard). 977 | # To create a documentation set, doxygen will generate a Makefile in the 978 | # HTML output directory. Running make will produce the docset in that 979 | # directory and running "make install" will install the docset in 980 | # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 981 | # it at startup. 982 | # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 983 | # for more information. 984 | 985 | GENERATE_DOCSET = NO 986 | 987 | # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 988 | # feed. A documentation feed provides an umbrella under which multiple 989 | # documentation sets from a single provider (such as a company or product suite) 990 | # can be grouped. 991 | 992 | DOCSET_FEEDNAME = "Doxygen generated docs" 993 | 994 | # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 995 | # should uniquely identify the documentation set bundle. This should be a 996 | # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 997 | # will append .docset to the name. 998 | 999 | DOCSET_BUNDLE_ID = org.doxygen.Project 1000 | 1001 | # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify 1002 | # the documentation publisher. This should be a reverse domain-name style 1003 | # string, e.g. com.mycompany.MyDocSet.documentation. 1004 | 1005 | DOCSET_PUBLISHER_ID = org.doxygen.Publisher 1006 | 1007 | # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. 1008 | 1009 | DOCSET_PUBLISHER_NAME = Publisher 1010 | 1011 | # If the GENERATE_HTMLHELP tag is set to YES, additional index files 1012 | # will be generated that can be used as input for tools like the 1013 | # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 1014 | # of the generated HTML documentation. 1015 | 1016 | GENERATE_HTMLHELP = NO 1017 | 1018 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 1019 | # be used to specify the file name of the resulting .chm file. You 1020 | # can add a path in front of the file if the result should not be 1021 | # written to the html output directory. 1022 | 1023 | CHM_FILE = 1024 | 1025 | # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 1026 | # be used to specify the location (absolute path including file name) of 1027 | # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 1028 | # the HTML help compiler on the generated index.hhp. 1029 | 1030 | HHC_LOCATION = 1031 | 1032 | # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 1033 | # controls if a separate .chi index file is generated (YES) or that 1034 | # it should be included in the master .chm file (NO). 1035 | 1036 | GENERATE_CHI = NO 1037 | 1038 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 1039 | # is used to encode HtmlHelp index (hhk), content (hhc) and project file 1040 | # content. 1041 | 1042 | CHM_INDEX_ENCODING = 1043 | 1044 | # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 1045 | # controls whether a binary table of contents is generated (YES) or a 1046 | # normal table of contents (NO) in the .chm file. 1047 | 1048 | BINARY_TOC = NO 1049 | 1050 | # The TOC_EXPAND flag can be set to YES to add extra items for group members 1051 | # to the contents of the HTML help documentation and to the tree view. 1052 | 1053 | TOC_EXPAND = NO 1054 | 1055 | # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 1056 | # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 1057 | # that can be used as input for Qt's qhelpgenerator to generate a 1058 | # Qt Compressed Help (.qch) of the generated HTML documentation. 1059 | 1060 | GENERATE_QHP = NO 1061 | 1062 | # If the QHG_LOCATION tag is specified, the QCH_FILE tag can 1063 | # be used to specify the file name of the resulting .qch file. 1064 | # The path specified is relative to the HTML output folder. 1065 | 1066 | QCH_FILE = 1067 | 1068 | # The QHP_NAMESPACE tag specifies the namespace to use when generating 1069 | # Qt Help Project output. For more information please see 1070 | # http://doc.trolltech.com/qthelpproject.html#namespace 1071 | 1072 | QHP_NAMESPACE = org.doxygen.Project 1073 | 1074 | # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 1075 | # Qt Help Project output. For more information please see 1076 | # http://doc.trolltech.com/qthelpproject.html#virtual-folders 1077 | 1078 | QHP_VIRTUAL_FOLDER = doc 1079 | 1080 | # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 1081 | # add. For more information please see 1082 | # http://doc.trolltech.com/qthelpproject.html#custom-filters 1083 | 1084 | QHP_CUST_FILTER_NAME = 1085 | 1086 | # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 1087 | # custom filter to add. For more information please see 1088 | # 1089 | # Qt Help Project / Custom Filters. 1090 | 1091 | QHP_CUST_FILTER_ATTRS = 1092 | 1093 | # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 1094 | # project's 1095 | # filter section matches. 1096 | # 1097 | # Qt Help Project / Filter Attributes. 1098 | 1099 | QHP_SECT_FILTER_ATTRS = 1100 | 1101 | # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 1102 | # be used to specify the location of Qt's qhelpgenerator. 1103 | # If non-empty doxygen will try to run qhelpgenerator on the generated 1104 | # .qhp file. 1105 | 1106 | QHG_LOCATION = 1107 | 1108 | # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files 1109 | # will be generated, which together with the HTML files, form an Eclipse help 1110 | # plugin. To install this plugin and make it available under the help contents 1111 | # menu in Eclipse, the contents of the directory containing the HTML and XML 1112 | # files needs to be copied into the plugins directory of eclipse. The name of 1113 | # the directory within the plugins directory should be the same as 1114 | # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 1115 | # the help appears. 1116 | 1117 | GENERATE_ECLIPSEHELP = NO 1118 | 1119 | # A unique identifier for the eclipse help plugin. When installing the plugin 1120 | # the directory name containing the HTML and XML files should also have 1121 | # this name. 1122 | 1123 | ECLIPSE_DOC_ID = org.doxygen.Project 1124 | 1125 | # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) 1126 | # at top of each HTML page. The value NO (the default) enables the index and 1127 | # the value YES disables it. Since the tabs have the same information as the 1128 | # navigation tree you can set this option to NO if you already set 1129 | # GENERATE_TREEVIEW to YES. 1130 | 1131 | DISABLE_INDEX = NO 1132 | 1133 | # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 1134 | # structure should be generated to display hierarchical information. 1135 | # If the tag value is set to YES, a side panel will be generated 1136 | # containing a tree-like index structure (just like the one that 1137 | # is generated for HTML Help). For this to work a browser that supports 1138 | # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 1139 | # Windows users are probably better off using the HTML help feature. 1140 | # Since the tree basically has the same information as the tab index you 1141 | # could consider to set DISABLE_INDEX to NO when enabling this option. 1142 | 1143 | GENERATE_TREEVIEW = NO 1144 | 1145 | # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 1146 | # (range [0,1..20]) that doxygen will group on one line in the generated HTML 1147 | # documentation. Note that a value of 0 will completely suppress the enum 1148 | # values from appearing in the overview section. 1149 | 1150 | ENUM_VALUES_PER_LINE = 4 1151 | 1152 | # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 1153 | # and Class Hierarchy pages using a tree view instead of an ordered list. 1154 | 1155 | USE_INLINE_TREES = NO 1156 | 1157 | # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 1158 | # used to set the initial width (in pixels) of the frame in which the tree 1159 | # is shown. 1160 | 1161 | TREEVIEW_WIDTH = 250 1162 | 1163 | # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 1164 | # links to external symbols imported via tag files in a separate window. 1165 | 1166 | EXT_LINKS_IN_WINDOW = NO 1167 | 1168 | # Use this tag to change the font size of Latex formulas included 1169 | # as images in the HTML documentation. The default is 10. Note that 1170 | # when you change the font size after a successful doxygen run you need 1171 | # to manually remove any form_*.png images from the HTML output directory 1172 | # to force them to be regenerated. 1173 | 1174 | FORMULA_FONTSIZE = 10 1175 | 1176 | # Use the FORMULA_TRANPARENT tag to determine whether or not the images 1177 | # generated for formulas are transparent PNGs. Transparent PNGs are 1178 | # not supported properly for IE 6.0, but are supported on all modern browsers. 1179 | # Note that when changing this option you need to delete any form_*.png files 1180 | # in the HTML output before the changes have effect. 1181 | 1182 | FORMULA_TRANSPARENT = YES 1183 | 1184 | # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 1185 | # (see http://www.mathjax.org) which uses client side Javascript for the 1186 | # rendering instead of using prerendered bitmaps. Use this if you do not 1187 | # have LaTeX installed or if you want to formulas look prettier in the HTML 1188 | # output. When enabled you may also need to install MathJax separately and 1189 | # configure the path to it using the MATHJAX_RELPATH option. 1190 | 1191 | USE_MATHJAX = NO 1192 | 1193 | # When MathJax is enabled you need to specify the location relative to the 1194 | # HTML output directory using the MATHJAX_RELPATH option. The destination 1195 | # directory should contain the MathJax.js script. For instance, if the mathjax 1196 | # directory is located at the same level as the HTML output directory, then 1197 | # MATHJAX_RELPATH should be ../mathjax. The default value points to 1198 | # the MathJax Content Delivery Network so you can quickly see the result without 1199 | # installing MathJax. However, it is strongly recommended to install a local 1200 | # copy of MathJax from http://www.mathjax.org before deployment. 1201 | 1202 | MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest 1203 | 1204 | # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension 1205 | # names that should be enabled during MathJax rendering. 1206 | 1207 | MATHJAX_EXTENSIONS = 1208 | 1209 | # When the SEARCHENGINE tag is enabled doxygen will generate a search box 1210 | # for the HTML output. The underlying search engine uses javascript 1211 | # and DHTML and should work on any modern browser. Note that when using 1212 | # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 1213 | # (GENERATE_DOCSET) there is already a search function so this one should 1214 | # typically be disabled. For large projects the javascript based search engine 1215 | # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. 1216 | 1217 | SEARCHENGINE = YES 1218 | 1219 | # When the SERVER_BASED_SEARCH tag is enabled the search engine will be 1220 | # implemented using a PHP enabled web server instead of at the web client 1221 | # using Javascript. Doxygen will generate the search PHP script and index 1222 | # file to put on the web server. The advantage of the server 1223 | # based approach is that it scales better to large projects and allows 1224 | # full text search. The disadvantages are that it is more difficult to setup 1225 | # and does not have live searching capabilities. 1226 | 1227 | SERVER_BASED_SEARCH = NO 1228 | 1229 | #--------------------------------------------------------------------------- 1230 | # configuration options related to the LaTeX output 1231 | #--------------------------------------------------------------------------- 1232 | 1233 | # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 1234 | # generate Latex output. 1235 | 1236 | GENERATE_LATEX = NO 1237 | 1238 | # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 1239 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1240 | # put in front of it. If left blank `latex' will be used as the default path. 1241 | 1242 | LATEX_OUTPUT = latex 1243 | 1244 | # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 1245 | # invoked. If left blank `latex' will be used as the default command name. 1246 | # Note that when enabling USE_PDFLATEX this option is only used for 1247 | # generating bitmaps for formulas in the HTML output, but not in the 1248 | # Makefile that is written to the output directory. 1249 | 1250 | LATEX_CMD_NAME = latex 1251 | 1252 | # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 1253 | # generate index for LaTeX. If left blank `makeindex' will be used as the 1254 | # default command name. 1255 | 1256 | MAKEINDEX_CMD_NAME = makeindex 1257 | 1258 | # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 1259 | # LaTeX documents. This may be useful for small projects and may help to 1260 | # save some trees in general. 1261 | 1262 | COMPACT_LATEX = NO 1263 | 1264 | # The PAPER_TYPE tag can be used to set the paper type that is used 1265 | # by the printer. Possible values are: a4, letter, legal and 1266 | # executive. If left blank a4wide will be used. 1267 | 1268 | PAPER_TYPE = a4 1269 | 1270 | # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 1271 | # packages that should be included in the LaTeX output. 1272 | 1273 | EXTRA_PACKAGES = 1274 | 1275 | # The LATEX_HEADER tag can be used to specify a personal LaTeX header for 1276 | # the generated latex document. The header should contain everything until 1277 | # the first chapter. If it is left blank doxygen will generate a 1278 | # standard header. Notice: only use this tag if you know what you are doing! 1279 | 1280 | LATEX_HEADER = 1281 | 1282 | # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for 1283 | # the generated latex document. The footer should contain everything after 1284 | # the last chapter. If it is left blank doxygen will generate a 1285 | # standard footer. Notice: only use this tag if you know what you are doing! 1286 | 1287 | LATEX_FOOTER = 1288 | 1289 | # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 1290 | # is prepared for conversion to pdf (using ps2pdf). The pdf file will 1291 | # contain links (just like the HTML output) instead of page references 1292 | # This makes the output suitable for online browsing using a pdf viewer. 1293 | 1294 | PDF_HYPERLINKS = YES 1295 | 1296 | # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 1297 | # plain latex in the generated Makefile. Set this option to YES to get a 1298 | # higher quality PDF documentation. 1299 | 1300 | USE_PDFLATEX = YES 1301 | 1302 | # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 1303 | # command to the generated LaTeX files. This will instruct LaTeX to keep 1304 | # running if errors occur, instead of asking the user for help. 1305 | # This option is also used when generating formulas in HTML. 1306 | 1307 | LATEX_BATCHMODE = NO 1308 | 1309 | # If LATEX_HIDE_INDICES is set to YES then doxygen will not 1310 | # include the index chapters (such as File Index, Compound Index, etc.) 1311 | # in the output. 1312 | 1313 | LATEX_HIDE_INDICES = NO 1314 | 1315 | # If LATEX_SOURCE_CODE is set to YES then doxygen will include 1316 | # source code with syntax highlighting in the LaTeX output. 1317 | # Note that which sources are shown also depends on other settings 1318 | # such as SOURCE_BROWSER. 1319 | 1320 | LATEX_SOURCE_CODE = NO 1321 | 1322 | # The LATEX_BIB_STYLE tag can be used to specify the style to use for the 1323 | # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See 1324 | # http://en.wikipedia.org/wiki/BibTeX for more info. 1325 | 1326 | LATEX_BIB_STYLE = plain 1327 | 1328 | #--------------------------------------------------------------------------- 1329 | # configuration options related to the RTF output 1330 | #--------------------------------------------------------------------------- 1331 | 1332 | # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 1333 | # The RTF output is optimized for Word 97 and may not look very pretty with 1334 | # other RTF readers or editors. 1335 | 1336 | GENERATE_RTF = NO 1337 | 1338 | # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 1339 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1340 | # put in front of it. If left blank `rtf' will be used as the default path. 1341 | 1342 | RTF_OUTPUT = rtf 1343 | 1344 | # If the COMPACT_RTF tag is set to YES Doxygen generates more compact 1345 | # RTF documents. This may be useful for small projects and may help to 1346 | # save some trees in general. 1347 | 1348 | COMPACT_RTF = NO 1349 | 1350 | # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 1351 | # will contain hyperlink fields. The RTF file will 1352 | # contain links (just like the HTML output) instead of page references. 1353 | # This makes the output suitable for online browsing using WORD or other 1354 | # programs which support those fields. 1355 | # Note: wordpad (write) and others do not support links. 1356 | 1357 | RTF_HYPERLINKS = NO 1358 | 1359 | # Load style sheet definitions from file. Syntax is similar to doxygen's 1360 | # config file, i.e. a series of assignments. You only have to provide 1361 | # replacements, missing definitions are set to their default value. 1362 | 1363 | RTF_STYLESHEET_FILE = 1364 | 1365 | # Set optional variables used in the generation of an rtf document. 1366 | # Syntax is similar to doxygen's config file. 1367 | 1368 | RTF_EXTENSIONS_FILE = 1369 | 1370 | #--------------------------------------------------------------------------- 1371 | # configuration options related to the man page output 1372 | #--------------------------------------------------------------------------- 1373 | 1374 | # If the GENERATE_MAN tag is set to YES (the default) Doxygen will 1375 | # generate man pages 1376 | 1377 | GENERATE_MAN = NO 1378 | 1379 | # The MAN_OUTPUT tag is used to specify where the man pages will be put. 1380 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1381 | # put in front of it. If left blank `man' will be used as the default path. 1382 | 1383 | MAN_OUTPUT = man 1384 | 1385 | # The MAN_EXTENSION tag determines the extension that is added to 1386 | # the generated man pages (default is the subroutine's section .3) 1387 | 1388 | MAN_EXTENSION = .3 1389 | 1390 | # If the MAN_LINKS tag is set to YES and Doxygen generates man output, 1391 | # then it will generate one additional man file for each entity 1392 | # documented in the real man page(s). These additional files 1393 | # only source the real man page, but without them the man command 1394 | # would be unable to find the correct page. The default is NO. 1395 | 1396 | MAN_LINKS = NO 1397 | 1398 | #--------------------------------------------------------------------------- 1399 | # configuration options related to the XML output 1400 | #--------------------------------------------------------------------------- 1401 | 1402 | # If the GENERATE_XML tag is set to YES Doxygen will 1403 | # generate an XML file that captures the structure of 1404 | # the code including all documentation. 1405 | 1406 | GENERATE_XML = NO 1407 | 1408 | # The XML_OUTPUT tag is used to specify where the XML pages will be put. 1409 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1410 | # put in front of it. If left blank `xml' will be used as the default path. 1411 | 1412 | XML_OUTPUT = xml 1413 | 1414 | # The XML_SCHEMA tag can be used to specify an XML schema, 1415 | # which can be used by a validating XML parser to check the 1416 | # syntax of the XML files. 1417 | 1418 | XML_SCHEMA = 1419 | 1420 | # The XML_DTD tag can be used to specify an XML DTD, 1421 | # which can be used by a validating XML parser to check the 1422 | # syntax of the XML files. 1423 | 1424 | XML_DTD = 1425 | 1426 | # If the XML_PROGRAMLISTING tag is set to YES Doxygen will 1427 | # dump the program listings (including syntax highlighting 1428 | # and cross-referencing information) to the XML output. Note that 1429 | # enabling this will significantly increase the size of the XML output. 1430 | 1431 | XML_PROGRAMLISTING = YES 1432 | 1433 | #--------------------------------------------------------------------------- 1434 | # configuration options for the AutoGen Definitions output 1435 | #--------------------------------------------------------------------------- 1436 | 1437 | # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 1438 | # generate an AutoGen Definitions (see autogen.sf.net) file 1439 | # that captures the structure of the code including all 1440 | # documentation. Note that this feature is still experimental 1441 | # and incomplete at the moment. 1442 | 1443 | GENERATE_AUTOGEN_DEF = NO 1444 | 1445 | #--------------------------------------------------------------------------- 1446 | # configuration options related to the Perl module output 1447 | #--------------------------------------------------------------------------- 1448 | 1449 | # If the GENERATE_PERLMOD tag is set to YES Doxygen will 1450 | # generate a Perl module file that captures the structure of 1451 | # the code including all documentation. Note that this 1452 | # feature is still experimental and incomplete at the 1453 | # moment. 1454 | 1455 | GENERATE_PERLMOD = NO 1456 | 1457 | # If the PERLMOD_LATEX tag is set to YES Doxygen will generate 1458 | # the necessary Makefile rules, Perl scripts and LaTeX code to be able 1459 | # to generate PDF and DVI output from the Perl module output. 1460 | 1461 | PERLMOD_LATEX = NO 1462 | 1463 | # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 1464 | # nicely formatted so it can be parsed by a human reader. This is useful 1465 | # if you want to understand what is going on. On the other hand, if this 1466 | # tag is set to NO the size of the Perl module output will be much smaller 1467 | # and Perl will parse it just the same. 1468 | 1469 | PERLMOD_PRETTY = YES 1470 | 1471 | # The names of the make variables in the generated doxyrules.make file 1472 | # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 1473 | # This is useful so different doxyrules.make files included by the same 1474 | # Makefile don't overwrite each other's variables. 1475 | 1476 | PERLMOD_MAKEVAR_PREFIX = 1477 | 1478 | #--------------------------------------------------------------------------- 1479 | # Configuration options related to the preprocessor 1480 | #--------------------------------------------------------------------------- 1481 | 1482 | # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 1483 | # evaluate all C-preprocessor directives found in the sources and include 1484 | # files. 1485 | 1486 | ENABLE_PREPROCESSING = YES 1487 | 1488 | # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 1489 | # names in the source code. If set to NO (the default) only conditional 1490 | # compilation will be performed. Macro expansion can be done in a controlled 1491 | # way by setting EXPAND_ONLY_PREDEF to YES. 1492 | 1493 | MACRO_EXPANSION = NO 1494 | 1495 | # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 1496 | # then the macro expansion is limited to the macros specified with the 1497 | # PREDEFINED and EXPAND_AS_DEFINED tags. 1498 | 1499 | EXPAND_ONLY_PREDEF = NO 1500 | 1501 | # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 1502 | # pointed to by INCLUDE_PATH will be searched when a #include is found. 1503 | 1504 | SEARCH_INCLUDES = NO 1505 | 1506 | # The INCLUDE_PATH tag can be used to specify one or more directories that 1507 | # contain include files that are not input files but should be processed by 1508 | # the preprocessor. 1509 | 1510 | INCLUDE_PATH = 1511 | 1512 | # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 1513 | # patterns (like *.h and *.hpp) to filter out the header-files in the 1514 | # directories. If left blank, the patterns specified with FILE_PATTERNS will 1515 | # be used. 1516 | 1517 | INCLUDE_FILE_PATTERNS = 1518 | 1519 | # The PREDEFINED tag can be used to specify one or more macro names that 1520 | # are defined before the preprocessor is started (similar to the -D option of 1521 | # gcc). The argument of the tag is a list of macros of the form: name 1522 | # or name=definition (no spaces). If the definition and the = are 1523 | # omitted =1 is assumed. To prevent a macro definition from being 1524 | # undefined via #undef or recursively expanded use the := operator 1525 | # instead of the = operator. 1526 | 1527 | PREDEFINED = \ 1528 | WIN32 = 1 1529 | 1530 | # DOXYGEN = 1 \ 1531 | 1532 | 1533 | # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 1534 | # this tag can be used to specify a list of macro names that should be expanded. 1535 | # The macro definition that is found in the sources will be used. 1536 | # Use the PREDEFINED tag if you want to use a different macro definition that 1537 | # overrules the definition found in the source code. 1538 | 1539 | EXPAND_AS_DEFINED = 1540 | 1541 | # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 1542 | # doxygen's preprocessor will remove all references to function-like macros 1543 | # that are alone on a line, have an all uppercase name, and do not end with a 1544 | # semicolon, because these will confuse the parser if not removed. 1545 | 1546 | SKIP_FUNCTION_MACROS = YES 1547 | 1548 | #--------------------------------------------------------------------------- 1549 | # Configuration::additions related to external references 1550 | #--------------------------------------------------------------------------- 1551 | 1552 | # The TAGFILES option can be used to specify one or more tagfiles. For each 1553 | # tag file the location of the external documentation should be added. The 1554 | # format of a tag file without this location is as follows: 1555 | # TAGFILES = file1 file2 ... 1556 | # Adding location for the tag files is done as follows: 1557 | # TAGFILES = file1=loc1 "file2 = loc2" ... 1558 | # where "loc1" and "loc2" can be relative or absolute paths 1559 | # or URLs. Note that each tag file must have a unique name (where the name does 1560 | # NOT include the path). If a tag file is not located in the directory in which 1561 | # doxygen is run, you must also specify the path to the tagfile here. 1562 | 1563 | TAGFILES = 1564 | 1565 | # When a file name is specified after GENERATE_TAGFILE, doxygen will create 1566 | # a tag file that is based on the input files it reads. 1567 | 1568 | GENERATE_TAGFILE = 1569 | 1570 | # If the ALLEXTERNALS tag is set to YES all external classes will be listed 1571 | # in the class index. If set to NO only the inherited external classes 1572 | # will be listed. 1573 | 1574 | ALLEXTERNALS = NO 1575 | 1576 | # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 1577 | # in the modules index. If set to NO, only the current project's groups will 1578 | # be listed. 1579 | 1580 | EXTERNAL_GROUPS = YES 1581 | 1582 | # The PERL_PATH should be the absolute path and name of the perl script 1583 | # interpreter (i.e. the result of `which perl'). 1584 | 1585 | PERL_PATH = /bin/perl 1586 | 1587 | #--------------------------------------------------------------------------- 1588 | # Configuration options related to the dot tool 1589 | #--------------------------------------------------------------------------- 1590 | 1591 | # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 1592 | # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 1593 | # or super classes. Setting the tag to NO turns the diagrams off. Note that 1594 | # this option also works with HAVE_DOT disabled, but it is recommended to 1595 | # install and use dot, since it yields more powerful graphs. 1596 | 1597 | CLASS_DIAGRAMS = NO 1598 | 1599 | # You can define message sequence charts within doxygen comments using the \msc 1600 | # command. Doxygen will then run the mscgen tool (see 1601 | # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 1602 | # documentation. The MSCGEN_PATH tag allows you to specify the directory where 1603 | # the mscgen tool resides. If left empty the tool is assumed to be found in the 1604 | # default search path. 1605 | 1606 | MSCGEN_PATH = 1607 | 1608 | # If set to YES, the inheritance and collaboration graphs will hide 1609 | # inheritance and usage relations if the target is undocumented 1610 | # or is not a class. 1611 | 1612 | HIDE_UNDOC_RELATIONS = YES 1613 | 1614 | # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 1615 | # available from the path. This tool is part of Graphviz, a graph visualization 1616 | # toolkit from AT&T and Lucent Bell Labs. The other options in this section 1617 | # have no effect if this option is set to NO (the default) 1618 | 1619 | HAVE_DOT = NO 1620 | 1621 | # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 1622 | # allowed to run in parallel. When set to 0 (the default) doxygen will 1623 | # base this on the number of processors available in the system. You can set it 1624 | # explicitly to a value larger than 0 to get control over the balance 1625 | # between CPU load and processing speed. 1626 | 1627 | DOT_NUM_THREADS = 0 1628 | 1629 | # By default doxygen will use the Helvetica font for all dot files that 1630 | # doxygen generates. When you want a differently looking font you can specify 1631 | # the font name using DOT_FONTNAME. You need to make sure dot is able to find 1632 | # the font, which can be done by putting it in a standard location or by setting 1633 | # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 1634 | # directory containing the font. 1635 | 1636 | DOT_FONTNAME = Helvetica 1637 | 1638 | # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 1639 | # The default size is 10pt. 1640 | 1641 | DOT_FONTSIZE = 10 1642 | 1643 | # By default doxygen will tell dot to use the Helvetica font. 1644 | # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to 1645 | # set the path where dot can find it. 1646 | 1647 | DOT_FONTPATH = 1648 | 1649 | # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 1650 | # will generate a graph for each documented class showing the direct and 1651 | # indirect inheritance relations. Setting this tag to YES will force the 1652 | # CLASS_DIAGRAMS tag to NO. 1653 | 1654 | CLASS_GRAPH = YES 1655 | 1656 | # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 1657 | # will generate a graph for each documented class showing the direct and 1658 | # indirect implementation dependencies (inheritance, containment, and 1659 | # class references variables) of the class with other documented classes. 1660 | 1661 | COLLABORATION_GRAPH = YES 1662 | 1663 | # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 1664 | # will generate a graph for groups, showing the direct groups dependencies 1665 | 1666 | GROUP_GRAPHS = YES 1667 | 1668 | # If the UML_LOOK tag is set to YES doxygen will generate inheritance and 1669 | # collaboration diagrams in a style similar to the OMG's Unified Modeling 1670 | # Language. 1671 | 1672 | UML_LOOK = NO 1673 | 1674 | # If the UML_LOOK tag is enabled, the fields and methods are shown inside 1675 | # the class node. If there are many fields or methods and many nodes the 1676 | # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS 1677 | # threshold limits the number of items for each type to make the size more 1678 | # managable. Set this to 0 for no limit. Note that the threshold may be 1679 | # exceeded by 50% before the limit is enforced. 1680 | 1681 | UML_LIMIT_NUM_FIELDS = 10 1682 | 1683 | # If set to YES, the inheritance and collaboration graphs will show the 1684 | # relations between templates and their instances. 1685 | 1686 | TEMPLATE_RELATIONS = NO 1687 | 1688 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 1689 | # tags are set to YES then doxygen will generate a graph for each documented 1690 | # file showing the direct and indirect include dependencies of the file with 1691 | # other documented files. 1692 | 1693 | INCLUDE_GRAPH = YES 1694 | 1695 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 1696 | # HAVE_DOT tags are set to YES then doxygen will generate a graph for each 1697 | # documented header file showing the documented files that directly or 1698 | # indirectly include this file. 1699 | 1700 | INCLUDED_BY_GRAPH = YES 1701 | 1702 | # If the CALL_GRAPH and HAVE_DOT options are set to YES then 1703 | # doxygen will generate a call dependency graph for every global function 1704 | # or class method. Note that enabling this option will significantly increase 1705 | # the time of a run. So in most cases it will be better to enable call graphs 1706 | # for selected functions only using the \callgraph command. 1707 | 1708 | CALL_GRAPH = NO 1709 | 1710 | # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 1711 | # doxygen will generate a caller dependency graph for every global function 1712 | # or class method. Note that enabling this option will significantly increase 1713 | # the time of a run. So in most cases it will be better to enable caller 1714 | # graphs for selected functions only using the \callergraph command. 1715 | 1716 | CALLER_GRAPH = NO 1717 | 1718 | # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 1719 | # will generate a graphical hierarchy of all classes instead of a textual one. 1720 | 1721 | GRAPHICAL_HIERARCHY = YES 1722 | 1723 | # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 1724 | # then doxygen will show the dependencies a directory has on other directories 1725 | # in a graphical way. The dependency relations are determined by the #include 1726 | # relations between the files in the directories. 1727 | 1728 | DIRECTORY_GRAPH = YES 1729 | 1730 | # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 1731 | # generated by dot. Possible values are svg, png, jpg, or gif. 1732 | # If left blank png will be used. If you choose svg you need to set 1733 | # HTML_FILE_EXTENSION to xhtml in order to make the SVG files 1734 | # visible in IE 9+ (other browsers do not have this requirement). 1735 | 1736 | DOT_IMAGE_FORMAT = png 1737 | 1738 | # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to 1739 | # enable generation of interactive SVG images that allow zooming and panning. 1740 | # Note that this requires a modern browser other than Internet Explorer. 1741 | # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you 1742 | # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files 1743 | # visible. Older versions of IE do not have SVG support. 1744 | 1745 | INTERACTIVE_SVG = NO 1746 | 1747 | # The tag DOT_PATH can be used to specify the path where the dot tool can be 1748 | # found. If left blank, it is assumed the dot tool can be found in the path. 1749 | 1750 | DOT_PATH = 1751 | 1752 | # The DOTFILE_DIRS tag can be used to specify one or more directories that 1753 | # contain dot files that are included in the documentation (see the 1754 | # \dotfile command). 1755 | 1756 | DOTFILE_DIRS = 1757 | 1758 | # The MSCFILE_DIRS tag can be used to specify one or more directories that 1759 | # contain msc files that are included in the documentation (see the 1760 | # \mscfile command). 1761 | 1762 | MSCFILE_DIRS = 1763 | 1764 | # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 1765 | # nodes that will be shown in the graph. If the number of nodes in a graph 1766 | # becomes larger than this value, doxygen will truncate the graph, which is 1767 | # visualized by representing a node as a red box. Note that doxygen if the 1768 | # number of direct children of the root node in a graph is already larger than 1769 | # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 1770 | # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. 1771 | 1772 | DOT_GRAPH_MAX_NODES = 50 1773 | 1774 | # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 1775 | # graphs generated by dot. A depth value of 3 means that only nodes reachable 1776 | # from the root by following a path via at most 3 edges will be shown. Nodes 1777 | # that lay further from the root node will be omitted. Note that setting this 1778 | # option to 1 or 2 may greatly reduce the computation time needed for large 1779 | # code bases. Also note that the size of a graph can be further restricted by 1780 | # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. 1781 | 1782 | MAX_DOT_GRAPH_DEPTH = 0 1783 | 1784 | # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 1785 | # background. This is disabled by default, because dot on Windows does not 1786 | # seem to support this out of the box. Warning: Depending on the platform used, 1787 | # enabling this option may lead to badly anti-aliased labels on the edges of 1788 | # a graph (i.e. they become hard to read). 1789 | 1790 | DOT_TRANSPARENT = NO 1791 | 1792 | # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 1793 | # files in one run (i.e. multiple -o and -T options on the command line). This 1794 | # makes dot run faster, but since only newer versions of dot (>1.8.10) 1795 | # support this, this feature is disabled by default. 1796 | 1797 | DOT_MULTI_TARGETS = NO 1798 | 1799 | # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 1800 | # generate a legend page explaining the meaning of the various boxes and 1801 | # arrows in the dot generated graphs. 1802 | 1803 | GENERATE_LEGEND = YES 1804 | 1805 | # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 1806 | # remove the intermediate dot files that are used to generate 1807 | # the various graphs. 1808 | 1809 | DOT_CLEANUP = YES 1810 | -------------------------------------------------------------------------------- /LuaBridge/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | # LuaBridge 1.0.2 6 | 7 | [LuaBridge][3] is a lightweight, dependency-free library for making C++ data, 8 | functions, and classes available to [Lua][5]: A powerful, fast, lightweight, 9 | embeddable scripting language. LuaBridge has been tested and works with Lua 10 | revisions starting from 5.1.5., although it should work in any version of Lua 11 | from 5.1.0 and later. 12 | 13 | LuaBridge offers the following features: 14 | 15 | - Nothing to compile, just include one header file! 16 | 17 | - Simple, light, and nothing else needed (like Boost). 18 | 19 | - Supports different object lifetime management models. 20 | 21 | - Convenient, type-safe access to the Lua stack. 22 | 23 | - Automatic function parameter type binding. 24 | 25 | - Does not require C++11. 26 | 27 | LuaBridge is distributed as a single header file. You simply add 28 | `#include "LuaBridge.h"` where you want to bind your functions, classes, and 29 | variables. There are no additional source files, no compilation settings, and 30 | no Makefiles or IDE-specific project files. LuaBridge is easy to integrate. 31 | A few additional header files provide optional features. Like the main header 32 | file, these are simply used via `#include`. No additional source files need 33 | to be compiled. 34 | 35 | C++ concepts like variables and classes are made available to Lua through a 36 | process called _registration_. Because Lua is weakly typed, the resulting 37 | structure is not rigid. The API is based on C++ template metaprogramming. It 38 | contains template code to automatically generate at compile-time the various 39 | Lua C API calls necessary to export your program's classes and functions to 40 | the Lua environment. 41 | 42 | ### Version 43 | 44 | LuaBridge repository branches are as follows: 45 | 46 | - **[master][7]**: Tagged, stable release versions. 47 | 48 | - **[release][8]**: Tagged candidates for imminent release. 49 | 50 | - **[develop][9]**: Work in progress. 51 | 52 | ## LuaBridge Demo and Tests 53 | 54 | LuaBridge provides both a command line program and a stand-alone graphical 55 | program for compiling and running the test suite. The graphical program brings 56 | up an interactive window where you can enter execute Lua statements in a 57 | persistent environment. This application is cross platform and works on 58 | Windows, Mac OS, iOS, Android, and GNU/Linux systems with X11. The stand-alone 59 | program should work anywhere. Both of these applications include LuaBridge, 60 | Lua version 5.2, and the code necessary to produce a cross platform graphic 61 | application. They are all together in a separate repository, with no 62 | additional dependencies, available on Github at [LuaBridge Demo and Tests][4]. 63 | This is what the GUI application looks like, along with the C++ code snippet 64 | for registering the two classes: 65 | 66 | 67 | 68 |
69 | 70 | ## Registration 71 | 72 | There are five types of objects that LuaBridge can register: 73 | 74 | - **Data**: Global variables, data members, and static data members. 75 | 76 | - **Functions**: Global functions, member functions, and static member 77 | functions. 78 | 79 | - **CFunctions**: A regular function, member function, or static member 80 | function that uses the `lua_CFunction` calling convention. 81 | 82 | - **Namespaces**: A namespace is simply a table containing registrations of 83 | functions, data, properties, and other namespaces. 84 | 85 | - **Properties**: Global properties, property members, and static property 86 | members. These appear like data to Lua, but are implemented 87 | using get and set functions on the C++ side. 88 | 89 | Both data and properties can be marked as _read-only_ at the time of 90 | registration. This is different from `const`; the values of these objects can 91 | be modified on the C++ side, but Lua scripts cannot change them. Code samples 92 | that follow are in C++ or Lua, depending on context. For brevity of exposition 93 | code samples in C++ assume the traditional variable `lua_State* L` is defined, 94 | and that a `using namespace luabridge` using-directive is in effect. 95 | 96 | ### Namespaces 97 | 98 | All LuaBridge registrations take place in a _namespace_. When we refer to a 99 | _namespace_ we are always talking about a namespace in the Lua sense, which is 100 | implemented using tables. The namespace need not correspond to a C++ namespace; 101 | in fact no C++ namespaces need to exist at all unless you want them to. 102 | LuaBridge namespaces are visible only to Lua scripts; they are used as a 103 | logical grouping tool. To obtain access to the global namespace we write: 104 | 105 | getGlobalNamespace (L); 106 | 107 | This returns an object on which further registrations can be performed. The 108 | subsequent registrations will go into the global namespace, a practice which 109 | is not recommended. Instead, we can add our own namespace by writing: 110 | 111 | getGlobalNamespace (L) 112 | .beginNamespace ("test"); 113 | 114 | This creates a table in `_G` called "test". Since we have not performed any 115 | registrations, this table will be empty except for some bookkeeping key/value 116 | pairs. LuaBridge reserves all identifiers that start with a double underscore. 117 | So `__test` would be an invalid name (although LuaBridge will silently accept 118 | it). Functions like `beginNamespace` return the corresponding object on which 119 | we can make more registrations. Given: 120 | 121 | getGlobalNamespace (L) 122 | .beginNamespace ("test") 123 | .beginNamespace ("detail") 124 | .endNamespace () 125 | .beginNamespace ("utility") 126 | .endNamespace () 127 | .endNamespace (); 128 | 129 | The results are accessible to Lua as `test`, `test.detail`, and 130 | `test.utility`. Here we introduce the `endNamespace` function; it returns an 131 | object representing the original enclosing namespace. All LuaBridge functions 132 | which create registrations return an object upon which subsequent 133 | registrations can be made, allowing for an unlimited number of registrations 134 | to be chained together using the dot operator `.`. Adding two objects with the 135 | same name, in the same namespace, results in undefined behavior (although 136 | LuaBridge will silently accept it). 137 | 138 | A namespace can be re-opened later to add more functions. This lets you split 139 | up the registration between different source files. These are equivalent: 140 | 141 | getGlobalNamespace (L) 142 | .beginNamespace ("test") 143 | .addFunction ("foo", foo) 144 | .endNamespace (); 145 | 146 | getGlobalNamespace (L) 147 | .beginNamespace ("test") 148 | .addFunction ("bar", bar) 149 | .endNamespace (); 150 | 151 | and 152 | 153 | getGlobalNamespace (L) 154 | .beginNamespace ("test") 155 | .addFunction ("foo", foo) 156 | .addFunction ("bar", bar) 157 | .endNamespace (); 158 | 159 | 160 | ### Data, Properties, Functions, and CFunctions. 161 | 162 | These are registered into a namespace using `addVariable`, `addProperty`, 163 | `addFunction`, and `addCFunction`. When registered functions are called by 164 | scripts, LuaBridge automatically takes care of the conversion of arguments 165 | into the appropriate data type when doing so is possible. This automated 166 | system works for the function's return value, and up to 8 parameters although 167 | more can be added by extending the templates. Pointers, references, and 168 | objects of class type as parameters are treated specially, and explained 169 | later. If we have: 170 | 171 | int globalVar; 172 | static float staticVar; 173 | 174 | std::string stringProperty; 175 | std::string getString () { return stringProperty; } 176 | void setString (std::string s) { return s; } 177 | 178 | int foo () { return 42; } 179 | void bar (char const*) { } 180 | int cFunc (lua_State* L) { return 0; } 181 | 182 | These are registered with: 183 | 184 | getGlobalNamespace (L) 185 | .beginNamespace ("test") 186 | .addVariable ("var1", &globalVar) 187 | .addVariable ("var2", &staticVar, false) // read-only 188 | .addProperty ("prop1", getString, setString) 189 | .addProperty ("prop2", getString) // read only 190 | .addFunction ("foo", foo) 191 | .addFunction ("bar", bar) 192 | .addCFunction ("cfunc", cFunc) 193 | .endNamespace (); 194 | 195 | Variables can be marked _read-only_ by passing `false` in the second optional 196 | parameter. If the parameter is omitted, `true` is used making the variable 197 | read/write. Properties are marked read-only by omitting the set function. 198 | After the registrations above, the following Lua identifiers are valid: 199 | 200 | test -- a namespace 201 | test.var1 -- a lua_Number variable 202 | test.var2 -- a read-only lua_Number variable 203 | test.prop1 -- a lua_String property 204 | test.prop2 -- a read-only lua_String property 205 | test.foo -- a function returning a lua_Number 206 | test.bar -- a function taking a lua_String as a parameter 207 | test.cfunc -- a function with a variable argument list and multi-return 208 | 209 | Note that `test.prop1` and `test.prop2` both refer to the same value. However, 210 | since `test.prop2` is read-only, assignment does not work. These Lua 211 | statements have the stated effects: 212 | 213 | test.var1 = 5 -- okay 214 | test.var2 = 6 -- error: var2 is not writable 215 | test.prop1 = "Hello" -- okay 216 | test.prop1 = 68 -- okay, Lua converts the number to a string. 217 | test.prop2 = "bar" -- error: prop2 is not writable 218 | 219 | test.foo () -- calls foo and discards the return value 220 | test.var1 = foo () -- calls foo and stores the result in var1 221 | test.bar ("Employee") -- calls bar with a string 222 | test.bar (test) -- error: bar expects a string not a table 223 | 224 | LuaBridge does not support overloaded functions nor is it likely to in the 225 | future. Since Lua is dynamically typed, any system that tries to resolve a set 226 | of parameters passed from a script will face considerable ambiguity when 227 | trying to choose an appropriately matching C++ function signature. 228 | 229 | ### Classes 230 | 231 | A class registration is opened using either `beginClass` or `deriveClass` and 232 | ended using `endClass`. Once registered, a class can later be re-opened for 233 | more registrations using `beginClass`. However, `deriveClass` should only be 234 | used once. To add more registrations to an already registered derived class, 235 | use `beginClass`. These declarations: 236 | 237 | struct A { 238 | static int staticData; 239 | static float staticProperty; 240 | 241 | static float getStaticProperty () { return staticProperty; } 242 | static void setStaticProperty (float f) { staticProperty = f; } 243 | static void staticFunc () { } 244 | 245 | static int staticCFunc () { return 0; } 246 | 247 | std::string dataMember; 248 | 249 | char dataProperty; 250 | char getProperty () const { return dataProperty; } 251 | void setProperty (char v) { dataProperty = v; } 252 | 253 | void func1 () { } 254 | virtual void virtualFunc () { } 255 | 256 | int cfunc (lua_State* L) { return 0; } 257 | }; 258 | 259 | struct B : public A { 260 | double dataMember2; 261 | 262 | void func1 () { } 263 | void func2 () { } 264 | void virtualFunc () { } 265 | }; 266 | 267 | int A::staticData; 268 | float A::staticProperty; 269 | 270 | Are registered using: 271 | 272 | getGlobalNamespace (L) 273 | .beginNamespace ("test") 274 | .beginClass ("A") 275 | .addStaticData ("staticData", &A::staticData) 276 | .addStaticProperty ("staticProperty", &A::staticProperty) 277 | .addStaticFunction ("staticFunc", &A::staticFunc) 278 | .addStaticCFunction ("staticCFunc", &A::staticCFunc) 279 | .addData ("data", &A::dataMember) 280 | .addProperty ("prop", &A::getProperty, &A::setProperty) 281 | .addFunction ("func1", &A::func1) 282 | .addFunction ("virtualFunc", &A::virtualFunc) 283 | .addCFunction ("cfunc", &A::cfunc) 284 | .endClass () 285 | .deriveClass ("B") 286 | .addData ("data", &B::dataMember2) 287 | .addFunction ("func1", &B::func1) 288 | .addFunction ("func2", &B::func2) 289 | .endClass () 290 | .endClass (); 291 | 292 | Method registration works just like function registration. Virtual methods 293 | work normally; no special syntax is needed. const methods are detected and 294 | const-correctness is enforced, so if a function returns a const object (or 295 | a container holding to a const object) to Lua, that reference to the object 296 | will be considered const and only const methods can be called on it. 297 | Destructors are registered automatically for each class. 298 | 299 | As with regular variables and properties, class data and properties can be 300 | marked read-only by passing false in the second parameter, or omitting the set 301 | set function respectively. The `deriveClass` takes two template arguments: the 302 | class to be registered, and its base class. Inherited methods do not have to 303 | be re-declared and will function normally in Lua. If a class has a base class 304 | that is **not** registered with Lua, there is no need to declare it as a 305 | subclass. 306 | 307 | ### Property Member Proxies 308 | 309 | Sometimes when registering a class which comes from a third party library, the 310 | data is not exposed in a way that can be expressed as a pointer to member, 311 | there are no get or set functions, or the get and set functons do not have the 312 | right function signature. Since the class declaration is closed for changes, 313 | LuaBridge provides allows a _property member proxy_. This is a pair of get 314 | and set flat functions which take as their first parameter a pointer to 315 | the object. This is easily understood with the following example: 316 | 317 | // Third party declaration, can't be changed 318 | struct Vec 319 | { 320 | float coord [3]; 321 | }; 322 | 323 | Taking the address of an array element, e.g. `&Vec::coord [0]` results in an 324 | error instead of a pointer-to-member. The class is closed for modifications, 325 | but we want to export Vec objects to Lua using the familiar object notation. 326 | To do this, first we add a "helper" class: 327 | 328 | struct VecHelper 329 | { 330 | template 331 | static float get (Vec const* vec) 332 | { 333 | return vec->coord [index]; 334 | } 335 | 336 | template 337 | static void set (Vec* vec, float value) 338 | { 339 | vec->coord [index] = value; 340 | } 341 | }; 342 | 343 | This helper class is only used to provide property member proxies. `Vec` 344 | continues to be used in the C++ code as it was before. Now we can register 345 | the `Vec` class with property member proxies for `x`, `y`, and `z`: 346 | 347 | getGlobalNamespace (L) 348 | .beginNamespace ("test") 349 | .beginClass ("Vec") 350 | .addProperty ("x", &VecHelper::get <0>, &VecHelper::set <0>) 351 | .addProperty ("y", &VecHelper::get <1>, &VecHelper::set <1>) 352 | .addProperty ("z", &VecHelper::get <2>, &VecHelper::set <2>) 353 | .endClass () 354 | .endNamespace (); 355 | 356 | ### Constructors 357 | 358 | A single constructor may be added for a class using `addConstructor`. 359 | LuaBridge cannot automatically determine the number and types of constructor 360 | parameters like it can for functions and methods, so you must provide them. 361 | This is done by specifying the signature of the desired constructor function 362 | as the first template parameter to `addConstructor`. The parameter types will 363 | be extracted from this (the return type is ignored). For example, these 364 | statements register constructors for the given classes: 365 | 366 | struct A { 367 | A (); 368 | }; 369 | 370 | struct B { 371 | explicit B (char const* s, int nChars); 372 | }; 373 | 374 | getGlobalNamespace (L) 375 | .beginNamespace ("test") 376 | .beginClass ("A") 377 | .addConstructor () 378 | .endClass () 379 | .beginClass ("B") 380 | .addConstructor () 381 | .endClass (); 382 | .endNamespace () 383 | 384 | Constructors added in this fashion are called from Lua using the fully 385 | qualified name of the class. This Lua code will create instances of `A` and 386 | `B` 387 | 388 | a = test.A () -- Create a new A. 389 | b = test.B ("hello", 5) -- Create a new B. 390 | b = test.B () -- Error: expected string in argument 1 391 | 392 | ## The Lua Stack 393 | 394 | In the Lua C API, all operations on the `lua_State` are performed through the 395 | Lua stack. In order to pass parameters back and forth between C++ and Lua, 396 | LuaBridge uses specializations of this template class concept: 397 | 398 | template 399 | struct Stack 400 | { 401 | static void push (lua_State* L, T t); 402 | static T get (lua_State* L, int index); 403 | }; 404 | 405 | The Stack template class specializations are used automatically for variables, 406 | properties, data members, property members, function arguments and return 407 | values. These basic types are supported: 408 | 409 | - `bool` 410 | - `char`, converted to a string of length one. 411 | - `char const*` and `std::string` strings. 412 | - Integers, `float`, and `double`, converted to `Lua_number`. 413 | 414 | User-defined types which are convertible to one of the basic types are 415 | possible, simply provide a `Stack <>` specialization in the `luabridge` 416 | namespace for your user-defined type, modeled after the existing types. 417 | For example, here is a specialization for a [juce::String][6]: 418 | 419 | template <> 420 | struct Stack 421 | { 422 | static void push (lua_State* L, juce::String s) 423 | { 424 | lua_pushstring (L, s.toUTF8 ()); 425 | } 426 | 427 | static juce::String get (lua_State* L, int index) 428 | { 429 | return juce::String (luaL_checkstring (L, index)); 430 | } 431 | }; 432 | 433 | ### The `lua_State*` 434 | 435 | Sometimes it is convenient from within a bound function or member function 436 | to gain access to the `lua_State*` normally available to a `lua_CFunction`. 437 | With LuaBridge, all you need to do is add a `lua_State*` as the last 438 | parameter of your bound function: 439 | 440 | void useState (lua_State* L); 441 | 442 | getGlobalNamespace (L).addFunction ("useState", &useState); 443 | 444 | You can still include regular arguments while receiving the state: 445 | 446 | void useStateAndArgs (int i, std::string s, lua_State* L); 447 | 448 | getGlobalNamespace (L).addFunction ("useStateAndArgs", &useStateAndArgs); 449 | 450 | When a script calls `useStateAndArgs`, it passes only the integer and string 451 | parameters. LuaBridge takes care of inserting the `lua_State*` into the 452 | argument list for the corresponding C++ function. This will work correctly 453 | even for the state created by coroutines. Undefined behavior results if 454 | the `lua_State*` is not the last parameter. 455 | 456 | ### Class Object Types 457 | 458 | An object of a registered class `T` may be passed to Lua as: 459 | 460 | - `T*` or `T&`: Passed by reference, with _C++ lifetime_. 461 | - `T const*` or `T const&`: Passed by const reference, with _C++ lifetime_. 462 | - `T` or `T const`: Passed by value (a copy), with _Lua lifetime_. 463 | 464 | ### C++ Lifetime 465 | 466 | The creation and deletion of objects with _C++ lifetime_ is controlled by 467 | the C++ code. Lua does nothing when it garbage collects a reference to such an 468 | object. Specifically, the object's destructor is not called (since C++ owns 469 | it). Care must be taken to ensure that objects with C++ lifetime are not 470 | deleted while still being referenced by a `lua_State*`, or else undefined 471 | behavior results. In the previous examples, an instance of `A` can be passed 472 | to Lua with C++ lifetime, like this: 473 | 474 | A a; 475 | 476 | push (L, &a); // pointer to 'a', C++ lifetime 477 | lua_setglobal (L, "a"); 478 | 479 | push (L, (A const*)&a); // pointer to 'a const', C++ lifetime 480 | lua_setglobal (L, "ac"); 481 | 482 | push (L, &a); // equivalent to push (L, (A const*)&a) 483 | lua_setglobal (L, "ac2"); 484 | 485 | push (L, new A); // compiles, but will leak memory 486 | lua_setglobal (L, "ap"); 487 | 488 | ### Lua Lifetime 489 | 490 | When an object of a registered class is passed by value to Lua, it will have 491 | _Lua lifetime_. A copy of the passed object is constructed inside the 492 | userdata. When Lua has no more references to the object, it becomes eligible 493 | for garbage collection. When the userdata is collected, the destructor for 494 | the class will be called on the object. Care must be taken to ensure that 495 | objects with Lua lifetime are not accessed by C++ after they are garbage 496 | collected, or else undefined behavior results. An instance of `B` can be 497 | passed to Lua with Lua lifetime this way: 498 | 499 | B b; 500 | 501 | push (L, b); // Copy of b passed, Lua lifetime. 502 | lua_setglobal (L, "b"); 503 | 504 | Given the previous code segments, these Lua statements are applicable: 505 | 506 | print (test.A.staticData) -- Prints the static data member. 507 | print (test.A.staticProperty) -- Prints the static property member. 508 | test.A.staticFunc () -- Calls the static method. 509 | 510 | print (a.data) -- Prints the data member. 511 | print (a.prop) -- Prints the property member. 512 | a:func1 () -- Calls A::func1 (). 513 | test.A.func1 (a) -- Equivalent to a:func1 (). 514 | test.A.func1 ("hello") -- Error: "hello" is not a class A. 515 | a:virtualFunc () -- Calls A::virtualFunc (). 516 | 517 | print (b.data) -- Prints B::dataMember. 518 | print (b.prop) -- Prints inherited property member. 519 | b:func1 () -- Calls B::func1 (). 520 | b:func2 () -- Calls B::func2 (). 521 | test.B.func2 (a) -- Error: a is not a class B. 522 | test.A.func1 (b) -- Calls A::func1 (). 523 | b:virtualFunc () -- Calls B::virtualFunc (). 524 | test.B.virtualFunc (b) -- Calls B::virtualFunc (). 525 | test.A.virtualFunc (b) -- Calls B::virtualFunc (). 526 | test.B.virtualFunc (a) -- Error: a is not a class B. 527 | 528 | a = nil; collectgarbage () -- 'a' still exists in C++. 529 | b = nil; collectgarbage () -- Lua calls ~B() on the copy of b. 530 | 531 | When Lua script creates an object of class type using a registered 532 | constructor, the resulting value will have Lua lifetime. After Lua no longer 533 | references the object, it becomes eligible for garbage collection. You can 534 | still pass these to C++, either by reference or by value. If passed by 535 | reference, the usual warnings apply about accessing the reference later, 536 | after it has been garbage collected. 537 | 538 | ### Pointers, References, and Pass by Value 539 | 540 | When C++ objects are passed from Lua back to C++ as arguments to functions, 541 | or set as data members, LuaBridge does its best to automate the conversion. 542 | Using the previous definitions, the following functions may be registered 543 | to Lua: 544 | 545 | void func0 (A a); 546 | void func1 (A* a); 547 | void func2 (A const* a); 548 | void func3 (A& a); 549 | void func4 (A const& a); 550 | 551 | Executing this Lua code will have the prescribed effect: 552 | 553 | func0 (a) -- Passes a copy of a, using A's copy constructor. 554 | func1 (a) -- Passes a pointer to a. 555 | func2 (a) -- Passes a pointer to a const a. 556 | func3 (a) -- Passes a reference to a. 557 | func4 (a) -- Passes a reference to a const a. 558 | 559 | In the example above, all functions can read the data members and property 560 | members of `a`, or call const member functions of `a`. Only `func0`, `func1` 561 | and `func3` can modify the data members and data properties, or call 562 | non-const member functions of `a`. 563 | 564 | The usual C++ inheritance and pointer assignment rules apply. Given: 565 | 566 | void func5 (B b); 567 | void func6 (B* b); 568 | 569 | These Lua statements hold: 570 | 571 | func5 (b) - Passes a copy of b, using B's copy constructor. 572 | func6 (b) - Passes a pointer to b. 573 | func6 (a) - Error: Pointer to B expected. 574 | func1 (b) - Okay, b is a subclass of a. 575 | 576 | When a pointer or pointer to const is passed to Lua and the pointer is null 577 | (zero), LuaBridge will pass Lua a `nil` instead. When Lua passes a `nil` 578 | to C++ where a pointer is expected, a null (zero) is passed instead. 579 | Attempting to pass a null pointer to a C++ function expecting a reference 580 | results in `lua_error` being called. 581 | 582 | ## Shared Lifetime 583 | 584 | LuaBridge supports a "shared lifetime" model: dynamically allocated and 585 | reference counted objects whose ownership is shared by both Lua and C++. 586 | The object remains in existence until there are no remaining C++ or Lua 587 | references, and Lua performs its usual garbage collection cycle. A container 588 | is recognized by a specialization of the `ContainerTraits` template class. 589 | LuaBridge will automatically recognize when a data type is a container when 590 | the correspoding specialization is present. Two styles of containers come with 591 | LuaBridge, including the necessary specializations: 592 | 593 | ### The `RefCountedObjectPtr` Container 594 | 595 | This is an intrusive style container. Your existing class declaration must be 596 | changed to be also derived from `RefCountedObject`. Given `class T`, derived 597 | from `RefCountedObject`, the container `RefCountedObjectPtr ` may be used. 598 | In order for reference counts to be maintained properly, all C++ code must 599 | store a container instead of the pointer. This is similar in style to 600 | `std::shared_ptr` although there are slight differences. For example: 601 | 602 | // A is reference counted. 603 | struct A : public RefCountedObject 604 | { 605 | void foo () { } 606 | }; 607 | 608 | struct B 609 | { 610 | RefCountedObjectPtr a; // holds a reference to A 611 | }; 612 | 613 | void bar (RefCountedObjectPtr a) 614 | { 615 | a->foo (); 616 | } 617 | 618 | ### The `RefCountedPtr` Container 619 | 620 | This is a non intrusive reference counted pointer. The reference counts are 621 | kept in a global hash table, which does incur a small performance penalty. 622 | However, it does not require changing any already existing class declarations. 623 | This is especially useful when the classes to be registered come from a third 624 | party library and cannot be modified. To use it, simply wrap all pointers 625 | to class objects with the container instead: 626 | 627 | struct A 628 | { 629 | void foo () { } 630 | }; 631 | 632 | struct B 633 | { 634 | RefCountedPtr a; 635 | }; 636 | 637 | RefCountedPtr createA () 638 | { 639 | return new A; 640 | } 641 | 642 | void bar (RefCountedPtr a) 643 | { 644 | a->foo (); 645 | } 646 | 647 | void callFoo () 648 | { 649 | bar (createA ()); 650 | 651 | // The created A will be destroyed 652 | // when we leave this scope 653 | } 654 | 655 | ### Custom Containers 656 | 657 | If you have your own container, you must provide a specialization of 658 | `ContainerTraits` in the `luabridge` namespace for your type before it will be 659 | recognized by LuaBridge (or else the code will not compile): 660 | 661 | template 662 | struct ContainerTraits > 663 | { 664 | typedef typename T Type; 665 | 666 | static T* get (CustomContainer const& c) 667 | { 668 | return c.getPointerToObject (); 669 | } 670 | }; 671 | 672 | Standard containers like `std::shared_ptr` or `boost::shared_ptr` **will not 673 | work**. This is because of type erasure; when the object goes from C++ to 674 | Lua and back to C++, there is no way to associate the object with the 675 | original container. The new container is constructed from a pointer to the 676 | object instead of an existing container. The result is undefined behavior 677 | since there are now two sets of reference counts. 678 | 679 | ### Container Construction 680 | 681 | When a constructor is registered for a class, there is an additional 682 | optional second template parameter describing the type of container to use. 683 | If this parameter is specified, calls to the constructor will create the 684 | object dynamically, via operator new, and place it a container of that 685 | type. The container must have been previously specialized in 686 | `ContainerTraits`, or else a compile error will result. This code will 687 | register two objects, each using a constructor that creates an object 688 | with Lua lifetime using the specified container: 689 | 690 | class C : public RefCountedObject 691 | { 692 | C () { } 693 | }; 694 | 695 | class D 696 | { 697 | D () { } 698 | }; 699 | 700 | getGlobalNamespace (L) 701 | .beginNamespace ("test") 702 | .beginClass ("C") 703 | .addConstructor > () 704 | .endClass () 705 | .beginClass ("D") 706 | .addConstructor > () 707 | .endClass (); 708 | .endNamespace () 709 | 710 | ### Mixing Lifetimes 711 | 712 | Mixing object lifetime models is entirely possible, subject to the usual 713 | caveats of holding references to objects which could get deleted. For 714 | example, C++ can be called from Lua with a pointer to an object of class 715 | type; the function can modify the object or call non-const data members. 716 | These modifications are visible to Lua (since they both refer to the same 717 | object). An object store in a container can be passed to a function expecting 718 | a pointer. These conversion work seamlessly. 719 | 720 | ## Security 721 | 722 | The metatables and userdata that LuaBridge creates in the `lua_State*` are 723 | protected using a security system, to eliminate the possibility of undefined 724 | behavior resulting from scripted manipulation of the environment. The 725 | security system has these components: 726 | 727 | - Class and const class tables use the 'table proxy' technique. The 728 | corresponding metatables have `__index` and `__newindex` metamethods, 729 | so these class tables are immutable from Lua. 730 | 731 | - Metatables have `__metatable` set to a boolean value. Scripts cannot 732 | obtain the metatable from a LuaBridge object. 733 | 734 | - Classes are mapped to metatables through the registry, which Lua scripts 735 | cannot access. The global environment does not expose metatables 736 | 737 | - Metatables created by LuaBridge are tagged with a lightuserdata key which 738 | is unique in the process. Other libraries cannot forge a LuaBridge 739 | metatable. 740 | 741 | This security system can be easily bypassed if scripts are given access to 742 | the debug library (or functionality similar to it, i.e. a raw `getmetatable`). 743 | The security system can also be defeated by C code in the host, either by 744 | revealing the unique lightuserdata key to another module or by putting a 745 | LuaBridge metatable in a place that can be accessed by scripts. 746 | 747 | When a class member function is called, or class property member accessed, 748 | the `this` pointer is type-checked. This is because member functions exposed 749 | to Lua are just plain functions that usually get called with the Lua colon 750 | notation, which passes the object in question as the first parameter. Lua's 751 | dynamic typing makes this type-checking mandatory to prevent undefined 752 | behavior resulting from improper use. 753 | 754 | If a type check error occurs, LuaBridge uses the `lua_error` mechanism to 755 | trigger a failure. A host program can always recover from an error through 756 | the use of `lua_pcall`; proper usage of LuaBridge will never result in 757 | undefined behavior. 758 | 759 | ## Limitations 760 | 761 | LuaBridge does not support: 762 | 763 | - Enumerated constants 764 | - More than 8 parameters on a function or method (although this can be 765 | increased by adding more `TypeListValues` specializations). 766 | - Overloaded functions, methods, or constructors. 767 | - Global variables (variables must be wrapped in a named scope). 768 | - Automatic conversion between STL container types and Lua tables. 769 | - Inheriting Lua classes from C++ classes. 770 | - Passing nil to a C++ function that expects a pointer or reference. 771 | - Standard containers like `std::shared_ptr`. 772 | 773 | ## Development 774 | 775 | [Github][3] is the new official home for LuaBridge. The old SVN repository is 776 | deprecated since it is no longer used, or maintained. The original author has 777 | graciously passed the reins to Vinnie Falco for maintaining and improving the 778 | project. To obtain the older official releases, checkout the tags from 0.2.1 779 | and earlier. 780 | 781 | If you are an existing LuaBridge user, a new LuaBridge user, or a potential 782 | LuaBridge user, we welcome your input, feedback, and contributions. Feel 783 | free to open Issues, or fork the repository. All questions, comments, 784 | suggestions, and/or proposed changes will be handled by the new maintainer. 785 | 786 | ## License 787 | 788 | Copyright (C) 2012, [Vinnie Falco][1] ([e-mail][0])
789 | Copyright (C) 2007, Nathan Reed
790 | 791 | Portions from The Loki Library:
792 | Copyright (C) 2001 by Andrei Alexandrescu 793 | 794 | License: The [MIT License][2] 795 | 796 | Older versions of LuaBridge up to and including 0.2 are distributed under the 797 | BSD 3-Clause License. See the corresponding license file in those versions 798 | for more details. 799 | 800 | [0]: mailto:vinnie.falco@gmail.com "Vinnie Falco (Email)" 801 | [1]: http://www.vinniefalco.com "Vinnie Falco" 802 | [2]: http://www.opensource.org/licenses/mit-license.html "The MIT License" 803 | [3]: https://github.com/vinniefalco/LuaBridge "LuaBridge" 804 | [4]: https://github.com/vinniefalco/LuaBridgeDemo "LuaBridge Demo" 805 | [5]: http://lua.org "The Lua Programming Language" 806 | [6]: http://www.rawmaterialsoftware.com/juce/api/classString.html "juce::String" 807 | [7]: https://github.com/vinniefalco/LuaBridge "LuaBridge master branch" 808 | [8]: https://github.com/vinniefalco/LuaBridge/tree/release "LuaBridge release branch" 809 | [9]: https://github.com/vinniefalco/LuaBridge/tree/develop "LuaBridge develop branch" 810 | -------------------------------------------------------------------------------- /LuaBridge/RefCountedObject.h: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | /* 3 | https://github.com/vinniefalco/LuaBridge 4 | https://github.com/vinniefalco/LuaBridgeDemo 5 | 6 | Copyright (C) 2012, Vinnie Falco 7 | Copyright 2004-11 by Raw Material Software Ltd. 8 | 9 | This is a derivative work used by permission from part of 10 | JUCE, available at http://www.rawaterialsoftware.com 11 | 12 | License: The MIT License (http://www.opensource.org/licenses/mit-license.php) 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all 22 | copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | SOFTWARE. 31 | 32 | This file incorporates work covered by the following copyright and 33 | permission notice: 34 | 35 | This file is part of the JUCE library - "Jules' Utility Class Extensions" 36 | Copyright 2004-11 by Raw Material Software Ltd. 37 | */ 38 | //============================================================================== 39 | 40 | #ifndef LUABRIDGE_REFCOUNTEDOBJECT_HEADER 41 | #define LUABRIDGE_REFCOUNTEDOBJECT_HEADER 42 | 43 | #if !defined (LUABRIDGE_LUABRIDGE_HEADER) 44 | #error LuaBridge.h must be included before including this file 45 | #endif 46 | 47 | //#define LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 48 | 49 | //============================================================================== 50 | /** 51 | Adds reference-counting to an object. 52 | 53 | To add reference-counting to a class, derive it from this class, and 54 | use the RefCountedObjectPtr class to point to it. 55 | 56 | e.g. @code 57 | class MyClass : public RefCountedObjectType 58 | { 59 | void foo(); 60 | 61 | // This is a neat way of declaring a typedef for a pointer class, 62 | // rather than typing out the full templated name each time.. 63 | typedef RefCountedObjectPtr Ptr; 64 | }; 65 | 66 | MyClass::Ptr p = new MyClass(); 67 | MyClass::Ptr p2 = p; 68 | p = 0; 69 | p2->foo(); 70 | @endcode 71 | 72 | Once a new RefCountedObjectType has been assigned to a pointer, be 73 | careful not to delete the object manually. 74 | */ 75 | template 76 | class RefCountedObjectType 77 | { 78 | public: 79 | //============================================================================== 80 | /** Increments the object's reference count. 81 | 82 | This is done automatically by the smart pointer, but is public just 83 | in case it's needed for nefarious purposes. 84 | */ 85 | inline void incReferenceCount() const 86 | { 87 | ++refCount; 88 | } 89 | 90 | /** Decreases the object's reference count. 91 | 92 | If the count gets to zero, the object will be deleted. 93 | */ 94 | inline void decReferenceCount() const 95 | { 96 | assert (getReferenceCount() > 0); 97 | 98 | if (--refCount == 0) 99 | delete this; 100 | } 101 | 102 | /** Returns the object's current reference count. */ 103 | inline int getReferenceCount() const 104 | { 105 | return static_cast (refCount); 106 | } 107 | 108 | protected: 109 | //============================================================================== 110 | /** Creates the reference-counted object (with an initial ref count of zero). */ 111 | RefCountedObjectType() : refCount () 112 | { 113 | } 114 | 115 | /** Destructor. */ 116 | virtual ~RefCountedObjectType() 117 | { 118 | // it's dangerous to delete an object that's still referenced by something else! 119 | assert (getReferenceCount() == 0); 120 | } 121 | 122 | private: 123 | //============================================================================== 124 | CounterType mutable refCount; 125 | }; 126 | 127 | //============================================================================== 128 | /** 129 | A smart-pointer class which points to a reference-counted object. 130 | 131 | The template parameter specifies the class of the object you want to point to - the easiest 132 | way to make a class reference-countable is to simply make it inherit from RefCountedObjectType, 133 | but if you need to, you could roll your own reference-countable class by implementing a pair of 134 | mathods called incReferenceCount() and decReferenceCount(). 135 | 136 | When using this class, you'll probably want to create a typedef to abbreviate the full 137 | templated name - e.g. 138 | 139 | @code typedef RefCountedObjectPtr MyClassPtr;@endcode 140 | */ 141 | template 142 | class RefCountedObjectPtr 143 | { 144 | public: 145 | /** The class being referenced by this pointer. */ 146 | typedef ReferenceCountedObjectClass ReferencedType; 147 | 148 | //============================================================================== 149 | /** Creates a pointer to a null object. */ 150 | inline RefCountedObjectPtr() : referencedObject (0) 151 | { 152 | } 153 | 154 | /** Creates a pointer to an object. 155 | 156 | This will increment the object's reference-count if it is non-null. 157 | */ 158 | inline RefCountedObjectPtr (ReferenceCountedObjectClass* const refCountedObject) 159 | : referencedObject (refCountedObject) 160 | { 161 | if (refCountedObject != 0) 162 | refCountedObject->incReferenceCount(); 163 | } 164 | 165 | /** Copies another pointer. 166 | This will increment the object's reference-count (if it is non-null). 167 | */ 168 | inline RefCountedObjectPtr (const RefCountedObjectPtr& other) 169 | : referencedObject (other.referencedObject) 170 | { 171 | if (referencedObject != 0) 172 | referencedObject->incReferenceCount(); 173 | } 174 | 175 | #if LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS 176 | /** Takes-over the object from another pointer. */ 177 | inline RefCountedObjectPtr (RefCountedObjectPtr&& other) 178 | : referencedObject (other.referencedObject) 179 | { 180 | other.referencedObject = 0; 181 | } 182 | #endif 183 | 184 | /** Copies another pointer. 185 | This will increment the object's reference-count (if it is non-null). 186 | */ 187 | template 188 | inline RefCountedObjectPtr (const RefCountedObjectPtr& other) 189 | : referencedObject (static_cast (other.getObject())) 190 | { 191 | if (referencedObject != 0) 192 | referencedObject->incReferenceCount(); 193 | } 194 | 195 | /** Changes this pointer to point at a different object. 196 | 197 | The reference count of the old object is decremented, and it might be 198 | deleted if it hits zero. The new object's count is incremented. 199 | */ 200 | RefCountedObjectPtr& operator= (const RefCountedObjectPtr& other) 201 | { 202 | return operator= (other.referencedObject); 203 | } 204 | 205 | /** Changes this pointer to point at a different object. 206 | 207 | The reference count of the old object is decremented, and it might be 208 | deleted if it hits zero. The new object's count is incremented. 209 | */ 210 | template 211 | RefCountedObjectPtr& operator= (const RefCountedObjectPtr& other) 212 | { 213 | return operator= (static_cast (other.getObject())); 214 | } 215 | 216 | #if LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS 217 | /** Takes-over the object from another pointer. */ 218 | RefCountedObjectPtr& operator= (RefCountedObjectPtr&& other) 219 | { 220 | std::swap (referencedObject, other.referencedObject); 221 | return *this; 222 | } 223 | #endif 224 | 225 | /** Changes this pointer to point at a different object. 226 | 227 | The reference count of the old object is decremented, and it might be 228 | deleted if it hits zero. The new object's count is incremented. 229 | */ 230 | RefCountedObjectPtr& operator= (ReferenceCountedObjectClass* const newObject) 231 | { 232 | if (referencedObject != newObject) 233 | { 234 | if (newObject != 0) 235 | newObject->incReferenceCount(); 236 | 237 | ReferenceCountedObjectClass* const oldObject = referencedObject; 238 | referencedObject = newObject; 239 | 240 | if (oldObject != 0) 241 | oldObject->decReferenceCount(); 242 | } 243 | 244 | return *this; 245 | } 246 | 247 | /** Destructor. 248 | 249 | This will decrement the object's reference-count, and may delete it if it 250 | gets to zero. 251 | */ 252 | inline ~RefCountedObjectPtr() 253 | { 254 | if (referencedObject != 0) 255 | referencedObject->decReferenceCount(); 256 | } 257 | 258 | /** Returns the object that this pointer references. 259 | The pointer returned may be zero, of course. 260 | */ 261 | inline operator ReferenceCountedObjectClass*() const 262 | { 263 | return referencedObject; 264 | } 265 | 266 | // the -> operator is called on the referenced object 267 | inline ReferenceCountedObjectClass* operator->() const 268 | { 269 | return referencedObject; 270 | } 271 | 272 | /** Returns the object that this pointer references. 273 | The pointer returned may be zero, of course. 274 | */ 275 | inline ReferenceCountedObjectClass* getObject() const 276 | { 277 | return referencedObject; 278 | } 279 | 280 | private: 281 | //============================================================================== 282 | ReferenceCountedObjectClass* referencedObject; 283 | }; 284 | 285 | /** Compares two ReferenceCountedObjectPointers. */ 286 | template 287 | bool operator== (const RefCountedObjectPtr& object1, ReferenceCountedObjectClass* const object2) 288 | { 289 | return object1.getObject() == object2; 290 | } 291 | 292 | /** Compares two ReferenceCountedObjectPointers. */ 293 | template 294 | bool operator== (const RefCountedObjectPtr& object1, const RefCountedObjectPtr& object2) 295 | { 296 | return object1.getObject() == object2.getObject(); 297 | } 298 | 299 | /** Compares two ReferenceCountedObjectPointers. */ 300 | template 301 | bool operator== (ReferenceCountedObjectClass* object1, RefCountedObjectPtr& object2) 302 | { 303 | return object1 == object2.getObject(); 304 | } 305 | 306 | /** Compares two ReferenceCountedObjectPointers. */ 307 | template 308 | bool operator!= (const RefCountedObjectPtr& object1, const ReferenceCountedObjectClass* object2) 309 | { 310 | return object1.getObject() != object2; 311 | } 312 | 313 | /** Compares two ReferenceCountedObjectPointers. */ 314 | template 315 | bool operator!= (const RefCountedObjectPtr& object1, RefCountedObjectPtr& object2) 316 | { 317 | return object1.getObject() != object2.getObject(); 318 | } 319 | 320 | /** Compares two ReferenceCountedObjectPointers. */ 321 | template 322 | bool operator!= (ReferenceCountedObjectClass* object1, RefCountedObjectPtr& object2) 323 | { 324 | return object1 != object2.getObject(); 325 | } 326 | 327 | //============================================================================== 328 | 329 | namespace luabridge 330 | { 331 | 332 | template 333 | struct ContainerTraits > 334 | { 335 | typedef T Type; 336 | 337 | static T* get (RefCountedObjectPtr const& c) 338 | { 339 | return c.getObject (); 340 | } 341 | }; 342 | 343 | } 344 | 345 | //============================================================================== 346 | 347 | #endif 348 | 349 | -------------------------------------------------------------------------------- /LuaBridge/RefCountedPtr.h: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | /* 3 | https://github.com/vinniefalco/LuaBridge 4 | https://github.com/vinniefalco/LuaBridgeDemo 5 | 6 | Copyright (C) 2012, Vinnie Falco 7 | Copyright (C) 2007, Nathan Reed 8 | 9 | License: The MIT License (http://www.opensource.org/licenses/mit-license.php) 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all 19 | copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | SOFTWARE. 28 | */ 29 | //============================================================================== 30 | 31 | #ifndef LUABRIDGE_REFCOUNTEDPTR_HEADER 32 | #define LUABRIDGE_REFCOUNTEDPTR_HEADER 33 | 34 | #ifdef _MSC_VER 35 | # include 36 | #else 37 | # include 38 | # include 39 | #endif 40 | 41 | //============================================================================== 42 | /** 43 | Support for our RefCountedPtr. 44 | */ 45 | struct RefCountedPtrBase 46 | { 47 | // Declaration of container for the refcounts 48 | #ifdef _MSC_VER 49 | typedef stdext::hash_map RefCountsType; 50 | #else 51 | struct ptr_hash 52 | { 53 | size_t operator () (const void * const v) const 54 | { 55 | static __gnu_cxx::hash H; 56 | return H(uintptr_t(v)); 57 | } 58 | }; 59 | typedef __gnu_cxx::hash_map RefCountsType; 60 | #endif 61 | 62 | protected: 63 | inline RefCountsType& getRefCounts () 64 | { 65 | static RefCountsType refcounts; 66 | return refcounts ; 67 | } 68 | }; 69 | 70 | //============================================================================== 71 | /** 72 | A reference counted smart pointer. 73 | 74 | The api is compatible with boost::RefCountedPtr and std::RefCountedPtr, in the 75 | sense that it implements a strict subset of the functionality. 76 | 77 | This implementation uses a hash table to look up the reference count 78 | associated with a particular pointer. 79 | 80 | @tparam T The class type. 81 | 82 | @todo Decompose RefCountedPtr using a policy. At a minimum, the underlying 83 | reference count should be policy based (to support atomic operations) 84 | and the delete behavior should be policy based (to support custom 85 | disposal methods). 86 | 87 | @todo Provide an intrusive version of RefCountedPtr. 88 | */ 89 | template 90 | class RefCountedPtr : private RefCountedPtrBase 91 | { 92 | public: 93 | template 94 | struct rebind 95 | { 96 | typedef RefCountedPtr other; 97 | }; 98 | 99 | /** Construct as nullptr or from existing pointer to T. 100 | 101 | @param p The optional, existing pointer to assign from. 102 | */ 103 | RefCountedPtr (T* p = 0) : m_p (p) 104 | { 105 | ++getRefCounts () [m_p]; 106 | } 107 | 108 | /** Construct from another RefCountedPtr. 109 | 110 | @param rhs The RefCountedPtr to assign from. 111 | */ 112 | RefCountedPtr (RefCountedPtr const& rhs) : m_p (rhs.get()) 113 | { 114 | ++getRefCounts () [m_p]; 115 | } 116 | 117 | /** Construct from a RefCountedPtr of a different type. 118 | 119 | @invariant A pointer to U must be convertible to a pointer to T. 120 | 121 | @param rhs The RefCountedPtr to assign from. 122 | @tparam U The other object type. 123 | */ 124 | template 125 | RefCountedPtr (RefCountedPtr const& rhs) : m_p (static_cast (rhs.get())) 126 | { 127 | ++getRefCounts () [m_p]; 128 | } 129 | 130 | /** Release the object. 131 | 132 | If there are no more references then the object is deleted. 133 | */ 134 | ~RefCountedPtr () 135 | { 136 | reset(); 137 | } 138 | 139 | /** Assign from another RefCountedPtr. 140 | 141 | @param rhs The RefCountedPtr to assign from. 142 | @return A reference to the RefCountedPtr. 143 | */ 144 | RefCountedPtr & operator= (RefCountedPtr const& rhs) 145 | { 146 | if (m_p != rhs.m_p) 147 | { 148 | reset (); 149 | m_p = rhs.m_p; 150 | ++getRefCounts () [m_p]; 151 | } 152 | return *this; 153 | } 154 | 155 | /** Assign from another RefCountedPtr of a different type. 156 | 157 | @note A pointer to U must be convertible to a pointer to T. 158 | 159 | @tparam U The other object type. 160 | @param rhs The other RefCountedPtr to assign from. 161 | @return A reference to the RefCountedPtr. 162 | */ 163 | template 164 | RefCountedPtr & operator= (RefCountedPtr const& rhs) 165 | { 166 | reset (); 167 | m_p = static_cast (rhs.get()); 168 | ++getRefCounts () [m_p]; 169 | return *this; 170 | } 171 | 172 | /** Retrieve the raw pointer. 173 | 174 | @return A pointer to the object. 175 | */ 176 | T* get () const 177 | { 178 | return m_p; 179 | } 180 | 181 | /** Retrieve the raw pointer. 182 | 183 | @return A pointer to the object. 184 | */ 185 | T* operator* () const 186 | { 187 | return m_p; 188 | } 189 | 190 | /** Retrieve the raw pointer. 191 | 192 | @return A pointer to the object. 193 | */ 194 | T* operator-> () const 195 | { 196 | return m_p; 197 | } 198 | 199 | /** Determine the number of references. 200 | 201 | @note This is not thread-safe. 202 | 203 | @return The number of active references. 204 | */ 205 | long use_count () const 206 | { 207 | return getRefCounts () [m_p]; 208 | } 209 | 210 | /** Release the pointer. 211 | 212 | The reference count is decremented. If the reference count reaches 213 | zero, the object is deleted. 214 | */ 215 | void reset () 216 | { 217 | if (m_p != 0) 218 | { 219 | if (--getRefCounts () [m_p] <= 0) 220 | delete m_p; 221 | 222 | m_p = 0; 223 | } 224 | } 225 | 226 | private: 227 | T* m_p; 228 | }; 229 | 230 | //============================================================================== 231 | 232 | namespace luabridge 233 | { 234 | 235 | template 236 | struct ContainerTraits > 237 | { 238 | typedef T Type; 239 | 240 | static T* get (RefCountedPtr const& c) 241 | { 242 | return c.get (); 243 | } 244 | }; 245 | 246 | } 247 | 248 | #endif 249 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | InspectLua 2 | ========== 3 | 4 | 主要深入学习Lua,包括Lua与C等其他语言的交互、Lua源码阅读等。下面是各个源文件一个简单的说明: 5 | 6 | 学习在C中调用lua的一般全局变量、table以及函数相应的文件有: 7 | 8 | TestConfig.lua 9 | 10 | util.h 11 | 12 | util.c --主要定义了打印lua栈、C中调用Lua的函数一个通用接口 13 | capi_example.c --主要用来熟悉lua与c交互的一些API 14 | c_function_to_extend_lua.c 15 | extend_c_app_by_lua.c 16 | test_general_call_lua_in_c.c 17 | simple_lua_interpreter.c 18 | 19 | 学习在Lua中使用C中定义的函数、模块以及userdata,相关的文件有: 20 | 21 | TestLuaExtendedbyC.lua 22 | 23 | c_function_to_extend_lua.h 24 | 25 | c_function_to_extend_lua.c 26 | c_module_to_extend_lua.c 27 | c_userdata_to_extend_lua.c 28 | c_userdata_with_gc_to_extend_lua.c --测试lua在回收userdata时,会调用相应元表的__gc对应方法 29 | test_extend_lua_by_c.c 30 | 31 | 把C++中定义的类以及成员方法,在lua中使用,相关的文件有: 32 | 33 | TestBindingCppWithLua.lua 34 | 35 | binding_cpp_with_lua.cpp 36 | binding_cpp_with_lua.hpp --定义了模板,可以方便封装要在lua中使用的类以及方法 37 | test_binding_cpp_with_lua.hpp 38 | 39 | 利用LuaBridge绑定C++到Lua,相关的文件有: 40 | 41 | LuaBridge/ 42 | study_lua_bridge_main.cpp 43 | study_lua_bridge.lua 44 | 45 | 利用LuaBridge绑定C++到Lua,相关的文件有: 46 | 47 | TestBindingCppWithLua.lua 48 | test_binding_cpp_with_lua.cpp 49 | binding_cpp_with_lunafive.hpp 50 | 51 | 利用lunar绑定C++到Lua,相关的文件有: 52 | 53 | lunar_test_script.lua 54 | lunar_test_main.cpp 55 | lunar.hpp 56 | 57 | 58 | -------------------------------------------------------------------------------- /TestBindingCppWithLua.lua: -------------------------------------------------------------------------------- 1 | 2 | local foo = Foo() 3 | 4 | foo:foo() -- in foo 5 | 6 | foo:set_member(8) 7 | local member = foo:get_member() 8 | 9 | print("object member value:",member) --8 10 | 11 | --property test 12 | print("object member value:",foo.member) --8 13 | 14 | foo.member = 9 15 | print("object member value:",foo.member) --9 16 | 17 | foo1 = Foo() 18 | 19 | print(tostring(foo1)) --Foo (0x97d9e0) 20 | 21 | print(foo == foo) --true 22 | print(foo1 == foo) --false 23 | -------------------------------------------------------------------------------- /TestConfig.lua: -------------------------------------------------------------------------------- 1 | --test confg 2 | width = 10 3 | height = 20 4 | 5 | --test table 6 | --background = "BLUE" 7 | background = {r = 0.3, g = 0.1, b = 0} 8 | 9 | --test lua function in c 10 | function f(x,y) 11 | return (x^2 * math.sin(y))/(1 - x) --luaL_openlibs(L) must be called in c 12 | end 13 | -------------------------------------------------------------------------------- /TestLuaExtendedbyC.lua: -------------------------------------------------------------------------------- 1 | -- 2 | print("--extend lua by c function--") 3 | -- 4 | local angle = 30 5 | print("libsin:",math.sin(angle)) 6 | print("mysin:",mysin(angle)) 7 | 8 | -- 9 | print("--extend lua by c module--") 10 | -- 11 | --require "mylib" 12 | print("mysininmodule:",mytestlib.sin(angle)) 13 | 14 | local s = {1,2,3} 15 | function f(i) 16 | return 2*i 17 | end 18 | 19 | mytestlib.map(s,f) 20 | for _,v in ipairs(s) do 21 | print("i:",v) 22 | end 23 | 24 | -- 25 | print("--test upvalue in c function--") 26 | -- 27 | x = mytestlib.tuplenew(10,"hi",{},3) 28 | print(x(1)) 29 | print(x(2)) 30 | print(x(3)) 31 | print(x()) 32 | 33 | -- 34 | print("--test userdata--") 35 | -- 36 | local SIZE = 1000 37 | a = array.new(SIZE) 38 | 39 | --[[ 40 | print(a) --userdata: 0x1c15af8 41 | print(array.size(a)) --1000 42 | for i = 1,SIZE do 43 | array.set(a,i,i%5==0) 44 | end 45 | 46 | print(array.get(a,10)) --true 47 | print(array.get(a,9)) --false 48 | --print(array.get(io.stdin,10)) --cannot run config. file:TestLuaExtendedbyC.lua:46: bad argument #1 to 'get' (MyArray expected, got userdata) 49 | --]] 50 | 51 | print(a) --userdata: 0x1c15af8 52 | print(a:size()) --1000 53 | for i = 1,SIZE do 54 | a:set(i,i%5==0) 55 | end 56 | 57 | print(a:get(10)) --true 58 | print(a:get(9)) --false 59 | 60 | for name in dir(".") do 61 | print(name) 62 | end 63 | -------------------------------------------------------------------------------- /binding_cpp_with_lua.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | test a c++ template to bind cpp with lua 3 | 4 | Example: 5 | $g++ binding_cpp_with_lua.cpp -llua -lm -ldl -o binding_cpp_with_lua 6 | $./binding_cpp_with_lua 7 | in constructor 8 | in foo 9 | in foo 10 | haha,extend 11 | object member value: 8 12 | in destructor 13 | 14 | Analyse: 15 | 16 | */ 17 | 18 | 19 | #include "test_binding_cpp_with_lua.hpp" 20 | 21 | void load(lua_State *L, const char *file_name) 22 | { 23 | if ((luaL_loadfile(L,file_name)) || (lua_pcall(L,0,0,0))) 24 | printf("cannot run config file:%s\n",lua_tostring(L,-1)); 25 | } 26 | 27 | int main(void) 28 | { 29 | const char *fname = "TestBindingCppWithLua.lua"; 30 | 31 | lua_State *L = luaL_newstate(); 32 | luaL_openlibs(L); 33 | 34 | Luna::Register(L); 35 | 36 | load(L,fname); /*load confile file*/ 37 | 38 | lua_close(L); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /binding_cpp_with_lua.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | define a c++ template to bind cpp with lua 3 | */ 4 | 5 | #ifndef BINDING_CPP_WITH_LUA_HPP 6 | #define BINDING_CPP_WITH_LUA_HPP 7 | 8 | extern "C" { 9 | #include "lua.h" 10 | #include "lualib.h" 11 | #include "lauxlib.h" 12 | } 13 | 14 | template class Luna { 15 | public: 16 | static void Register(lua_State *L) { 17 | lua_pushcfunction(L,&Luna::construct); 18 | lua_setglobal(L,T::className); 19 | 20 | luaL_newmetatable(L,T::className); 21 | lua_pushstring(L,"__gc"); 22 | lua_pushcfunction(L,&Luna::gc_obj); 23 | lua_settable(L,-3); 24 | } 25 | 26 | static int construct(lua_State *L) { 27 | T* obj = new T(L); 28 | 29 | lua_newtable(L); 30 | lua_pushnumber(L,0); 31 | T** a = (T**)lua_newuserdata(L,sizeof(T*)); 32 | *a = obj; 33 | luaL_getmetatable(L,T::className); 34 | lua_setmetatable(L,-2); //set userdata metatable 35 | lua_settable(L,-3); //table[0] = userdataobj 36 | 37 | for (int i = 0; T::Register[i].name; i++) 38 | { 39 | lua_pushstring(L,T::Register[i].name); 40 | lua_pushnumber(L,i); 41 | lua_pushcclosure(L,&Luna::thunk,1); 42 | lua_settable(L,-3); //table["funcname"] = funcnameofuserdata 43 | } 44 | 45 | return 1; 46 | } 47 | 48 | static int thunk(lua_State *L) { 49 | int i = (int)lua_tonumber(L,lua_upvalueindex(1)); 50 | 51 | lua_pushnumber(L,0); 52 | lua_gettable(L,1); 53 | 54 | T** obj = static_cast(luaL_checkudata(L,-1,T::className)); 55 | lua_remove(L,-1); 56 | return ((*obj)->*(T::Register[i].mfunc))(L); 57 | } 58 | 59 | static int gc_obj(lua_State *L) { 60 | T** obj = static_cast(luaL_checkudata(L,-1,T::className)); 61 | delete (*obj); 62 | return 0; 63 | } 64 | 65 | struct RegTpe { 66 | const char *name; 67 | int (T::*mfunc)(lua_State*); 68 | }; 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /binding_cpp_with_lunafive.hpp: -------------------------------------------------------------------------------- 1 | #include "lua.hpp" 2 | #include // For strlen 3 | 4 | #define nullptr 0 5 | 6 | template < class T > class Luna { 7 | public: 8 | 9 | struct PropertyType { 10 | const char *name; 11 | int (T::*getter) (lua_State *); 12 | int (T::*setter) (lua_State *); 13 | }; 14 | 15 | struct FunctionType { 16 | const char *name; 17 | int (T::*func) (lua_State *); 18 | }; 19 | 20 | /* 21 | @ check 22 | Arguments: 23 | * L - Lua State 24 | * narg - Position to check 25 | 26 | Description: 27 | Retrieves a wrapped class from the arguments passed to the func, specified by narg (position). 28 | This func will raise an exception if the argument is not of the correct type. 29 | */ 30 | static T* check(lua_State * L, int narg) 31 | { 32 | T** obj = static_cast (luaL_checkudata(L, narg, T::className)); 33 | if ( !obj ) 34 | return nullptr; // lightcheck returns nullptr if not found. 35 | return *obj; // return pointer to T object 36 | } 37 | 38 | /* 39 | @ lightcheck 40 | Arguments: 41 | * L - Lua State 42 | * narg - Position to check 43 | 44 | Description: 45 | Retrieves a wrapped class from the arguments passed to the func, specified by narg (position). 46 | This func will return nullptr if the argument is not of the correct type. Useful for supporting 47 | multiple types of arguments passed to the func 48 | */ 49 | static T* lightcheck(lua_State * L, int narg) { 50 | T** obj = static_cast (luaL_testudata(L, narg, T::className)); 51 | if ( !obj ) 52 | return nullptr; // lightcheck returns nullptr if not found. 53 | return *obj; //return pointer to T object 54 | } 55 | 56 | /* 57 | @ Register 58 | Arguments: 59 | * L - Lua State 60 | * namespac - Namespace to load into 61 | 62 | Description: 63 | Registers your class with Lua. Leave namespac "" if you want to load it into the global space. 64 | */ 65 | // REGISTER CLASS AS A GLOBAL TABLE 66 | static void Register(lua_State * L, const char *namespac = NULL ) { 67 | 68 | if ( namespac && strlen(namespac) ) 69 | { 70 | lua_getglobal(L, namespac); 71 | if( lua_isnil(L,-1) ) // Create namespace if not present 72 | { 73 | lua_newtable(L); 74 | lua_pushvalue(L,-1); // Duplicate table pointer since setglobal pops the value 75 | lua_setglobal(L,namespac); 76 | } 77 | lua_pushcfunction(L, &Luna < T >::constructor); 78 | lua_setfield(L, -2, T::className); 79 | lua_pop(L, 1); 80 | } else { 81 | lua_pushcfunction(L, &Luna < T >::constructor); 82 | lua_setglobal(L, T::className); 83 | } 84 | 85 | luaL_newmetatable(L, T::className); 86 | int metatable = lua_gettop(L); 87 | 88 | lua_pushstring(L, "__gc"); 89 | lua_pushcfunction(L, &Luna < T >::gc_obj); 90 | lua_settable(L, metatable); 91 | 92 | lua_pushstring(L, "__tostring"); 93 | lua_pushcfunction(L, &Luna < T >::to_string); 94 | lua_settable(L, metatable); 95 | 96 | // To be able to compare two Luna objects 97 | //(not natively possible with full userdata) 98 | lua_pushstring(L, "__eq"); 99 | lua_pushcfunction(L, &Luna < T >::equals); 100 | lua_settable(L, metatable); 101 | 102 | lua_pushstring(L, "__index"); 103 | lua_pushcfunction(L, &Luna < T >::property_getter); 104 | lua_settable(L, metatable); 105 | 106 | lua_pushstring(L, "__newindex"); 107 | lua_pushcfunction(L, &Luna < T >::property_setter); 108 | lua_settable(L, metatable); 109 | 110 | for (int i = 0; T::properties[i].name; i++) { // Register some properties in it 111 | lua_pushstring(L, T::properties[i].name); //it Having some string associated with them 112 | lua_pushnumber(L, i); // And a number indexing which property it is 113 | lua_settable(L, metatable); //metatable[i] = propertyfunc 114 | } 115 | 116 | for (int i = 0; T::methods[i].name; i++) { 117 | lua_pushstring(L, T::methods[i].name); // Register some functions in it 118 | lua_pushnumber(L, i | ( 1 << 8 ) ); // Add a number indexing which func it is 119 | lua_settable(L, metatable); //metatable[i] = method 120 | } 121 | } 122 | 123 | /* 124 | @ constructor (internal) 125 | Arguments: 126 | * L - Lua State 127 | */ 128 | static int constructor(lua_State * L) 129 | { 130 | T* ap = new T(L); 131 | T** a = static_cast(lua_newuserdata(L, sizeof(T *))); // Push value = userdata 132 | *a = ap; 133 | 134 | luaL_getmetatable(L, T::className); // Fetch global metatable T::classname 135 | lua_setmetatable(L, -2); 136 | return 1; //return a userdata type to lua 137 | } 138 | 139 | /* 140 | @ createNew 141 | Arguments: 142 | * L - Lua State 143 | T*State- Instance to push 144 | 145 | Description: 146 | Loads an instance of the class into the Lua stack, and provides you a pointer so you can modify it. 147 | */ 148 | static void push(lua_State * L, T* instance ) 149 | { 150 | T **a = (T **) lua_newuserdata(L, sizeof(T *)); // Create userdata 151 | *a = instance; 152 | 153 | luaL_getmetatable(L, T::className); 154 | 155 | lua_setmetatable(L, -2); 156 | } 157 | 158 | /* 159 | @ property_getter (internal) Arguments: * L - Lua State */ 160 | static int property_getter(lua_State * L) 161 | { 162 | lua_getmetatable(L, 1); // Look up the index of a name 163 | lua_pushvalue(L, 2);// Push the name 164 | lua_rawget(L, -2);// Get the index 165 | 166 | if (lua_isnumber(L, -1)) { // Check if we got a valid index 167 | 168 | int _index = lua_tonumber(L, -1); 169 | 170 | T** obj = static_cast(lua_touserdata(L, 1)); 171 | 172 | lua_pushvalue(L, 3); 173 | 174 | if( _index & ( 1 << 8 ) ) // A func 175 | { 176 | lua_pushnumber(L, _index ^ ( 1 << 8 ) ); // Push the right func index 177 | lua_pushlightuserdata(L, obj); 178 | lua_pushcclosure(L, &Luna < T >::function_dispatch, 2); 179 | return 1; // Return a func 180 | } 181 | 182 | lua_pop(L,2); // Pop metatable and _index 183 | lua_remove(L,1); // Remove userdata 184 | lua_remove(L,1); // Remove [key] 185 | 186 | return ((*obj)->*(T::properties[_index].getter)) (L); 187 | } 188 | 189 | return 1; 190 | } 191 | 192 | /* 193 | @ property_setter (internal) 194 | Arguments: 195 | * L - Lua State 196 | */ 197 | static int property_setter(lua_State * L) 198 | { 199 | 200 | lua_getmetatable(L, 1); // Look up the index from name 201 | lua_pushvalue(L, 2); 202 | lua_rawget(L, -2); 203 | 204 | if ( lua_isnumber(L, -1) ) // Check if we got a valid index 205 | { 206 | 207 | int _index = lua_tonumber(L, -1); 208 | 209 | T** obj = static_cast(lua_touserdata(L, 1)); 210 | 211 | if( !obj || !*obj ) 212 | { 213 | luaL_error( L , "Internal error, no object given!" ); 214 | return 0; 215 | } 216 | 217 | if( _index >> 8 ) // Try to set a func 218 | { 219 | char c[128]; 220 | sprintf( c , "Trying to set the method [%s] of class [%s]" , (*obj)->T::methods[_index ^ ( 1 << 8 ) ].name , T::className ); 221 | luaL_error( L , c ); 222 | return 0; 223 | } 224 | 225 | lua_pop(L,2); // Pop metatable and _index 226 | lua_remove(L,1); // Remove userdata 227 | lua_remove(L,1); // Remove [key] 228 | 229 | return ((*obj)->*(T::properties[_index].setter)) (L); 230 | } 231 | 232 | return 0; 233 | } 234 | 235 | /* 236 | @ function_dispatch (internal) 237 | Arguments: 238 | * L - Lua State 239 | */ 240 | static int function_dispatch(lua_State * L) 241 | { 242 | int i = (int) lua_tonumber(L, lua_upvalueindex(1)); 243 | T** obj = static_cast < T ** >(lua_touserdata(L, lua_upvalueindex(2))); 244 | 245 | return ((*obj)->*(T::methods[i].func)) (L); 246 | } 247 | 248 | /* 249 | @ gc_obj (internal) 250 | Arguments: 251 | * L - Lua State 252 | */ 253 | static int gc_obj(lua_State * L) 254 | { 255 | T** obj = static_cast < T ** >(lua_touserdata(L, -1)); 256 | 257 | if( obj && *obj ) 258 | delete(*obj); 259 | 260 | return 0; 261 | } 262 | 263 | static int to_string(lua_State* L) 264 | { 265 | T** obj = static_cast(lua_touserdata(L, -1)); 266 | 267 | if( obj ) 268 | lua_pushfstring(L, "%s (%p)", T::className, (void*)*obj); 269 | else 270 | lua_pushstring(L,"Empty object"); 271 | 272 | return 1; 273 | } 274 | 275 | /* 276 | * Method which compares two Luna objects. 277 | * The full userdatas (as opposed to light userdata) can't be natively compared one to other, we have to had this to do it. 278 | */ 279 | static int equals(lua_State* L) 280 | { 281 | T** obj1 = static_cast(lua_touserdata(L, -1)); 282 | T** obj2 = static_cast(lua_touserdata(L, 1)); 283 | 284 | lua_pushboolean(L, *obj1 == *obj2); 285 | 286 | return 1; 287 | } 288 | }; 289 | -------------------------------------------------------------------------------- /c_function_to_extend_lua.c: -------------------------------------------------------------------------------- 1 | /* 2 | define some c function to extend lua script 3 | */ 4 | 5 | #include 6 | 7 | #include "lua.h" 8 | #include "lauxlib.h" 9 | #include "c_function_to_extend_lua.h" 10 | 11 | int l_sin(lua_State *L) 12 | { 13 | double d = luaL_checknumber(L,1); 14 | lua_pushnumber(L,sin(d)); 15 | 16 | return 1; 17 | } 18 | 19 | int l_dir(lua_State *L) 20 | { 21 | return 1; 22 | } 23 | -------------------------------------------------------------------------------- /c_function_to_extend_lua.h: -------------------------------------------------------------------------------- 1 | #ifndef c_function_to_extend_lua_h 2 | #define c_function_to_extend_lua_h 3 | 4 | int l_sin(lua_State *L); 5 | 6 | int l_dir(lua_State *L); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /c_module_to_extend_lua.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaximusZhou/InspectLua/568e6928f9e845bd5bb5a6de68970c500dc9b8c0/c_module_to_extend_lua.c -------------------------------------------------------------------------------- /c_userdata_to_extend_lua.c: -------------------------------------------------------------------------------- 1 | /* 2 | Example: 3 | 4 | Analyse: 5 | */ 6 | 7 | #include 8 | 9 | #include "lua.h" 10 | #include "lauxlib.h" 11 | #include "lualib.h" 12 | 13 | #define BITS_PER_WORD (CHAR_BIT * sizeof(unsigned int)) 14 | #define I_WORD(i) ((unsigned int)(i)/BITS_PER_WORD) 15 | #define I_BIT(i) (1 << ((unsigned int)(i)%BITS_PER_WORD)) 16 | 17 | #define UDATA_MTABLE_NAME "MyArray" 18 | #define checkarray(L) (NumArray*)luaL_checkudata(L,1,UDATA_MTABLE_NAME) 19 | 20 | 21 | typedef struct NumArray 22 | { 23 | int size; 24 | unsigned int values[1]; 25 | }NumArray; 26 | 27 | static int newarray(lua_State *L) 28 | { 29 | int i,n; 30 | size_t nbytes; 31 | NumArray *a; 32 | 33 | n = luaL_checkint(L,1); 34 | luaL_argcheck(L,n>=1,1,"invalid size"); 35 | 36 | nbytes = sizeof(NumArray) + I_WORD(n - 1) * sizeof(unsigned int); 37 | 38 | a = (NumArray*)lua_newuserdata(L,nbytes); 39 | 40 | a->size = n; 41 | for (i = 0; i <=I_WORD(n - 1); i++) 42 | a->values[i] = 0; 43 | 44 | /*set metatable for userdata*/ 45 | luaL_getmetatable(L,UDATA_MTABLE_NAME); 46 | lua_setmetatable(L,-2); 47 | 48 | return 1; /*new userdata in stack top*/ 49 | } 50 | 51 | static unsigned int *getindex(lua_State *L,unsigned int *mask) 52 | { 53 | NumArray *a = checkarray(L); 54 | int index = luaL_checkint(L,2) - 1; 55 | 56 | luaL_argcheck(L,(index >= 0 && index < a->size),1,"index out of range"); 57 | 58 | /*return*/ 59 | *mask = I_BIT(index); 60 | return &(a->values[I_WORD(index)]); 61 | } 62 | 63 | static int setarray(lua_State *L) 64 | { 65 | unsigned int mask; 66 | unsigned int *entry = getindex(L,&mask); 67 | luaL_checkany(L,3); /*ensure have a parameter*/ 68 | 69 | if(lua_toboolean(L,3)) 70 | (*entry) |= mask; 71 | else 72 | (*entry) &= (~mask); 73 | 74 | return 0; 75 | } 76 | 77 | static int getarray(lua_State *L) 78 | { 79 | unsigned int mask; 80 | unsigned int *entry = getindex(L,&mask); 81 | 82 | lua_pushboolean(L,(*entry) & mask); 83 | 84 | return 1; 85 | } 86 | 87 | static int getsize(lua_State *L) 88 | { 89 | NumArray *a = checkarray(L); 90 | luaL_argcheck(L,a != NULL,1,"bit array expected"); 91 | 92 | lua_pushinteger(L,a->size); 93 | 94 | return 1; 95 | } 96 | 97 | static int array2string(lua_State *L) 98 | { 99 | NumArray *a = checkarray(L); 100 | luaL_argcheck(L,a != NULL,1,"bit array expected"); 101 | 102 | lua_pushfstring(L,"array(%d)",a->size); 103 | 104 | return 1; 105 | } 106 | 107 | static const struct luaL_Reg arraylib_f[] = { 108 | {"new",newarray}, 109 | {NULL,NULL}, 110 | }; 111 | 112 | static const struct luaL_Reg arraylib_m[] = { 113 | {"set",setarray}, 114 | {"get",getarray}, 115 | {"size",getsize}, 116 | {"__tostring",array2string}, 117 | {NULL,NULL}, 118 | }; 119 | 120 | int luaopen_arraylib(lua_State *L) 121 | { 122 | luaL_newmetatable(L,UDATA_MTABLE_NAME); 123 | 124 | /*metatable.__index = metatable*/ 125 | lua_pushvalue(L,-1); 126 | lua_setfield(L,-2,"__index"); 127 | 128 | /*save interface in metatable*/ 129 | luaL_register(L,NULL,arraylib_m); 130 | 131 | luaL_register(L,"array",arraylib_f); 132 | return 1; 133 | } 134 | -------------------------------------------------------------------------------- /c_userdata_with_gc_to_extend_lua.c: -------------------------------------------------------------------------------- 1 | /* 2 | Example: 3 | 4 | Analyse: 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include "lua.h" 11 | #include "lauxlib.h" 12 | #include "lualib.h" 13 | 14 | #define DIRUDATA_MTABLE_NAME "MYDIR" 15 | 16 | static int dir_iter(lua_State*L) 17 | { 18 | DIR *d = *(DIR**)lua_touserdata(L,lua_upvalueindex(1)); 19 | struct dirent *entry; 20 | 21 | if((entry = readdir(d)) != NULL) 22 | { 23 | lua_pushstring(L,entry->d_name); 24 | return 1; 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | static int l_dir(lua_State *L) 31 | { 32 | const char *path = luaL_checkstring(L,1); 33 | 34 | size_t nbytes = sizeof(DIR*); 35 | DIR **d = (DIR**)lua_newuserdata(L,nbytes); 36 | 37 | luaL_getmetatable(L,DIRUDATA_MTABLE_NAME); 38 | lua_setmetatable(L,-2); 39 | 40 | *d = opendir(path); 41 | if (*d == NULL) 42 | luaL_error(L,"cannot open %s,%s",path,strerror(errno)); 43 | 44 | lua_pushcclosure(L,dir_iter,1); 45 | 46 | return 1; 47 | } 48 | 49 | static int dir_gc(lua_State *L) 50 | { 51 | DIR *d = *(DIR**)lua_touserdata(L,lua_upvalueindex(1)); 52 | if (d) 53 | closedir(d); 54 | 55 | return 0; 56 | } 57 | 58 | int luaopen_dir(lua_State *L) 59 | { 60 | luaL_newmetatable(L,DIRUDATA_MTABLE_NAME); 61 | 62 | /*set __gc value*/ 63 | lua_pushstring(L,"__gc"); 64 | lua_pushcfunction(L,dir_gc); 65 | lua_settable(L,-3); 66 | 67 | /*register c function*/ 68 | lua_pushcfunction(L,l_dir); 69 | lua_setglobal(L,"dir"); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /capi_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Example: 4 | $gcc -Wall capi_example.c -llua -lm -ldl -o capi_example 5 | $./capi_example 6 | true 10 nil 'hello' 7 | true 10 nil 'hello' true 8 | true 10 true 'hello' 9 | true 10 true 'hello' nil nil 10 | true 10 true nil nil 11 | true 12 | 13 | Analyse: 14 | 15 | */ 16 | #include 17 | #include "lua.h" 18 | #include "lauxlib.h" 19 | 20 | static void stack_dump(lua_State *L) 21 | { 22 | int i; 23 | int top = lua_gettop(L); 24 | for(i = 1; i <= top; i ++) 25 | { 26 | int t = lua_type(L,i); 27 | switch(t){ 28 | case LUA_TSTRING: 29 | { 30 | printf("'%s'",lua_tostring(L,i)); 31 | break; 32 | } 33 | 34 | case LUA_TBOOLEAN: 35 | { 36 | printf(lua_toboolean(L,i) ? "true":"false"); 37 | break; 38 | } 39 | 40 | case LUA_TNUMBER: 41 | { 42 | printf("%g",lua_tonumber(L,i)); 43 | break; 44 | } 45 | 46 | default: 47 | { 48 | printf("%s",lua_typename(L,t)); 49 | break; 50 | } 51 | } 52 | printf(" "); 53 | } 54 | printf("\n"); 55 | } 56 | 57 | int main(void) 58 | { 59 | lua_State *L = luaL_newstate(); 60 | 61 | lua_pushboolean(L,1); 62 | lua_pushnumber(L,10); 63 | lua_pushnil(L); 64 | lua_pushstring(L,"hello"); 65 | stack_dump(L); 66 | 67 | lua_pushvalue(L,-4); 68 | stack_dump(L); 69 | 70 | lua_replace(L,3); 71 | stack_dump(L); 72 | 73 | lua_settop(L,6); 74 | stack_dump(L); 75 | 76 | lua_remove(L,-3); 77 | stack_dump(L); 78 | 79 | lua_settop(L,-5); 80 | stack_dump(L); 81 | 82 | lua_close(L); 83 | 84 | return 0; 85 | 86 | } 87 | -------------------------------------------------------------------------------- /extend_c_app_by_lua.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Example: 4 | $gcc -Wall extend_c_app_by_lua.c -llua -lm -ldl -o extend_c_app_by_lua 5 | $./extend_c_app_by_lua 6 | stack size = 0 7 | w=10,h=20 8 | r=76,g=25,b=0 9 | result=0.239713 10 | 11 | Analyse: 12 | 13 | */ 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "lua.h" 20 | #include "lauxlib.h" 21 | #include "lualib.h" 22 | 23 | #define MAX_COLOR 255 24 | 25 | static char *fname = "TestConfig.lua"; 26 | 27 | struct ColorTable{ 28 | char *name; 29 | unsigned char red,green,blue; 30 | }colortable[] = { 31 | {"WHITE",MAX_COLOR,MAX_COLOR,MAX_COLOR}, 32 | {"RED",MAX_COLOR,0,0}, 33 | {"GREEN",0,MAX_COLOR,0}, 34 | {"BLUE",0,0,MAX_COLOR}, 35 | {NULL,0,0,0}, 36 | }; 37 | 38 | 39 | void error(lua_State *L, const char *fmt, ...) 40 | { 41 | va_list argp; 42 | va_start(argp,fmt); 43 | 44 | vfprintf(stderr,fmt,argp); 45 | 46 | va_end(argp); 47 | lua_close(L); 48 | exit(EXIT_FAILURE); 49 | } 50 | 51 | void load(lua_State *L, const char *file_name) 52 | { 53 | if ((luaL_loadfile(L,file_name)) || (lua_pcall(L,0,0,0))) 54 | error(L,"cannot run config. file:%s\n",lua_tostring(L,-1)); 55 | } 56 | 57 | void get_globar_var(lua_State *L, int *w,int *h) 58 | { 59 | /*push global var in stack*/ 60 | lua_getglobal(L,"width"); 61 | lua_getglobal(L,"height"); 62 | 63 | if (!lua_isnumber(L,-2)) 64 | error(L,"width should be a number\n"); 65 | 66 | if (!lua_isnumber(L,-1)) 67 | error(L,"height should be a number\n"); 68 | 69 | *w = lua_tonumber(L,-2); 70 | *h = lua_tonumber(L,-1); 71 | } 72 | 73 | /*use global var in c*/ 74 | void test_global_var(lua_State *L) 75 | { 76 | int w = 0,h = 0; 77 | 78 | get_globar_var(L,&w,&h); 79 | 80 | printf("w=%d,h=%d\n",w,h); /*w=10,h=20*/ 81 | 82 | } 83 | 84 | /*get field from table in stack top*/ 85 | static int getfield(lua_State *L, const char *key) 86 | { 87 | int result; 88 | 89 | if(!lua_istable(L,-1)) 90 | error(L,"the element in stack top is not a table in get key %s\n",key); 91 | 92 | /*next two lines can be replaced by lua_getfield(L,-1,key)*/ 93 | lua_pushstring(L,key); 94 | lua_gettable(L,-2); 95 | 96 | if(!lua_isnumber(L,-1)) 97 | error(L,"invalid component in background color"); 98 | 99 | result = (int)(lua_tonumber(L,-1) * MAX_COLOR); 100 | lua_pop(L,1); /* lua_pop(L,n) == lua_settop(L, -(n)-1)*/ 101 | 102 | return result; 103 | } 104 | 105 | /*use table in c*/ 106 | void test_table(lua_State *L) 107 | { 108 | int red,green,blue; 109 | lua_getglobal(L,"background"); 110 | if (lua_isstring(L,-1)) 111 | { 112 | const char *colorname = lua_tostring(L,-1); 113 | int i ; 114 | for(i = 0; colortable[i].name != NULL; i++) 115 | if (strcmp(colortable[i].name,colorname) == 0) 116 | break; 117 | 118 | if (colortable[i].name == NULL) 119 | error(L,"invaild color name (%s)",colorname); 120 | else 121 | { 122 | red = colortable[i].red; 123 | green = colortable[i].green; 124 | blue = colortable[i].blue; 125 | } 126 | } 127 | else if(lua_istable(L,-1)) 128 | { 129 | red = getfield(L,"r"); 130 | green = getfield(L,"g"); 131 | blue = getfield(L,"b"); 132 | } 133 | else 134 | error(L,"invaild value for 'background'"); 135 | 136 | printf("r=%d,g=%d,b=%d\n",red,green,blue); 137 | } 138 | 139 | 140 | /*use lua function in c*/ 141 | void test_lua_function(lua_State *L) 142 | { 143 | double x = 0.5, y = 0.5; 144 | double result; 145 | 146 | lua_getglobal(L,"f"); /*push f function in stack*/ 147 | 148 | lua_pushnumber(L,x); /*push two parameter */ 149 | lua_pushnumber(L,y); 150 | 151 | if(lua_pcall(L,2,1,0) != 0) 152 | error(L,"error running function 'f':%s\n",lua_tostring(L,-1)); 153 | 154 | if (!lua_isnumber(L,-1)) 155 | error(L,"function 'f' must be return number\n"); 156 | 157 | result = lua_tonumber(L,-1); 158 | printf("result=%g\n",result); /*result=0.239713*/ 159 | } 160 | int main(void) 161 | { 162 | lua_State *L = luaL_newstate(); 163 | load(L,fname); /*load confile file*/ 164 | printf("stack size = %d\n",lua_gettop(L)); /*stack size = 0*/ 165 | 166 | lua_settop(L,0); /*clear stack*/ 167 | test_global_var(L); /*test TestConfig.lua*/ 168 | 169 | lua_settop(L,0); /*clear stack*/ 170 | test_table(L); 171 | 172 | lua_settop(L,0); /*clear stack*/ 173 | luaL_openlibs(L); 174 | test_lua_function(L); 175 | 176 | return 0; 177 | } 178 | -------------------------------------------------------------------------------- /lua_class.lua: -------------------------------------------------------------------------------- 1 | 2 | --Get Parent Class 3 | function Super(Class) 4 | return getmetatable(Class).__index 5 | end 6 | 7 | --if clsSub is clsAncestor subcalss 8 | function IsSub(clsSub, clsAncestor) 9 | local Temp = clsSub 10 | while 1 do 11 | local mt = getmetatable(Temp) 12 | if mt then 13 | Temp = mt.__index 14 | if Temp == clsAncestor then 15 | return true 16 | end 17 | else 18 | return false 19 | end 20 | end 21 | end 22 | 23 | clsObject = { 24 | __ClassType = "class type" --identifying table is class, Not object 25 | } 26 | 27 | function clsObject:Inherit(o) 28 | o = o or {} 29 | o.__ClassType = "class type" 30 | o.mt = { __index = o} 31 | setmetatable(o, {__index = self}) 32 | return o 33 | end 34 | 35 | 36 | function clsObject:New(...) 37 | local o = {} 38 | 39 | setmetatable(o, self.mt) 40 | 41 | if o.__init__ then 42 | o:__init__(...) 43 | end 44 | return o 45 | end 46 | 47 | function clsObject:__init__() 48 | end 49 | 50 | function clsObject:Destroy() 51 | end 52 | 53 | function clsObject:GetType() 54 | return "BaseClass" 55 | end 56 | -------------------------------------------------------------------------------- /lua_hot_fix.lua: -------------------------------------------------------------------------------- 1 | _G.LoadModule = _G.LoadModule or {} 2 | local LoadModule = _G.LoadModule 3 | 4 | local function ReplaceTbl(Dest, Src) 5 | local function RealFun(Dest, Src, Depth) 6 | assert(type(Dest)=="table" and type(Src)=="table", 7 | "error data type") 8 | 9 | if not Depth then 10 | Depth = 0 11 | end 12 | if Depth>=20 then 13 | error("too long Depth to replace") 14 | return 15 | end 16 | 17 | for k,v in pairs(Dest) do 18 | if type(v) == "table" then 19 | if type(Src[k]) == "table" and 20 | k ~="__index" then 21 | RealFun(v, Src[k], Depth+1) 22 | else 23 | Dest[k] = Src[k] 24 | end 25 | 26 | else 27 | Dest[k] = Src[k] 28 | end 29 | end 30 | 31 | --add new data or function 32 | for k,v in pairs(Src) do 33 | if rawget(Dest, k) == nil then 34 | Dest[k] = v 35 | end 36 | end 37 | 38 | 39 | setmetatable(Dest, getmetatable(Src)) 40 | end 41 | RealFun(Dest, Src) 42 | end 43 | 44 | local function Update(PathFile, Reload) 45 | 46 | local Old = LoadModule[PathFile] 47 | if Old and not Reload then 48 | return Old 49 | end 50 | 51 | local func, err = loadfile(PathFile) 52 | if not func then 53 | return func, err 54 | end 55 | 56 | --first update 57 | if not Old then 58 | LoadModule[PathFile] = {} 59 | local New = LoadModule[PathFile] 60 | setmetatable(New, {__index = _G}) 61 | setfenv(func, New)() 62 | return New 63 | end 64 | 65 | local OldCache = {} 66 | for k,v in pairs(Old) do 67 | OldCache[k] = v 68 | Old[k] = nil 69 | end 70 | 71 | --change in modue inplace!! 72 | setfenv(func, Old)() 73 | 74 | for k,v in pairs(OldCache) do 75 | local TmpNewData = Old[k] 76 | 77 | Old[k] = v --default value is old value 78 | if TmpNewData then 79 | if type(v) == "table" then 80 | if type(TmpNewData) == "table" then 81 | if rawget(v,"__ClassType") then --if table is classtype, Update! 82 | local mt = getmetatable(v) 83 | local old_mt = v.mt 84 | local index = old_mt.__index 85 | ReplaceTbl(v, TmpNewData) --Notice: change directly table v to ensure reference v rightly for others var 86 | v.mt = old_mt 87 | old_mt.__index = index 88 | end 89 | local mt = getmetatable(TmpNewData) 90 | if mt then setmetatable(v, mt) end 91 | end 92 | --update function 93 | elseif type(v) == "function" then 94 | Old[k] = TmpNewData 95 | end 96 | end 97 | end 98 | 99 | return Old 100 | end 101 | -------------------------------------------------------------------------------- /lunar.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Luanr is used to provide access to C++ classes from within Lua. 3 | Lunar(http://lua-users.org/wiki/CppBindingWithLunar) is an improved 4 | version of Luna(http://lua-users.org/wiki/LunaFive) 5 | */ 6 | 7 | extern "C" { 8 | #include "lua.h" 9 | #include "lauxlib.h" 10 | } 11 | 12 | template class Lunar { 13 | 14 | typedef struct { T *pT; } userdataType; 15 | 16 | public: 17 | 18 | typedef int (T::*mfp)(lua_State *L); 19 | typedef struct { const char *name; mfp mfunc; } RegType; 20 | 21 | static void Register(lua_State *L) { 22 | lua_newtable(L); 23 | int methods = lua_gettop(L); 24 | 25 | luaL_newmetatable(L, T::className); 26 | int metatable = lua_gettop(L); 27 | 28 | // store method table in globals so that 29 | // scripts can add functions written in Lua. 30 | lua_pushvalue(L, methods); 31 | set(L, LUA_GLOBALSINDEX, T::className); 32 | 33 | // hide metatable from Lua getmetatable() 34 | lua_pushvalue(L, methods); 35 | set(L, metatable, "__metatable"); 36 | 37 | lua_pushvalue(L, methods); 38 | set(L, metatable, "__index"); 39 | 40 | lua_pushcfunction(L, tostring_T); 41 | set(L, metatable, "__tostring"); 42 | 43 | lua_pushcfunction(L, gc_T); 44 | set(L, metatable, "__gc"); 45 | 46 | lua_newtable(L); // mt for method table 47 | lua_pushcfunction(L, new_T); 48 | lua_pushvalue(L, -1); // dup new_T function 49 | set(L, methods, "new"); // add new_T to method table 50 | set(L, -3, "__call"); // mt.__call = new_T 51 | lua_setmetatable(L, methods); 52 | 53 | // fill method table with methods from class T 54 | for (RegType *l = T::methods; l->name; l++) { 55 | lua_pushstring(L, l->name); 56 | lua_pushlightuserdata(L, (void*)l); 57 | lua_pushcclosure(L, thunk, 1); 58 | lua_settable(L, methods); 59 | } 60 | 61 | lua_pop(L, 2); // drop metatable and method table 62 | } 63 | 64 | // call named lua method from userdata method table 65 | static int call(lua_State *L, const char *method, 66 | int nargs=0, int nresults=LUA_MULTRET, int errfunc=0) 67 | { 68 | int base = lua_gettop(L) - nargs; // userdata index 69 | if (!luaL_checkudata(L, base, T::className)) { 70 | lua_settop(L, base-1); // drop userdata and args 71 | lua_pushfstring(L, "not a valid %s userdata", T::className); 72 | return -1; 73 | } 74 | 75 | lua_pushstring(L, method); // method name 76 | lua_gettable(L, base); // get method from userdata 77 | if (lua_isnil(L, -1)) { // no method? 78 | lua_settop(L, base-1); // drop userdata and args 79 | lua_pushfstring(L, "%s missing method '%s'", T::className, method); 80 | return -1; 81 | } 82 | lua_insert(L, base); // put method under userdata, args 83 | 84 | int status = lua_pcall(L, 1+nargs, nresults, errfunc); // call method 85 | if (status) { 86 | const char *msg = lua_tostring(L, -1); 87 | if (msg == NULL) msg = "(error with no message)"; 88 | lua_pushfstring(L, "%s:%s status = %d\n%s", 89 | T::className, method, status, msg); 90 | lua_remove(L, base); // remove old message 91 | return -1; 92 | } 93 | return lua_gettop(L) - base + 1; // number of results 94 | } 95 | 96 | // push onto the Lua stack a userdata containing a pointer to T object 97 | static int push(lua_State *L, T *obj, bool gc=false) { 98 | if (!obj) { lua_pushnil(L); return 0; } 99 | luaL_getmetatable(L, T::className); // lookup metatable in Lua registry 100 | if (lua_isnil(L, -1)) luaL_error(L, "%s missing metatable", T::className); 101 | int mt = lua_gettop(L); 102 | subtable(L, mt, "userdata", "v"); 103 | userdataType *ud = 104 | static_cast(pushuserdata(L, obj, sizeof(userdataType))); 105 | if (ud) { 106 | ud->pT = obj; // store pointer to object in userdata 107 | lua_pushvalue(L, mt); 108 | lua_setmetatable(L, -2); 109 | if (gc == false) { 110 | lua_checkstack(L, 3); 111 | subtable(L, mt, "do not trash", "k"); 112 | lua_pushvalue(L, -2); 113 | lua_pushboolean(L, 1); 114 | lua_settable(L, -3); 115 | lua_pop(L, 1); 116 | } 117 | } 118 | lua_replace(L, mt); 119 | lua_settop(L, mt); 120 | return mt; // index of userdata containing pointer to T object 121 | } 122 | 123 | // get userdata from Lua stack and return pointer to T object 124 | static T *check(lua_State *L, int narg) { 125 | userdataType *ud = 126 | static_cast(luaL_checkudata(L, narg, T::className)); 127 | if(!ud) { 128 | luaL_typerror(L, narg, T::className); 129 | return NULL; 130 | } 131 | return ud->pT; // pointer to T object 132 | } 133 | 134 | private: 135 | Lunar(); // hide default constructor 136 | 137 | // member function dispatcher 138 | static int thunk(lua_State *L) { 139 | // stack has userdata, followed by method args 140 | T *obj = check(L, 1); // get 'self', or if you prefer, 'this' 141 | lua_remove(L, 1); // remove self so member function args start at index 1 142 | // get member function from upvalue 143 | RegType *l = static_cast(lua_touserdata(L, lua_upvalueindex(1))); 144 | return (obj->*(l->mfunc))(L); // call member function 145 | } 146 | 147 | // create a new T object and 148 | // push onto the Lua stack a userdata containing a pointer to T object 149 | static int new_T(lua_State *L) { 150 | lua_remove(L, 1); // use classname:new(), instead of classname.new() 151 | T *obj = new T(L); // call constructor for T objects 152 | push(L, obj, true); // gc_T will delete this object 153 | return 1; // userdata containing pointer to T object 154 | } 155 | 156 | // garbage collection metamethod 157 | static int gc_T(lua_State *L) { 158 | if (luaL_getmetafield(L, 1, "do not trash")) { 159 | lua_pushvalue(L, 1); // dup userdata 160 | lua_gettable(L, -2); 161 | if (!lua_isnil(L, -1)) return 0; // do not delete object 162 | } 163 | userdataType *ud = static_cast(lua_touserdata(L, 1)); 164 | T *obj = ud->pT; 165 | if (obj) delete obj; // call destructor for T objects 166 | return 0; 167 | } 168 | 169 | static int tostring_T (lua_State *L) { 170 | char buff[32]; 171 | userdataType *ud = static_cast(lua_touserdata(L, 1)); 172 | T *obj = ud->pT; 173 | sprintf(buff, "%p", (void*)obj); 174 | lua_pushfstring(L, "%s (%s)", T::className, buff); 175 | 176 | return 1; 177 | } 178 | 179 | static void set(lua_State *L, int table_index, const char *key) { 180 | lua_pushstring(L, key); 181 | lua_insert(L, -2); // swap value and key 182 | lua_settable(L, table_index); 183 | } 184 | 185 | static void weaktable(lua_State *L, const char *mode) { 186 | lua_newtable(L); 187 | lua_pushvalue(L, -1); // table is its own metatable 188 | lua_setmetatable(L, -2); 189 | lua_pushliteral(L, "__mode"); 190 | lua_pushstring(L, mode); 191 | lua_settable(L, -3); // metatable.__mode = mode 192 | } 193 | 194 | static void subtable(lua_State *L, int tindex, const char *name, const char *mode) { 195 | lua_pushstring(L, name); 196 | lua_gettable(L, tindex); 197 | if (lua_isnil(L, -1)) { 198 | lua_pop(L, 1); 199 | lua_checkstack(L, 3); 200 | weaktable(L, mode); 201 | lua_pushstring(L, name); 202 | lua_pushvalue(L, -2); 203 | lua_settable(L, tindex); 204 | } 205 | } 206 | 207 | static void *pushuserdata(lua_State *L, void *key, size_t sz) { 208 | void *ud = 0; 209 | lua_pushlightuserdata(L, key); 210 | lua_gettable(L, -2); // lookup[key] 211 | if (lua_isnil(L, -1)) { 212 | lua_pop(L, 1); // drop nil 213 | lua_checkstack(L, 3); 214 | ud = lua_newuserdata(L, sz); // create new userdata 215 | lua_pushlightuserdata(L, key); 216 | lua_pushvalue(L, -2); // dup userdata 217 | lua_settable(L, -4); // lookup[key] = userdata 218 | } 219 | return ud; 220 | } 221 | }; 222 | 223 | #define LUNAR_DECLARE_METHOD(Class, Name) {#Name, &Class::Name} 224 | -------------------------------------------------------------------------------- /lunar_test_main.cpp: -------------------------------------------------------------------------------- 1 | //g++ -o lunar_test_main lunar_test_main.cpp -llua -lm -ldl 2 | extern "C" { 3 | #include "lua.h" 4 | #include "lauxlib.h" 5 | #include "lualib.h" 6 | } 7 | 8 | #include "lunar.hpp" 9 | 10 | class Account { 11 | public: 12 | Account(double balance=0) : m_balance(balance) { } 13 | void deposit(double amount) { m_balance += amount; } 14 | void withdraw(double amount) { m_balance -= amount; } 15 | double balance(void) { return m_balance; } 16 | ~Account() { printf("deleted Account (%p)\n", this); } 17 | 18 | // Lua interface 19 | Account(lua_State *L) : m_balance(luaL_checknumber(L, 1)) { } 20 | int deposit (lua_State *L) { deposit (luaL_checknumber(L, 1)); return 0; } 21 | int withdraw(lua_State *L) { withdraw(luaL_checknumber(L, 1)); return 0; } 22 | int balance (lua_State *L) { lua_pushnumber(L, balance()); return 1; } 23 | 24 | static const char className[]; 25 | static Lunar::RegType methods[]; 26 | 27 | private: 28 | lua_Number m_balance; 29 | }; 30 | 31 | const char Account::className[] = "Account"; 32 | 33 | #define method(class, name) {#name, &class::name} 34 | 35 | Lunar::RegType Account::methods[] = { 36 | method(Account, deposit), 37 | method(Account, withdraw), 38 | method(Account, balance), 39 | {0,0} 40 | }; 41 | 42 | static int report (lua_State *L, int status) 43 | { 44 | if (status) { 45 | const char *msg = lua_tostring(L, -1); 46 | if (msg == NULL) msg = "(error with no message)"; 47 | fprintf(stderr, "ERROR: %s\n", msg); 48 | lua_pop(L, 1); 49 | } 50 | return status; 51 | } 52 | 53 | static int application (lua_State *L) 54 | { 55 | lua_settop(L, 0); 56 | lua_pushliteral(L, "_TRACEBACK"); 57 | lua_gettable(L, LUA_GLOBALSINDEX); // get traceback function 58 | int tb = lua_gettop(L); 59 | 60 | Account a; 61 | Account *b = new Account(30); 62 | 63 | int A = Lunar::push(L, &a); 64 | int B = Lunar::push(L, b, true); 65 | 66 | lua_pushliteral(L, "a"); 67 | lua_pushvalue(L, A); 68 | lua_settable(L, LUA_GLOBALSINDEX); 69 | 70 | lua_pushliteral(L, "b"); 71 | lua_pushvalue(L, B); 72 | lua_settable(L, LUA_GLOBALSINDEX); 73 | 74 | lua_pushvalue(L, A); 75 | lua_pushnumber(L, 100.00); 76 | report(L, Lunar::call(L, "deposit", 1, 0, tb) < 0); 77 | lua_pushvalue(L, A); 78 | report(L, Lunar::call(L, "show", 0, 0, tb) < 0); 79 | lua_pushvalue(L, B); 80 | report(L, Lunar::call(L, "show", 0, 0, tb) < 0); 81 | 82 | lua_pushliteral(L, "main"); 83 | lua_gettable(L, LUA_GLOBALSINDEX); 84 | report(L, lua_pcall(L, 0, 0, tb)); 85 | 86 | lua_getglobal(L,"script_obj1"); 87 | lua_pushnumber(L, 100.00); 88 | report(L, Lunar::call(L, "deposit", 1, 0, tb) < 0); 89 | 90 | printf("script_obj1:"); 91 | lua_getglobal(L,"script_obj1"); 92 | report(L, Lunar::call(L, "show", 0, 0, tb) < 0); 93 | 94 | return 0; 95 | } 96 | 97 | int main (int argc, char *argv[]) 98 | { 99 | lua_State *L = luaL_newstate(); 100 | 101 | luaL_openlibs(L); 102 | 103 | Lunar::Register(L); 104 | 105 | if (argc>1) { 106 | printf("loading '%s'\n", argv[1]); 107 | if (report(L, luaL_loadfile(L, argv[1]) || lua_pcall(L, 0, 0, 0)) == 0) { 108 | printf("running application\n"); 109 | if (report(L, lua_cpcall(L, &application, 0)) == 0) { 110 | printf("okay\n"); 111 | } 112 | } 113 | } 114 | 115 | lua_gc(L,LUA_GCRESTART,0); 116 | printf("close\n"); 117 | lua_close(L); 118 | printf("done\n"); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /lunar_test_script.lua: -------------------------------------------------------------------------------- 1 | function printf(...) 2 | io.write(string.format(unpack(arg))) 3 | end 4 | 5 | --expand the metatable Account,it is metatable of all instance of registed class 6 | function Account:show() 7 | printf("Account balance = $%0.02f\n", self:balance()) 8 | end 9 | 10 | parent = {} 11 | 12 | function parent:rob(amount) 13 | amount = amount or self:balance() 14 | self:withdraw(amount) 15 | return amount 16 | end 17 | 18 | getmetatable(Account).__index = parent 19 | 20 | function main() 21 | print('a =', a) 22 | print('b =', b) 23 | print('metatable =', getmetatable(a))-- the metatable of a is Account,Not metatable table 24 | print('Account =', Account) 25 | table.foreach(Account, print) 26 | 27 | a:show() a:deposit(50.30) a:show() a:withdraw(25.10) a:show() 28 | a:rob(10) a:show() 29 | --debug.debug() 30 | end 31 | 32 | --script_obj = Account() --error:bad argument #1 to 'Account' (number expected, got no value) 33 | script_obj1 = Account(10) 34 | script_obj2 = Account:new(20) 35 | 36 | print("script_obj1 = ",script_obj1) 37 | print("script_obj2 = ",script_obj2) 38 | -------------------------------------------------------------------------------- /permutation_by_coroutine.lua: -------------------------------------------------------------------------------- 1 | ------------------------------------------------- 2 | --Generate all permutation by coroutine 3 | ------------------------------------------------- 4 | 5 | function print_array(t) 6 | for _,value in ipairs( t or {}) do 7 | io.write(value," ") 8 | end 9 | io.write("\n") 10 | end 11 | 12 | function genpermu(t,n) 13 | n = n or #t 14 | if n <= 1 then 15 | coroutine.yield(t) 16 | else 17 | for i =n,1,-1 do 18 | t[i],t[n] = t[n],t[i] 19 | genpermu(t,n-1) 20 | t[i],t[n] = t[n],t[i] 21 | end 22 | end 23 | end 24 | 25 | function permutations(a) 26 | local co = coroutine.create(function() genpermu(a) end) 27 | return function() 28 | local code,res = coroutine.resume(co) 29 | return res 30 | end 31 | end 32 | 33 | for p in permutations({"a","b","c"}) do 34 | print_array(p) 35 | end 36 | -------------------------------------------------------------------------------- /simple_lua_interpreter.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Example: 4 | $gcc -Wall simple_lua_interpreter.c -llua -lm -ldl -o simple_lua_interpreter 5 | 6 | Analyse: 7 | http://stackoverflow.com/questions/4743233/is-usr-local-lib-searched-for-shared-libraries: About /usr/local/lib 8 | http://fangmenghu.blog.163.com/blog/static/124582020104171451565/: About /lib,/usr/lib and /usr/local/lib 9 | https://erex.sinaapp.com/?p=126: About compile search path 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | #include "lauxlib.h" 17 | #include "lualib.h" //for luaL_openlibs 18 | 19 | int main(void) 20 | { 21 | char buf[256]; 22 | int error; 23 | lua_State *L = luaL_newstate(); 24 | luaL_openlibs(L); 25 | 26 | while(fgets(buf,sizeof(buf),stdin) != NULL) 27 | { 28 | error = luaL_loadbuffer(L,buf,strlen(buf),"line") || lua_pcall(L,0,0,0); 29 | 30 | if(error) 31 | { 32 | fprintf(stderr,"%s",lua_tostring(L,-1)); 33 | lua_pop(L,1); 34 | } 35 | } 36 | lua_close(L); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /study_lua_bridge.lua: -------------------------------------------------------------------------------- 1 | -- 2 | --test Namespaces 3 | -- 4 | --print(test,test.detail,test.utility) 5 | 6 | 7 | -- 8 | --test Data, Properties, Functions, and CFunctions 9 | -- 10 | --[[ 11 | test.var1 = 5 -- okay 12 | --test.var2 = 6 -- error: var2 is not writable 13 | 14 | --test.prop1 = "Hello" -- okay 15 | --test.prop1 = 68 -- okay, Lua converts the number to a string. 16 | --test.prop2 = "bar" -- error: prop2 is not writable 17 | 18 | test.foo() -- calls foo and discards the return value 19 | test.var1 = test.foo () -- calls foo and stores the result in var1 20 | test.bar ("Employee") -- calls bar with a string 21 | --test.bar (test) -- error: bar expects a string not a table 22 | --]] 23 | 24 | 25 | -- 26 | --test Class Objects 27 | -- 28 | local AClassObj = test.A () --create class A instance 29 | 30 | print("before:",test.A.staticData) -- access class A static member 31 | test.A.staticData = 8 -- modify class A static member 32 | print("after:",test.A.staticData) 33 | 34 | print("before:", test.A.getStaticProperty()) 35 | --test.A.staticProperty = 1.2 --error:can not modify 36 | 37 | print("staticCFunc") 38 | test.A.staticCFunc() --Call the static method 39 | 40 | AClassObj.data = "sting" 41 | print("dataMember:",AClassObj.data) 42 | 43 | AClassObj.prop = 'a' 44 | print("property:",AClassObj.prop) 45 | 46 | AClassObj:func1() --Notice: NO AClassObj.func1() 47 | --test.A.func1(AClassObj) -- Equivalent to AClassObj:func1() 48 | 49 | AClassObj:virtualFunc() 50 | 51 | AClassObj:cfunc("lua_State*",42) 52 | 53 | BClassObj = test.B("constructor register",42) --First Call base class A constructor function 54 | 55 | BClassObj:func1() 56 | 57 | BClassObj:func2() 58 | 59 | BClassObj:virtualFunc() --virtualFunc In Class B 60 | 61 | print("dataMember1",a.data1) 62 | a.data1 = 32 63 | print("a dataMember1",a.data1) 64 | 65 | print("pointer ac dataMember1",ac.data1) 66 | --ac.data1 = 32 --error: because ac is registed as const 67 | 68 | print("pointer ac2 dataMember1",ac.data1) 69 | --ac2.data1 = 32 --error: because ac2 is registed as const 70 | 71 | --ap.data1 = 42 72 | --print("ap dataMember1",ap.data1) 73 | 74 | a = nil; collectgarbage () -- 'a' still exists in C++. 75 | b = nil; collectgarbage () -- Lua calls ~B() on the copy of b. 76 | 77 | -------------------------------------------------------------------------------- /study_lua_bridge_main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | study luabridge to bind cpp 3 | 4 | 5 | Example: 6 | $g++ study_lua_bridge_main.cpp -llua -lm -ldl -o study_lua_bridge_main 7 | 8 | Analyse: 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | extern "C" { 15 | #include "lua.h" 16 | #include "lualib.h" 17 | #include "lauxlib.h" 18 | } 19 | 20 | //#include "../LuaBridge/Source/LuaBridge/LuaBridge.h" 21 | #include "./LuaBridge/LuaBridge.h" 22 | 23 | using namespace luabridge; 24 | 25 | void load(lua_State *L, const char *file_name) 26 | { 27 | if ((luaL_loadfile(L,file_name)) || (lua_pcall(L,0,0,0))) 28 | printf("cannot run config file:%s\n",lua_tostring(L,-1)); 29 | } 30 | 31 | int globalVar; 32 | static float staticVar; 33 | 34 | /* 35 | std::string stringProperty; 36 | std::string getString () { return stringProperty; } 37 | void setString (std::string s) { stringProperty = s; } 38 | */ 39 | 40 | int foo () { return 42; } 41 | void bar (char const* var) {printf("in function bar,var=%s\n",var); } 42 | int cFunc (lua_State* L) { return 0; } 43 | 44 | 45 | class A { 46 | public: 47 | A() { printf("A constructor\n");} 48 | ~A() { printf("A destructor\n");} 49 | 50 | static int staticData; 51 | static int getStaticData() {return staticData;} 52 | 53 | static float staticProperty; 54 | static float getStaticProperty () { return staticProperty; } 55 | static void setStaticProperty (float f) { staticProperty = f; } 56 | 57 | 58 | static int staticCFunc (lua_State *L) { return 0; } 59 | 60 | std::string dataMember; 61 | 62 | int dataMember1; 63 | 64 | char dataProperty; 65 | char getProperty () const { return dataProperty; } 66 | void setProperty (char v) { dataProperty = v; } 67 | 68 | void func1 () {printf("func1 In Class A\n"); } 69 | virtual void virtualFunc () {printf("virtualFunc In Class A\n"); } 70 | 71 | int cfunc (const char *var1,int var2,lua_State* L) 72 | { printf("cfunc In Class A:%s,%d,%d\n",var1,var2,lua_gettop(L)); return 0; } 73 | }; 74 | 75 | class B : public A { 76 | public: 77 | B(const char *s,int t) { printf("B constructor:%s,%d\n",s,t);} 78 | ~B() { printf("B destructor\n");} 79 | 80 | double dataMember2; 81 | 82 | void func1 () {printf("func1 In Class B\n"); } 83 | void func2 () { printf("func2 In Class B\n"); } 84 | void virtualFunc () {printf("virtualFunc In Class B\n"); } 85 | }; 86 | 87 | int A::staticData = 3; 88 | float A::staticProperty = 0.5; 89 | 90 | 91 | void register_by_luabridge(lua_State*L) 92 | { 93 | /*test Namespaces 94 | luabridge::getGlobalNamespace (L) 95 | .beginNamespace ("test") 96 | .beginNamespace ("detail") 97 | .endNamespace () 98 | .beginNamespace ("utility") 99 | .endNamespace () 100 | .endNamespace (); 101 | */ 102 | /*test Data, Properties, Functions, and CFunctions 103 | luabridge::getGlobalNamespace (L) 104 | .beginNamespace ("test") 105 | .addVariable ("var1", &globalVar) 106 | .addVariable ("var2", &staticVar, false) // read-only 107 | //.addProperty ("prop1", getString, setString) 108 | //.addProperty ("prop2", getString) // read-only 109 | .addFunction ("foo", foo) 110 | .addFunction ("bar", bar) 111 | .addCFunction ("cfunc", cFunc) 112 | .endNamespace (); 113 | */ 114 | 115 | getGlobalNamespace (L) 116 | .beginNamespace ("test") 117 | .beginClass
("A") 118 | .addConstructor () 119 | .addStaticData ("staticData", &A::staticData) 120 | .addStaticProperty ("staticProperty", &A::getStaticData) 121 | .addStaticFunction ("getStaticProperty", &A::getStaticProperty) //read-only 122 | .addStaticCFunction ("staticCFunc", &A::staticCFunc) 123 | .addData ("data", &A::dataMember) 124 | .addData ("data1", &A::dataMember1) 125 | .addProperty ("prop", &A::getProperty, &A::setProperty) 126 | .addFunction ("func1", &A::func1) 127 | .addFunction ("virtualFunc", &A::virtualFunc) 128 | .addFunction ("cfunc", &A::cfunc) 129 | .endClass () 130 | .deriveClass("B") 131 | .addConstructor () 132 | .addData ("data", &B::dataMember2) 133 | .addFunction ("func1", &B::func1) 134 | .addFunction ("func2", &B::func2) 135 | .endClass () 136 | .endNamespace (); 137 | 138 | 139 | //C++ lifetime 140 | A a; 141 | a.dataMember1 = 42; 142 | 143 | push (L, &a); // pointer to 'a', C++ lifetime 144 | lua_setglobal (L, "a"); 145 | 146 | push (L, (A const*)&a); // pointer to 'a const', C++ lifetime 147 | lua_setglobal (L, "ac"); 148 | 149 | push (L, &a); // equivalent to push (L, (A const*)&a) 150 | lua_setglobal (L, "ac2"); 151 | 152 | //push (L, new A); // compiles, but will leak memory, aslo C++ lifttiime 153 | //lua_setglobal (L, "ap"); 154 | 155 | B b("helloB",42); 156 | 157 | push(L,b); // Copy of b passed, Lua lifetime 158 | lua_setglobal(L,"b"); 159 | 160 | const char *fname = "study_lua_bridge.lua"; 161 | load(L,fname); /*load confile file*/ 162 | } 163 | 164 | int main(void) 165 | { 166 | 167 | lua_State *L = luaL_newstate(); 168 | luaL_openlibs(L); 169 | 170 | register_by_luabridge(L); 171 | 172 | lua_close(L); 173 | return 0; 174 | } 175 | -------------------------------------------------------------------------------- /test_binding_cpp_with_lua.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | define c++ class for lua 3 | */ 4 | 5 | #ifndef TEST_BINDING_CPP_WITH_LUA 6 | #define TEST_BINDING_CPP_WITH_LUA 7 | 8 | #include 9 | #include "binding_cpp_with_lunafive.hpp" 10 | 11 | class Foo { 12 | public: 13 | Foo(lua_State*L) { 14 | printf("in constructor\n"); 15 | } 16 | 17 | int foo(lua_State *L) { 18 | printf("in foo\n"); 19 | return 0; 20 | } 21 | 22 | int set_member(lua_State *L){ 23 | int value = luaL_checkint(L,2); 24 | member = value; 25 | return 0; 26 | } 27 | 28 | int get_member(lua_State *L) { 29 | lua_pushnumber(L,member); 30 | return 1; 31 | } 32 | 33 | 34 | int getmember(lua_State *L) { 35 | lua_pushnumber(L,member); 36 | return 1; 37 | } 38 | 39 | int setmember(lua_State *L){ 40 | int value = luaL_checkint(L,1); 41 | member = value; 42 | return 0; 43 | } 44 | 45 | 46 | ~Foo() { 47 | printf("in destructor\n"); 48 | } 49 | 50 | static const char className[]; 51 | static const Luna::FunctionType methods[]; 52 | static const Luna::PropertyType properties[]; 53 | 54 | private: 55 | int member; 56 | }; 57 | 58 | const char Foo::className[] = "Foo"; 59 | 60 | #define method(class, funcname) {#funcname, &class::funcname} 61 | const Luna::FunctionType Foo::methods[] = { 62 | method(Foo,foo), 63 | method(Foo,set_member), 64 | method(Foo,get_member), 65 | {0,0}, 66 | }; 67 | 68 | #define property(class,propertyname,getfuncname,setfuncname) \ 69 | {#propertyname,&class::getfuncname,&class::setfuncname} 70 | 71 | const Luna::PropertyType Foo::properties[] = { 72 | property(Foo,member,getmember,setmember), 73 | {0,0,0}, 74 | }; 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /test_extend_lua_by_c.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Example: 4 | $gcc -Wall test_extend_lua_by_c.c util.c c_function_to_extend_lua.c c_module_to_extend_lua.c c_userdata_to_extend_lua.c -llua -lm -ldl -o test_extend_lua_by_c 5 | $./test_extend_lua_by_c 6 | --extend lua by c function-- 7 | libsin: -0.98803162409286 8 | mysin: -0.98803162409286 9 | --extend lua by c module-- 10 | mysininmodule: -0.98803162409286 11 | i: 2 12 | i: 4 13 | i: 6 14 | --test upvalue in c function-- 15 | 10 16 | hi 17 | table: 0x1c153f0 18 | 10 hi table: 0x1c153f0 3 19 | --test userdata-- 20 | array(1000) 21 | 1000 22 | true 23 | false 24 | 25 | Analyse: 26 | 27 | */ 28 | #include 29 | 30 | #include "lua.h" 31 | #include "lauxlib.h" 32 | #include "lualib.h" 33 | #include "util.h" 34 | #include "c_function_to_extend_lua.h" 35 | 36 | int luaopen_mylib(lua_State *L); 37 | int luaopen_arraylib(lua_State *L); 38 | int luaopen_dir(lua_State *L); 39 | 40 | void open_c_func_to_extend_lua(lua_State *L) 41 | { 42 | lua_pushcfunction(L,l_sin); 43 | lua_setglobal(L,"mysin"); 44 | 45 | lua_pushcfunction(L,l_sin); 46 | 47 | /*open c module*/ 48 | luaopen_mylib(L); 49 | luaopen_arraylib(L); 50 | 51 | /*register c function to use userdata with gc*/ 52 | luaopen_dir(L); 53 | } 54 | 55 | int main(void) 56 | { 57 | char *fname = "TestLuaExtendedbyC.lua"; 58 | lua_State *L = luaL_newstate(); 59 | 60 | luaL_openlibs(L); 61 | open_c_func_to_extend_lua(L); 62 | 63 | load(L,fname); /*load confile file*/ 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /test_general_call_lua_in_c.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Example: 4 | $gcc -Wall test_general_call_lua_in_c.c util.c -llua -lm -ldl -o test_general_call_lua_in_c 5 | $./test_general_call_lua_in_c 6 | result=0.239713 7 | 8 | Analyse: 9 | 10 | */ 11 | #include 12 | 13 | #include "lua.h" 14 | #include "lauxlib.h" 15 | #include "lualib.h" 16 | #include "util.h" 17 | 18 | int main(void) 19 | { 20 | char *fname = "TestConfig.lua"; 21 | lua_State *L = luaL_newstate(); 22 | load(L,fname); /*load confile file*/ 23 | 24 | luaL_openlibs(L); 25 | 26 | double x = 0.5, y = 0.5; 27 | double result; 28 | call_va(L,"f","dd>d",x,y,&result); 29 | printf("result=%g\n",result); /*result=0.239713*/ 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /test_lua_class.lua: -------------------------------------------------------------------------------- 1 | require "lua_class" 2 | 3 | clsParent = clsObject:Inherit() 4 | 5 | function clsParent:Foo() 6 | print("ParentFoo!") 7 | end 8 | 9 | local ParentObj = clsParent:New() 10 | ParentObj:Foo() 11 | 12 | 13 | clsSon = clsParent:Inherit() 14 | function clsSon:Foo() 15 | Super(clsSon).Foo(self) 16 | print("SonFoo") 17 | end 18 | 19 | local SonObj = clsSon:Inherit() 20 | SonObj:Foo() 21 | 22 | print(IsSub(clsSon, clsParent)) 23 | print(IsSub(clsSon, clsObject)) 24 | -------------------------------------------------------------------------------- /traversal_global_env.lua: -------------------------------------------------------------------------------- 1 | --treaverse global env 2 | 3 | function treaverse_global_env(curtable,level) 4 | for key,value in pairs(curtable or {}) do 5 | local prefix = string.rep(" ",level*5) 6 | print(string.format("%s%s(%s)",prefix,key,type(value))) 7 | 8 | --notice endless loop 9 | if (type(value) == "table" ) and key ~= "_G" and (not value.package) then 10 | treaverse_global_env(value,level + 1) 11 | elseif (type(value) == "table" ) and (value.package) then 12 | print(string.format("%sSKIPTABLE:%s",prefix,key)) 13 | end 14 | end 15 | end 16 | 17 | treaverse_global_env(_G,0) 18 | 19 | print("..........test _ENV ...............") 20 | print("_G==_ENV:",_G == _ENV) -- output true 21 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | /* 2 | some useful interface 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "lua.h" 12 | #include "lauxlib.h" 13 | #include "util.h" 14 | 15 | void error(lua_State *L, const char *fmt, ...) 16 | { 17 | va_list argp; 18 | va_start(argp,fmt); 19 | 20 | vfprintf(stderr,fmt,argp); 21 | 22 | va_end(argp); 23 | lua_close(L); 24 | exit(EXIT_FAILURE); 25 | } 26 | 27 | void stack_dump(lua_State *L) 28 | { 29 | int i; 30 | int top = lua_gettop(L); 31 | for(i = 1; i <= top; i ++) 32 | { 33 | int t = lua_type(L,i); 34 | switch(t){ 35 | case LUA_TSTRING: 36 | { 37 | printf("'%s'",lua_tostring(L,i)); 38 | break; 39 | } 40 | 41 | case LUA_TBOOLEAN: 42 | { 43 | printf(lua_toboolean(L,i) ? "true":"false"); 44 | break; 45 | } 46 | 47 | case LUA_TNUMBER: 48 | { 49 | printf("%g",lua_tonumber(L,i)); 50 | break; 51 | } 52 | 53 | default: 54 | { 55 | printf("%s",lua_typename(L,t)); 56 | break; 57 | } 58 | } 59 | printf(" "); 60 | } 61 | printf("\n"); 62 | } 63 | 64 | void load(lua_State *L, const char *file_name) 65 | { 66 | if ((luaL_loadfile(L,file_name)) || (lua_pcall(L,0,0,0))) 67 | error(L,"cannot run config. file:%s\n",lua_tostring(L,-1)); 68 | } 69 | 70 | void call_va(lua_State *L,const char *funcname,const char *sig, ...) 71 | { 72 | int narg,nres; /*arg number and result number*/ 73 | bool isbreak; 74 | 75 | va_list vl; 76 | va_start(vl,sig); 77 | 78 | /*push function*/ 79 | lua_getglobal(L,funcname); 80 | 81 | /*push parameteres*/ 82 | 83 | isbreak = false; 84 | for(narg = 0; *sig ; narg ++) 85 | { 86 | /*check stack is full*/ 87 | lua_checkstack(L,1); 88 | 89 | switch(*sig) 90 | { 91 | case 'd': /*double type parametere*/ 92 | { 93 | lua_pushnumber(L,va_arg(vl,double)); 94 | break; 95 | } 96 | 97 | case 'i': /*int type parametere*/ 98 | { 99 | lua_pushinteger(L,va_arg(vl,int)); 100 | break; 101 | } 102 | case 's': /*string type parametere*/ 103 | { 104 | lua_pushstring(L,va_arg(vl,char*)); 105 | break; 106 | } 107 | 108 | case '>': /* parametere end*/ 109 | isbreak = true; 110 | break; 111 | default: 112 | error(L,"invalid option (%c)",*sig); 113 | } 114 | 115 | sig++; 116 | if(isbreak) 117 | break; 118 | } 119 | 120 | nres = strlen(sig); /*result number*/ 121 | 122 | if(lua_pcall(L,narg,nres,0) != 0) 123 | error(L,"error calling '%s':%s\n",funcname,lua_tostring(L,-1)); 124 | 125 | /*get all result*/ 126 | nres = -nres; 127 | while(*sig) 128 | { 129 | switch(*sig) 130 | { 131 | case 'd': 132 | { 133 | if(!lua_isnumber(L,nres)) 134 | error(L,"wrong result type,%c",*sig); 135 | *va_arg(vl,double *) = lua_tonumber(L,nres); 136 | break; 137 | } 138 | 139 | case 'i': 140 | { 141 | if(!lua_isnumber(L,nres)) 142 | error(L,"wrong result type,%c",*sig); 143 | *va_arg(vl,int *) = lua_tonumber(L,nres); 144 | break; 145 | } 146 | 147 | case 's': 148 | { 149 | if(!lua_isstring(L,nres)) 150 | error(L,"wrong result type"); 151 | *va_arg(vl,const char **) = lua_tostring(L,nres); 152 | break; 153 | } 154 | 155 | default: 156 | error(L,"invalid option (%c)",*sig); 157 | } 158 | sig++; 159 | nres++; 160 | } 161 | 162 | va_end(vl); 163 | } 164 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | #ifndef util_h 2 | #define util_h 3 | 4 | void error(lua_State *L, const char *fmt, ...); 5 | 6 | void stack_dump(lua_State *L); 7 | 8 | void load(lua_State *L, const char *file_name); 9 | 10 | /*a general interface can be userd to call lua function in c*/ 11 | void call_va(lua_State *L,const char *funcname,const char *sig, ...); 12 | 13 | #endif 14 | --------------------------------------------------------------------------------