diff options
author | 2015-01-10 14:05:06 +0100 | |
---|---|---|
committer | 2015-01-10 14:05:06 +0100 | |
commit | ecc0d5a977534e3e2e4fcf20c30938d457889d54 (patch) | |
tree | 359b88bebb6c9c1ef5f9f09817752ec22be8245b /3rdparty | |
parent | 02d37b6915e453fbc40afc80830d9a2cbb459d1f (diff) |
Added full LuaBridge sources
Diffstat (limited to '3rdparty')
24 files changed, 10379 insertions, 0 deletions
diff --git a/3rdparty/luabridge/.gitattributes b/3rdparty/luabridge/.gitattributes new file mode 100644 index 00000000000..176a458f94e --- /dev/null +++ b/3rdparty/luabridge/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/3rdparty/luabridge/.gitignore b/3rdparty/luabridge/.gitignore new file mode 100644 index 00000000000..d42a90ffe3d --- /dev/null +++ b/3rdparty/luabridge/.gitignore @@ -0,0 +1,2 @@ +Documentation +*.swp diff --git a/3rdparty/luabridge/CHANGES b/3rdparty/luabridge/CHANGES new file mode 100644 index 00000000000..e26a187fd99 --- /dev/null +++ b/3rdparty/luabridge/CHANGES @@ -0,0 +1,37 @@ +Version 2.0 + + * Numerous bug fixes + * Feature Requests from Github Issues + * Added LuaRef object + * Rewritten documentation + +Version 1.1.0 + + * Split code up into several files + * Add Lua table and type representations (based on Nigel's code) + * Reformat documentation as external HTML file + +Version 1.0.3 + + * Pass nil to Lua when a null pointer is passed for objects with shared lifetime. + +Version 1.0.2 + + * Option to hide metatables selectable at runtime, default to true. + * addStaticMethod () renamed to addStaticFunction () for consistency. + * addMethod () renamed to addFunction() for consistency. + * addCFunction () registrations. + * Convert null pointers to and from nil. + * Small performance increase in class pointer extraction. + +2012-05-30 Version 1.0.1 + + * Backward compatibility with Lua 5.1.x. + +2012-05-29 Version 1.0 + + * Explicit lifetime management models. + * Generalized containers. + * Single header distribution. + + diff --git a/3rdparty/luabridge/Doxyfile b/3rdparty/luabridge/Doxyfile new file mode 100644 index 00000000000..b4ca87da4d8 --- /dev/null +++ b/3rdparty/luabridge/Doxyfile @@ -0,0 +1,1799 @@ +# Doxyfile 1.8.1.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = LuaBridge + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = NO + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = NO + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = YES + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = LuaBridge.h \ + RefCountedObject.h \ + RefCountedPtr.h + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cpp \ + *.h \ + *.hpp + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = ./ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = Documentation + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 240 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 64 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = NO + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = WIN32 \ + = \ + 1 + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/3rdparty/luabridge/Manual.html b/3rdparty/luabridge/Manual.html new file mode 100644 index 00000000000..e2a7d0dfd93 --- /dev/null +++ b/3rdparty/luabridge/Manual.html @@ -0,0 +1,1794 @@ +<!doctype html> +<html> +<head> +<title>LuaBridge 2.0 Reference Manual</title> +<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1"> + +<!--=========================================================================--> +<style TYPE="text/css"> + +body { + color: #000000 ; + background-color: #FFFFFF ; + font-family: Helvetica, Arial, sans-serif ; + text-align: justify ; + margin-right: 30px ; + margin-left: 30px ; +} + +h1, h2, h3, h4 { + font-family: Verdana, Geneva, sans-serif ; + font-weight: normal ; + font-style: normal ; +} + +h1 { + padding-top: 0.4em ; + padding-bottom: 0.4em ; + padding-left: 24px ; + margin-left: -24px ; + background-color: #ffe668 ; + border-radius: 8px ; +} + +h2 { + padding-top: 0.4em ; + padding-bottom: 0.4em ; + padding-left: 1em ; + padding-right: 1em ; + background-color: #ffe668 ; + border-radius: 8px ; +} + +h3 { + padding-left: 0.5em ; + border-left: solid #ffe668 1em ; +} + +a:link { + color: #8d5c00 ; + background-color: inherit ; + text-decoration: none ; +} + +a:visited { + color: #b17b26; + background-color: inherit ; + text-decoration: none ; +} + +a:link:hover, a:visited:hover { + color: #8d5c00 ; + background-color: #ffe668 ; +} + +a:link:active, a:visited:active { + color: inherit; +} + +hr { + border: 0 ; + height: 1px ; + color: #a0a0a0 ; + background-color: #a0a0a0 ; +} + +:target { + background-color: #F8F8F8 ; + padding-top: 2px ; + padding-bottom: 2px ; + padding-left: 8px; + padding-right: 8px; + border: solid #a0a0a0 2px ; +} + +.footer { + color: gray ; + font-size: small ; +} + +ul { + list-style-type: none ; + list-style-position: outside ; +} + +ul.bullets { + list-style-type: disc ; +} + +img { + border: 0; +} + +table { + margin-left: 2em; +} + +pre, code { + font-size: 12pt ; +} + +pre { + margin-left: 2em; +} + +pre.split { + padding-left: 2em; + display: table-cell ; + white-space: pre-wrap ; + vertical-align: text-top ; + padding-right: 2em; +} + +pre.split + pre.split { + border-left: 1px solid #ccc; +} + +</style> + +</head> + +<!--=========================================================================--> + +<body> + +<header> +<hr> +<h1>LuaBridge 2.0 Reference Manual</h1> +<hr> +</header> + +<small> +Official repository is located at +<a href="https://github.com/vinniefalco/LuaBridge">https://github.com/vinniefalco/LuaBridge</a>. +<br> +Copyright © 2012 Vinnie Falco. Freely available under the terms of the +<A HREF="http://www.opensource.org/licenses/mit-license.html">MIT License</A>. +</small> + +<nav> +<H2>Contents</H2> +<UL id="toc" style="padding: 0"> +<LI><A href="#s1">1 - Introduction</A> +<UL> + <LI><A href="#s1.1">1.1 - Design</A> + <LI><A href="#s1.2">1.2 - Repository</A> + <LI><A href="#s1.3">1.3 - License and Credits</A> +</UL> +<P> +<LI><A href="#s2">2 - Accessing C++ from Lua</A> +<UL> + <LI><A href="#s2.1">2.1 - Namespaces</A> + <LI><A href="#s2.2">2.2 - Data, Properties, Functions, and CFunctions</A> + <LI><A href="#s2.3">2.3 - Class Objects</A> + <LI><A href="#s2.4">2.4 - Property Member Proxies</A> + <LI><A href="#s2.5">2.5 - Constructors</A> + <LI><A href="#s2.6">2.6 - Lua Stack</A> + <LI><A href="#s2.7">2.7 - lua_State</A> +</UL> +<p> +<LI><A href="#s3">3 - Passing Objects</A> +<UL> + <LI><A href="#s3.1">3.1 - C++ Lifetime</A> + <LI><A href="#s3.2">3.2 - Lua Lifetime</A> + <LI><A href="#s3.3">3.3 - Pointers, References, and Pass by Value</A> + <LI><A href="#s3.4">3.4 - Shared Lifetime</A> + <UL> + <LI><A href="#s3.4.1">3.4.1 - Class RefCountedObjectPtr</A> + <LI><A href="#s3.4.2">3.4.2 - Class RefCountedPtr</A> + <LI><A href="#s3.4.3">3.4.3 - User-defined Containers</A> + <LI><A href="#s3.4.4">3.4.4 - Container Constructors</A> + </UL> + <LI><A href="#s3.5">3.5 - Mixing Lifetimes</A> + <LI><A href="#s3.6">3.6 - Convenience Functions</A> +</UL> +<P> +<LI><A href="#s4">4 - Accessing Lua from C++</A> +<UL> + <LI><A href="#s4.1">4.1 - Class LuaRef</A> + <UL> + <LI><A href="#s4.1.1">4.1.1 - Type Conversions</A> + <LI><A href="#s4.1.2">4.1.2 - Visual Studio 2010, 2012</A> + </UL> + <LI><A href="#s4.2">4.2 - Table Proxies</A> + <LI><A href="#s4.3">4.3 - Calling Lua</A> + <UL> + <LI><A href="#s4.3.1">4.3.1 - Class LuaException</A> + </UL> +</uL> +<P> +<LI><A href="#s5">5 - Security</A> +</UL> +</nav> + +<!--========================================================================--> + +<section> + +<h1>1 - <span id="s1">Introduction</span></h1> + +<p> +<a href="https://github.com/vinniefalco/LuaBridge">LuaBridge</a> is a +lightweight and dependency-free library for mapping data, functions, and +classes back and forth between C++ and <a href="http://wwww.lua.org">Lua</a>, +a powerful, fast, lightweight, embeddable scripting language. LuaBridge has +been tested and works with Lua revisions starting from 5.1.5, although it +should work in any version of Lua from 5.1.0 and later. It also works +transparently with <a href="http://luajit.org/">LuaJIT</a>. +</p> + +<p> +LuaBridge offers the following features: +</p> + +<ul class="bullets" title="Features"> +<li><a href="http://www.opensource.org/licenses/mit-license.html">MIT Licensed</a>, no usage restrictions!</li> +<li>Headers-only: No Makefile, no .cpp files, just one <code>#include</code>!</li> +<li>Simple, light, and nothing else needed (like Boost).</li> +<li>No macros, settings, or configuration scripts needed.</li> +<li>Supports different object lifetime management models.</li> +<li>Convenient, type-safe access to the Lua stack.</li> +<li>Automatic function parameter type binding.</li> +<li>Easy access to Lua objects like tables and functions.</li> +<li>Written in a clear and easy to debug style.</li> +<li>Does not require C++11.</li> +</ul> + +<p> +LuaBridge is distributed as a a collection of header files. You simply add +one line, <code>#include "LuaBridge/LuaBridge.h"</code> where you want to +pass functions, classes, and variables back and forth between C++ and Lua. +There are no additional source files, no compilation settings, and no +Makefiles or IDE-specific project files. LuaBridge is easy to integrate. +</p> + +<p> +C++ concepts like variables and classes are made available to Lua through a +process called <em>registration</em>. Because Lua is weakly typed, the resulting +structure is not rigid. The API is based on C++ template metaprogramming. It +contains template code to automatically generate at compile-time the various +Lua C API calls necessary to export your program's classes and functions to +the Lua environment. +</p> + +<p> +To expose Lua objects to C++, a class called <code>LuaRef</code> is provided. +The implementation allows C++ code to access Lua objects such as numbers +or strings, but more importantly to access things like tables and their +values. Using this class makes idioms like calling Lua functions simple +and clean. +</p> + +<!--========================================================================--> + +<section> + +<h2>1.1 - <span id="s1.1">Design</span></h2> + +<p> +LuaBridge tries to be efficient as possible when creating the "glue" that +exposes C++ data and functions to Lua. At the same time, the code was +written with the intention that it is all as simple and clear as possible, +without resorting to obscure C++ idioms, ugly preprocessor macros, or +configuration settings. Furthermore, it is designed to be "header-only", +making it very easy to integrate into your projects. +</p> + +<p> +Because LuaBridge was written with simplicity in mind there are some features +that are not available. Although it comes close to the highest possible +performance, LuaBridge is not quite the fastest, +<a href="http://code.google.com/p/oolua/">OOLua</a> slightly outperforms +LuaBridge in some tests. LuaBridge also does not try to implement every +possible feature, +<a href="http://www.rasterbar.com/products/luabind.html">LuaBind</a> +explores every corner of the C++ language (but it requires Boost). +</p> + +<p> +LuaBridge does not support: +</p> + +<ul class="bullets"> +<li>Enumerated constants +<li>More than 8 parameters on a function or method (although this can be + increased by adding more <code>TypeListValues</code> specializations). +<li>Overloaded functions, methods, or constructors. +<li>Global variables (variables must be wrapped in a named scope). +<li>Automatic conversion between STL container types and Lua tables. +<li>Inheriting Lua classes from C++ classes. +<li>Passing nil to a C++ function that expects a pointer or reference. +<li>Standard containers like <code>std::shared_ptr</code>. +</ul> + +</section> + +<!--========================================================================--> + +<section> + +<h2>1.2 - <span id="s1.2">Repository</span></h2> + +<p> +The official repository is located at +<a href="https://github.com/vinniefalco/LuaBridge">https://github.com/vinniefalco/LuaBridge</a>. +The branches are organized as follows: +</p> + +<table> +<tr> + <td><b>master</b></td> + <td>Tagged, stable release versions.</td> +</tr> +<tr> + <td><b>release</b></td> + <td>A temporarily created branch that holds a release candidate for review.</td> +</tr> +<tr> + <td><b>develop</b></td> + <td>Contains work in progress, possibly unfinished or with bugs.</td> +</tr> +</table> + +<p> +These repositories are also available: +</p> + +<table> +<tr> + <td><b><a href="https://github.com/vinniefalco/LuaBridgeUnitTests">LuaBridgeUnitTests</a></b></td> + <td>A stand alone command line application to exercise LuaBridge functionality.</td> +</tr> +<tr> + <td><b><a href="https://github.com/vinniefalco/LuaBridgeDemo">LuaBridgeUnitDemo</a></b></td> + <td>A stand alone GUI application that provides an interactive console.</td> +</tr> +</table> + +</section> + +<!--========================================================================--> + +<section> + +<h2>1.3 - <span id="s1.3">License and Credits</span></h2> + +<p> +LuaBridge is published under the terms of the +<a href="http://www.opensource.org/licenses/mit-license.html">MIT License</a>: +</p> + +<pre> +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +</pre> + +<p> +The original version of LuaBridge was written by Nathan Reed. The project +has been taken over by Vinnie Falco, who added new functionality and wrote +the new documentation. Vinnie also incorporated <code>LuaRef</code> and +other Lua to C++ binding contributions from Nigel Atkinson. +</p> + +<p> +For questions, comments, or bug reports feel free to open a Github issue +or contact Vinnie Falco directly at the email address indicated below. +</p> + +<ul> +<li>Copyright 2012, Vinnie Falco <a href="mailto:vinnie.falco@gmail.com"><vinnie.falco@gmail.com></a> +<li>Copyright 2008, Nigel Atkinson <a href="mailto:suprapilot+LuaCode@gmail.com"><suprapilot+LuaCode@gmail.com></a> +<li>Copyright 2007, Nathan Reed +<li>Portions from The Loki Library: Copyright 2001 by Andrei Alexandrescu +</ul> + +<p> +Older versions of LuaBridge up to and including 0.2 (available separately) are +distributed under the BSD 3-Clause License. See the corresponding license file +in those versions (distributed separately) for more details. +</p> + +</section> + +<!--========================================================================--> + +</section> + +<section> + +<h1>2 - <span id="s2">Accessing C++ from Lua</span></h1> + +<p> +In order to expose C++ data and functions to Lua, each piece of exported +information must be <em>registered</em>. There are five types of objects that +LuaBridge can register: +</p> + +<table> +<tr> + <td><b>Namespaces</b> </td> + <td>A Lua table that contains other registrations.</td> +</tr> +<tr> + <td><b>Data</b> </td> + <td>Global or static variables, data members, and static data members.</td> +</tr> +<tr> + <td><b>Functions </b></td> + <td>Regular functions, member functions, and static member functions.</td> +</tr> +<tr> + <td><b>CFunctions </b></td> + <td>A regular function, member function, or static member function that + uses the <code>lua_CFunction</code> calling convention.</td> +</tr> +<tr> + <td><b>Properties </b></td> + <td>Global properties, property members, and static property members. + These appear like data to Lua, but are implemented in C++ using + functions to get and set the values.</td> + </tr> +</table> + +<p> +Both data and properties can be marked as <em>read-only</em> at the time of +registration. This is different from <code>const</code>; the values of these +objects can be modified on the C++ side, but Lua scripts cannot change them. +Code samples that follow are in C++ or Lua, depending on context. For brevity +of exposition code samples in C++ assume the traditional variable +<code>lua_State* L</code> is defined, and that a <code>using namespace luabridge</code> +using-directive is in effect. +</p> + +<!--========================================================================--> + +<section> + +<h2>2.1 - <span id="s2.1">Namespaces</span></h2> + +<p> +All LuaBridge registrations take place in a <em>namespace</em>. When we refer +to a <em>namespace</em> we are always talking about a namespace in the Lua +sense, which is implemented using tables. The namespace need not correspond +to a C++ namespace; in fact no C++ namespaces need to exist at all unless you +want them to. LuaBridge namespaces are visible only to Lua scripts; they are +used as a logical grouping tool. To obtain access to the global namespace +we write: +</p> + +<pre> +getGlobalNamespace (L); +</pre> + +<p> +This returns an object on which further registrations can be performed. The +subsequent registrations will go into the global namespace, a practice which +is not recommended. Instead, we can add our own namespace by writing: +</p> + +<pre> +getGlobalNamespace (L) + .beginNamespace ("test"); +</pre> + +<p> +This creates a table in <code>_G</code> called "test". Since we have not +performed any registrations, this table will be empty except for some +bookkeeping key/value pairs. LuaBridge reserves all identifiers that start +with a double underscore. So <code>__test</code> would be an invalid name +(although LuaBridge will silently accept it). Functions like +<code>beginNamespace</code> return the corresponding object on which we can +make more registrations. Given: +</p> + +<pre> +getGlobalNamespace (L) + .beginNamespace ("test") + .beginNamespace ("detail") + .endNamespace () + .beginNamespace ("utility") + .endNamespace () + .endNamespace (); +</pre> + +<p> +The results are accessible to Lua as <code>test</code>, <code>test.detail</code>, +and <code>test.utility</code>. Here we introduce the <code>endNamespace</code> +function; it returns an object representing the original enclosing namespace. +All LuaBridge functions which create registrations return an object upon which +subsequent registrations can be made, allowing for an unlimited number of +registrations to be chained together using the dot operator. Adding two objects +with the same name, in the same namespace, results in undefined behavior +(although LuaBridge will silently accept it). +</p> + +<p> +A namespace can be re-opened later to add more functions. This lets you split +up the registration between different source files. These are equivalent: +</p> + +<pre> +getGlobalNamespace (L) + .beginNamespace ("test") + .addFunction ("foo", foo) + .endNamespace (); + +getGlobalNamespace (L) + .beginNamespace ("test") + .addFunction ("bar", bar) + .endNamespace (); +</pre> + +<p> +and +</p> + +<pre> +getGlobalNamespace (L) + .beginNamespace ("test") + .addFunction ("foo", foo) + .addFunction ("bar", bar) + .endNamespace (); +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h2>2.2 - <span id="s2.2">Data, Properties, Functions, and CFunctions</span></h2> + +<p> +These are registered into a namespace using <code>addVariable</code>, +<code>addProperty</code>, <code>addFunction</code>, and <code>addCFunction</code>. +When registered functions are called by scripts, LuaBridge automatically takes +care of the conversion of arguments into the appropriate data type when doing +so is possible. This automated system works for the function's return value, +and up to 8 parameters although more can be added by extending the templates. +Pointers, references, and objects of class type as parameters are treated +specially, and explained later. If we have: +</p> + +<pre> +int globalVar; +static float staticVar; + +std::string stringProperty; +std::string getString () { return stringProperty; } +void setString (std::string s) { stringProperty = s; } + +int foo () { return 42; } +void bar (char const*) { } +int cFunc (lua_State* L) { return 0; } +</pre> + +<p> +These are registered with: +</p> + +<pre> +getGlobalNamespace (L) + .beginNamespace ("test") + .addVariable ("var1", &globalVar) + .addVariable ("var2", &staticVar, false) // read-only + .addProperty ("prop1", getString, setString) + .addProperty ("prop2", getString) // read only + .addFunction ("foo", foo) + .addFunction ("bar", bar) + .addCFunction ("cfunc", cFunc) + .endNamespace (); +</pre> + +<p> +Variables can be marked <em>read-only</em> by passing <code>false</code> in +the second optional parameter. If the parameter is omitted, <em>true</em> is +used making the variable read/write. Properties are marked read-only by +omitting the set function. After the registrations above, the following Lua +identifiers are valid: +</p> + +<pre> +test -- a namespace +test.var1 -- a lua_Number variable +test.var2 -- a read-only lua_Number variable +test.prop1 -- a lua_String property +test.prop2 -- a read-only lua_String property +test.foo -- a function returning a lua_Number +test.bar -- a function taking a lua_String as a parameter +test.cfunc -- a function with a variable argument list and multi-return +</pre> + +<p> +Note that <code>test.prop1</code> and `test.prop2` both refer to the +same value. However, since <code>test.prop2</code> is read-only, assignment +attempts will generate a run-time error. These Lua statements have the stated effects: +</p> + +<pre> +test.var1 = 5 -- okay +test.var2 = 6 -- error: var2 is not writable +test.prop1 = "Hello" -- okay +test.prop1 = 68 -- okay, Lua converts the number to a string. +test.prop2 = "bar" -- error: prop2 is not writable + +test.foo () -- calls foo and discards the return value +test.var1 = foo () -- calls foo and stores the result in var1 +test.bar ("Employee") -- calls bar with a string +test.bar (test) -- error: bar expects a string not a table +</pre> + +<p> +LuaBridge does not support overloaded functions nor is it likely to in the +future. Since Lua is dynamically typed, any system that tries to resolve a set +of parameters passed from a script will face considerable ambiguity when +trying to choose an appropriately matching C++ function signature. +</p> + +</section> + +<!--========================================================================--> + +<section> + +<h2>2.3 - <span id="s2.3">Class Objects</span></h2> + +<p> +A class registration is opened using either <code>beginClass</code> or +<code>deriveClass</code> and ended using <code>endClass</code>. Once +registered, a class can later be re-opened for more registrations using +<code>beginClass</code>. However, <code>deriveClass</code> should only be +used once. To add more registrations to an already registered derived class, +use <code>beginClass</code> on it. These declarations: +</p> + +<pre> +struct A { + static int staticData; + static float staticProperty; + + static float getStaticProperty () { return staticProperty; } + static void setStaticProperty (float f) { staticProperty = f; } + static void staticFunc () { } + + static int staticCFunc () { return 0; } + + std::string dataMember; + + char dataProperty; + char getProperty () const { return dataProperty; } + void setProperty (char v) { dataProperty = v; } + + void func1 () { } + virtual void virtualFunc () { } + + int cfunc (lua_State* L) { return 0; } +}; + +struct B : public A { + double dataMember2; + + void func1 () { } + void func2 () { } + void virtualFunc () { } +}; + +int A::staticData; +float A::staticProperty; +</pre> + +<p> +are registered using: +</p> + +<pre> +getGlobalNamespace (L) + .beginNamespace ("test") + .beginClass <A> ("A") + .addStaticData ("staticData", &A::staticData) + .addStaticProperty ("staticProperty", &A::staticProperty) + .addStaticFunction ("staticFunc", &A::staticFunc) + .addStaticCFunction ("staticCFunc", &A::staticCFunc) + .addData ("data", &A::dataMember) + .addProperty ("prop", &A::getProperty, &A::setProperty) + .addFunction ("func1", &A::func1) + .addFunction ("virtualFunc", &A::virtualFunc) + .addCFunction ("cfunc", &A::cfunc) + .endClass () + .deriveClass <B, A> ("B") + .addData ("data", &B::dataMember2) + .addFunction ("func1", &B::func1) + .addFunction ("func2", &B::func2) + .endClass () + .endNameSpace (); +</pre> + +<p> +Method registration works just like function registration. Virtual methods +work normally; no special syntax is needed. const methods are detected and +const-correctness is enforced, so if a function returns a const object (or +a container holding to a const object) to Lua, that reference to the object +will be considered const and only const methods can be called on it. +Destructors are registered automatically for each class. +</p> + +<p> +As with regular variables and properties, class data and properties can be +marked read-only by passing false in the second parameter, or omitting the set +set function respectively. The `deriveClass` takes two template arguments: the +class to be registered, and its base class. Inherited methods do not have to +be re-declared and will function normally in Lua. If a class has a base class +that is **not** registered with Lua, there is no need to declare it as a +subclass. +</p> + +<p> +Remember that in Lua, the colon operator '<code>:</code>' is used for +method call syntax: +</p> + +<pre> +local a = A () + +a.func1 () -- Does nothing +a:func1 () -- Works +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h2>2.4 - <span id="s2.4">Property Member Proxies</span></h2> + +<p> +Sometimes when registering a class which comes from a third party library, the +data is not exposed in a way that can be expressed as a pointer to member, +there are no get or set functions, or the get and set functons do not have the +right function signature. Since the class declaration is closed for changes, +LuaBridge allows for a <em>property member proxy</em>. This is a pair of get +and set flat functions which take as their first parameter a pointer to +the object. This is easily understood with the following example: +</p> + +<pre> +// Third party declaration, can't be changed +struct Vec +{ + float coord [3]; +}; +</pre> + +<p> +Taking the address of an array element, e.g. <code>&Vec::coord [0]</code> +results in an error instead of a pointer-to-member. The class is closed for +modifications, but we want to export Vec objects to Lua using the familiar +object notation. To do this, first we add a "helper" class: +</p> + +<pre> +struct VecHelper +{ + template <unsigned index> + static float get (Vec const* vec) + { + return vec->coord [index]; + } + + template <unsigned index> + static void set (Vec* vec, float value) + { + vec->coord [index] = value; + } +}; +</pre> + +<p> +This helper class is only used to provide property member proxies. +<code>Vec</code> continues to be used in the C++ code as it was before. +Now we can register the <code>Vec</code> class with property member proxies for +<code>x</code>, <code>y</code>, and <code>z</code>: +</p> + +<pre> +getGlobalNamespace (L) + .beginNamespace ("test") + .beginClass <Vec> ("Vec") + .addProperty ("x", &VecHelper::get <0>, &VecHelper::set <0>) + .addProperty ("y", &VecHelper::get <1>, &VecHelper::set <1>) + .addProperty ("z", &VecHelper::get <2>, &VecHelper::set <2>) + .endClass () + .endNamespace (); +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h2>2.5 - <span id="s2.5">Constructors</span></h2> + +<p> +A single constructor may be added for a class using <code>addConstructor</code>. +LuaBridge cannot automatically determine the number and types of constructor +parameters like it can for functions and methods, so you must provide them. +This is done by specifying the signature of the desired constructor function +as the first template parameter to <code>addConstructor</code>. The parameter +types will be extracted from this (the return type is ignored). For example, +these statements register constructors for the given classes: +</p> + +<pre> +struct A { + A (); +}; + +struct B { + explicit B (char const* s, int nChars); +}; + +getGlobalNamespace (L) + .beginNamespace ("test") + .beginClass <A> ("A") + .addConstructor <void (*) (void)> () + .endClass () + .beginClass <B> ("B") + .addConstructor <void (*) (char const*, int)> () + .endClass () + .endNamespace (); +</pre> + +<p> +Constructors added in this fashion are called from Lua using the fully +qualified name of the class. This Lua code will create instances of +<code>A</code> and <code>B</code>. +</p> + +<pre> +a = test.A () -- Create a new A. +b = test.B ("hello", 5) -- Create a new B. +b = test.B () -- Error: expected string in argument 1 +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h2>2.6 - <span id="s2.6">Lua Stack</span></h2> + +<p> +In the Lua C API, all operations on the <code>lua_State</code> are performed +through the Lua stack. In order to pass values back and forth between C++ +and Lua, LuaBridge uses specializations of this template class concept: +</p> + +<pre> +template <class T> +struct Stack +{ + static void push (lua_State* L, T t); + static T get (lua_State* L, int index); +}; +</pre> + +<p> +When a specialization of <code>Stack</code> exists for a given type +<code>T</code> we say that the <code>T</code> is <em>convertible</em>. +Throughout this document and the LuaBridge API, these types can be used +anywhere a convertible type is expected. +</p> + +<p> +The Stack template class specializations are used automatically for variables, +properties, data members, property members, function arguments and return +values. These basic types are supported: +</p> + +<ul class="bullets"> +<li><code>bool</code> +<li><code>char</code>, converted to a string of length one. +<li><code>char const*</code> and <code>std::string</code> strings. +<li>Integers, <code>float</code>, and <code>double</code>, + converted to <code>Lua_number</code>. +</ul> + +<p> +User-defined types which are convertible to one of the basic types are +possible, simply provide a <code>Stack<></code> specialization in the +<code>luabridge</code> namespace for your user-defined type, modeled after +the existing types. For example, here is a specialization for a +<code>juce::String</code>: +</p> + +<pre> +template <> +struct Stack <juce::String> +{ + static void push (lua_State* L, juce::String s) + { + lua_pushstring (L, s.toUTF8 ()); + } + + static juce::String get (lua_State* L, int index) + { + return juce::String (luaL_checkstring (L, index)); + } +}; +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h2>2.7 - <span id="s2.7">lua_State</span></h2> + +<p> +Sometimes it is convenient from within a bound function or member function +to gain access to the `lua_State*` normally available to a `lua_CFunction`. +With LuaBridge, all you need to do is add a `lua_State*` as the last +parameter of your bound function: +</p> + +<pre> +void useState (lua_State* L); + +getGlobalNamespace (L).addFunction ("useState", &useState); +</pre> + +<p> +You can still include regular arguments while receiving the state: +</p> + +<pre> +void useStateAndArgs (int i, std::string s, lua_State* L); + +getGlobalNamespace (L).addFunction ("useStateAndArgs", &useStateAndArgs); +</pre> + +<p> +When the script calls <code>useStateAndArgs</code>, it passes only the integer +and string parameters. LuaBridge takes care of inserting the <code>lua_State*</code> +into the argument list for the corresponding C++ function. This will work +correctly even for the state created by coroutines. Undefined behavior results +if the <code>lua_State*</code> is not the last parameter. +</p> + +</section> + +<!--========================================================================--> + +</section> + +<section> + +<h1>3 - <span id="s3">Passing Objects</span></h1> + +<p> +An object of a registered class <code>T</code> may be passed to Lua as: +</p> + +<table> +<tr> + <td><b><code>T</code></b></td> + <td>Passed by value (a copy), with <em>Lua lifetime</em>.</td> +</tr> +<tr> + <td><b><code>T const</code></b></td> + <td>Passed by value (a copy), with <em>Lua lifetime</em>.</td> +</tr> +<tr> + <td><b><code>T*</code></b></td> + <td>Passed by reference, with <em>C++ lifetime</em>.</td> +</tr> +<tr> + <td><b><code>T&</code></b></td> + <td>Passed by reference, with <em>C++ lifetime</em>.</td> +</tr> +<tr> + <td><b><code>T const*</code></b></td> + <td>Passed by const reference, with <em>C++ lifetime</em>.</td> +</tr> +<tr> + <td><b><code>T const&</code></b></td> + <td>Passed by const reference, with <em>C++ lifetime</em>.</td> +</tr> +</table> + +<!--========================================================================--> + +<section> + +<h2>3.1 - <span id="s3.1">C++ Lifetime</span></h2> + +<p> +The creation and deletion of objects with <em>C++ lifetime</em> is controlled by +the C++ code. Lua does nothing when it garbage collects a reference to such an +object. Specifically, the object's destructor is not called (since C++ owns +it). Care must be taken to ensure that objects with C++ lifetime are not +deleted while still being referenced by a <code>lua_State*</code>, or else +undefined behavior results. In the previous examples, an instance of <code>A</code> +can be passed to Lua with C++ lifetime, like this: +</p> + +<pre> +A a; + +push (L, &a); // pointer to 'a', C++ lifetime +lua_setglobal (L, "a"); + +push (L, (A const*)&a); // pointer to 'a const', C++ lifetime +lua_setglobal (L, "ac"); + +push <A const*> (L, &a); // equivalent to push (L, (A const*)&a) +lua_setglobal (L, "ac2"); + +push (L, new A); // compiles, but will leak memory +lua_setglobal (L, "ap"); +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h2>3.2 - <span id="s3.2">Lua Lifetime</span></h2> + +<p> +When an object of a registered class is passed by value to Lua, it will have +<em>Lua lifetime</em>. A copy of the passed object is constructed inside the +userdata. When Lua has no more references to the object, it becomes eligible +for garbage collection. When the userdata is collected, the destructor for +the class will be called on the object. Care must be taken to ensure that +objects with Lua lifetime are not accessed by C++ after they are garbage +collected, or else undefined behavior results. An instance of <code>B</code> +can be passed to Lua with Lua lifetime this way: +</p> + +<pre> +B b; + +push (L, b); // Copy of b passed, Lua lifetime. +lua_setglobal (L, "b"); +</pre> + +<p> +Given the previous code segments, these Lua statements are applicable: +</p> + +<pre> +print (test.A.staticData) -- Prints the static data member. +print (test.A.staticProperty) -- Prints the static property member. +test.A.staticFunc () -- Calls the static method. + +print (a.data) -- Prints the data member. +print (a.prop) -- Prints the property member. +a:func1 () -- Calls A::func1 (). +test.A.func1 (a) -- Equivalent to a:func1 (). +test.A.func1 ("hello") -- Error: "hello" is not a class A. +a:virtualFunc () -- Calls A::virtualFunc (). + +print (b.data) -- Prints B::dataMember. +print (b.prop) -- Prints inherited property member. +b:func1 () -- Calls B::func1 (). +b:func2 () -- Calls B::func2 (). +test.B.func2 (a) -- Error: a is not a class B. +test.A.func1 (b) -- Calls A::func1 (). +b:virtualFunc () -- Calls B::virtualFunc (). +test.B.virtualFunc (b) -- Calls B::virtualFunc (). +test.A.virtualFunc (b) -- Calls B::virtualFunc (). +test.B.virtualFunc (a) -- Error: a is not a class B. + +a = nil; collectgarbage () -- 'a' still exists in C++. +b = nil; collectgarbage () -- Lua calls ~B() on the copy of b. +</pre> + +<p> +When Lua script creates an object of class type using a registered +constructor, the resulting value will have Lua lifetime. After Lua no longer +references the object, it becomes eligible for garbage collection. You can +still pass these to C++, either by reference or by value. If passed by +reference, the usual warnings apply about accessing the reference later, +after it has been garbage collected. +</p> + +</section> + +<!--========================================================================--> + +<section> + +<h2>3.3 - <span id="s3.3">Pointers, References, and Pass by Value</span></h2> + +<p> +When C++ objects are passed from Lua back to C++ as arguments to functions, +or set as data members, LuaBridge does its best to automate the conversion. +Using the previous definitions, the following functions may be registered +to Lua: +</p> + +<pre> +void func0 (A a); +void func1 (A* a); +void func2 (A const* a); +void func3 (A& a); +void func4 (A const& a); +</pre> + +<p> +Executing this Lua code will have the prescribed effect: +</p> + +<pre> +func0 (a) -- Passes a copy of a, using A's copy constructor. +func1 (a) -- Passes a pointer to a. +func2 (a) -- Passes a pointer to a const a. +func3 (a) -- Passes a reference to a. +func4 (a) -- Passes a reference to a const a. +</pre> + +<p> +In the example above, all functions can read the data members and property +members of <code>a</code>, or call const member functions of <code>a</code>. +Only <code>func0</code>, <code>func1</code>, and <code>func3</code> can +modify the data members and data properties, or call non-const member +functions of <code>a</code>. +</p> + +<p> +The usual C++ inheritance and pointer assignment rules apply. Given: +</p> + +<pre> +void func5 (B b); +void func6 (B* b); +</pre> + +<p> +These Lua statements hold: +</p> + +<pre> +func5 (b) - Passes a copy of b, using B's copy constructor. +func6 (b) - Passes a pointer to b. +func6 (a) - Error: Pointer to B expected. +func1 (b) - Okay, b is a subclass of a. +</pre> + +<p> +When a pointer or pointer to const is passed to Lua and the pointer is null +(zero), LuaBridge will pass Lua a `nil` instead. When Lua passes a +<code>nil</code> to C++ where a pointer is expected, a null (zero) is passed +instead. Attempting to pass a null pointer to a C++ function expecting a +reference results in <code>lua_error</code> being called. +</p> + +</section> + +<!--========================================================================--> + +<section> + +<h2>3.4 - <span id="s3.4">Shared Lifetime</span></h2> + +<p> +LuaBridge supports a <em>shared lifetime</em> model: dynamically allocated +and reference counted objects whose ownership is shared by both Lua and C++. +The object remains in existence until there are no remaining C++ or Lua +references, and Lua performs its usual garbage collection cycle. A container +is recognized by a specialization of the <code>ContainerTraits</code> +template class. LuaBridge will automatically recognize when a data type is +a container when the correspoding specialization is present. Two styles of +containers come with LuaBridge, including the necessary specializations. +</p> + +<!--========================================================================--> + +<section> + +<h3>3.4.1 - <span id="s3.4.1">Class RefCountedObjectPtr</span></h3> + +<p> +This is an intrusive style container. Your existing class declaration must be +changed to be also derived from <code>RefCountedObject</code>. Given +<code>class T</code>, derived from <code>RefCountedObject</code>, the container +<code>RefCountedObjectPtr <T></code>` may be used. In order for +reference counts to be maintained properly, all C++ code must store a +container instead of the pointer. This is similar in style to +<code>std::shared_ptr</code> although there are slight differences. For +example: +</p> + +<pre> +// A is reference counted. +struct A : public RefCountedObject +{ + void foo () { } +}; + +struct B +{ + RefCountedObjectPtr <A> a; // holds a reference to A +}; + +void bar (RefCountedObjectPtr <A> a) +{ + a->foo (); +} +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h3>3.4.2 - <span id="s3.4.2">Class RefCountedPtr</span></h3> + +<p> +This is a non intrusive reference counted pointer. The reference counts are +kept in a global hash table, which does incur a small performance penalty. +However, it does not require changing any already existing class declarations. +This is especially useful when the classes to be registered come from a third +party library and cannot be modified. To use it, simply wrap all pointers +to class objects with the container instead: +</p> + +<pre> +struct A +{ + void foo () { } +}; + +struct B +{ + RefCountedPtr <A> a; +}; + +RefCountedPtr <A> createA () +{ + return new A; +} + +void bar (RefCountedPtr <A> a) +{ + a->foo (); +} + +void callFoo () +{ + bar (createA ()); + + // The created A will be destroyed + // when we leave this scope +} +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h3>3.4.3 - <span id="s3.4.3">User-defined Containers</span></h3> + +<p> +If you have your own container, you must provide a specialization of +<code>ContainerTraits</code> in the <code>luabridge</code> namespace for your +type before it will be recognized by LuaBridge (or else the code will not +compile): +</p> + +<pre> +template <class T> +struct ContainerTraits <CustomContainer <T> > +{ + typedef typename T Type; + + static T* get (CustomContainer <T> const& c) + { + return c.getPointerToObject (); + } +}; +</pre> + +<p> +Standard containers like <code>std::shared_ptr</code> or +<code>boost::shared_ptr</code> <b>will not work</b>. This is because of type +erasure; when the object goes from C++ to Lua and back to C++, there is no +way to associate the object with the original container. The new container is +constructed from a pointer to the object instead of an existing container. +The result is undefined behavior since there are now two sets of reference +counts. +</p> + +</section> + +<!--========================================================================--> + +<section> + +<h3>3.4.4 - <span id="s3.4.4">Container Constructors</span></h3> + +<p> +When a constructor is registered for a class, there is an additional +optional second template parameter describing the type of container to use. +If this parameter is specified, calls to the constructor will create the +object dynamically, via operator new, and place it a container of that +type. The container must have been previously specialized in +<code>ContainerTraits</code>, or else a compile error will result. This code +will register two objects, each using a constructor that creates an object +with Lua lifetime using the specified container: +</p> + +<pre> +class C : public RefCountedObject +{ + C () { } +}; + +class D +{ + D () { } +}; + +getGlobalNamespace (L) + .beginNamespace ("test") + .beginClass <C> ("C") + .addConstructor <void (*) (void), RefCountedObjectPtr <C> > () + .endClass () + .beginClass <D> ("D") + .addConstructor <void (*) (void), RefCountedPtr <D> > () + .endClass (); + .endNamespace () +</pre> + +</section> + +<!--========================================================================--> + +</section> + +<section> + +<h2>3.5 - <span id="s3.5">Mixing Lifetimes</span></h2> + +<p> +Mixing object lifetime models is entirely possible, subject to the usual +caveats of holding references to objects which could get deleted. For +example, C++ can be called from Lua with a pointer to an object of class +type; the function can modify the object or call non-const data members. +These modifications are visible to Lua (since they both refer to the same +object). An object store in a container can be passed to a function expecting +a pointer. These conversion work seamlessly. +<p> + +</section> + +<!--========================================================================--> + +<section> + +<h2>3.6 - <span id="s3.6">Convenience Functions</span></h2> + +<p> +The <code>setGlobal</code> function can be used to assign any convertible +value into a global variable. +</p> + +</section> + +<!--========================================================================--> + +</section> + +<section> + +<h1>4 - <span id="s4">Accessing Lua from C++</span></h1> + +<p> +Because Lua is a <em>dynamically typed language</em>, special consideration +is required to map values in Lua to C++. The following sections describe the +classes and functions used for representing Lua types. Only the essential +operations are explained; To gain understanding of all available functions, +please refer to the documentation comments in the corresponding source files. +</p> + +<!--========================================================================--> + +<section> + +<h2>4.1 - <span id="s4.1">Class LuaRef</span></h2> + +<p> +The <code>LuaRef</code> class is a container which references any Lua type. +It can hold anything which a Lua variable can hold: <strong>nil</strong>, +number, boolean, string, table, function, thread, userdata, and +lightuserdata. Because <code>LuaRef</code> uses the <code>Stack</code> +template specializations to do its work, classes, functions, and data +exported to Lua through namespace registrations can also be stored (these +are instances of userdata). In general, a <code>LuaRef</code> can represent +any <em>convertible</em> C++ type as well as all Lua types. +</p> + +<p> +A <code>LuaRef</code> variable constructed with no parameters produces a +reference to <strong>nil</strong>: +</p> + +<pre> +LuaRef v (L); // References nil +</pre> + +<p> +To construct a <code>LuaRef</code> to a specific value, the two parameter +constructor is used: +</p> + +<pre> +LuaRef v1 (L, 1); // A LUA_TNUMBER +LuaRef v2 (L, 1.1); // Also a LUA_TNUMBER +LuaRef v3 (L, true); // A LUA_TBOOLEAN +LuaRef v4 (L, "string"); // A LUA_TSTRING +</pre> + +<p> +The functions <code>newTable</code> and <code>getGlobal</code> create +references to new empty table and an existing value in the global table +respectively: +</p> + +<pre> +LuaRef v1 = newTable (L); // Create a new table +LuaRef v2 = getGlobal (L, "print") // Reference to _G ["print"] +</pre> + +<p> +A <code>LuaRef</code> can hold classes <em>registered</em> using LuaBridge: +</p> + +<pre> +class A; +//... +LuaRef v (L, new A); // A LuaBridge userdata holding a pointer to A +</pre> + +<p> +Any convertible type may be assigned to an already-existing <code>LuaRef</code>: +</p> + +<pre> +LuaRef v (L); // Nil +v = newTable (L); // An empty table +v = "string" // A string. The prevous value becomes + // eligible for garbage collection. +</pre> + +<p> +A <code>LuaRef</code> is itself a convertible type, and the convertible +type <code>Nil</code> can be used to represent a Lua <strong>nil</strong>. +</p> + +<pre> +LuaRef v1 (L, "x"); // assign "x" +LuaRef v2 (L, "y"); // assign "y" +v2 = v1; // v2 becomes "x" +v1 = "z"; // v1 becomes "z", v2 is unchanged +v1 = newTable (L); // An empty table +v2 = v1; // v2 references the same table as v1 +v1 = Nil (); // v1 becomes nil, table is still + // referenced by v2. +</pre> + +<p> +Values stored in a <code>LuaRef</code> object obey the same rules as +variables in Lua: tables, functions, threads, and full userdata values are +<em>objects</em>. The <code>LuaRef</code> does not actually <em>contain</em> +these values, only <em>references</em> to them. Assignment, parameter +passing, and function returns always manipulate references to such values; +these operations do not imply any kind of copy. +</p> + +<!--========================================================================--> + +<section> + +<h3>4.1.1 - <span id="s4.1.1">Type Conversions</span></h3> + +<p> +A universal C++ conversion operator is provided for implicit conversions +which allow a <code>LuaRef</code> to be used where any convertible type is +expected. These operations will all compile: +</p> + +<pre> +void passInt (int); +void passBool (bool); +void passString (std::string); +void passObject (A*); + +LuaRef v (L); +//... +passInt (v); // implicit conversion to int +passBool (v); // implicit conversion to bool +passString (v); // implicit conversion to string +passObject (v); // must hold a registered LuaBridge class or a + // lua_error() will be called. +</pre> + +<p> +Since Lua types are dynamic, the conversion is performed at run time using +traditional functions like <code>lua_toboolean</code> or +<code>lua_tostring</code>. In some cases, the type information may be +incorrect especially when passing objects of registered class types. +When performing these conversions, LuaBridge may raise a Lua error by +directly or indirectly calling <code>lua_error</code> To be bullet-proof, +such code must either be wrapped in a <code>lua_pcall</code>, or you must +install a Lua <em>panic function</em> that throws an exception which you +can catch. +</p> + +<p> +When an explicit conversion is required (such as when writing templates), +use the <code>cast</code> template function or an explicit C++ style cast. +</p> + +<pre> +void passString (std::string); + +LuaRef v (L); + +// The following are all equivalent: + +passString (std::string (v)); +passString ((std::string)v); +passString (static_cast <std::string> (v)); +passString (v.cast <std::string> ()); +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h3>4.1.2 - <span id="s4.1.2">Visual Studio 2010, 2012</span></h3> + +<p> +There is a defect with all versions of Visual Studio up to and including +Visual Studio 2012 which prevents the implicit conversion operator from +being applied when it is used as an operand in a boolean operator: +</p> + +<pre> +LuaRef v1 (L); +LuaRef v2 (L); + +if (v1 || v2) { } // Compile error in Visual Studio + +// Work-arounds: +if (v1.cast <bool> () || v2.cast <bool> ()) { } +if (bool (v1) || bool (v2)) { } +</pre> + +</section> + +<!--========================================================================--> + +</section> + +<section> + +<h2>4.2 - <span id="s4.2">Table Proxies</span></h2> + +<p> +As tables are the sole data structuring mechanism in Lua, the +<code>LuaRef</code> class provides robust facilities for accessing and +manipulating table elements using a simple, precise syntax. Any convertible +type may be used as a key or value. Applying the array indexing operator +<code>[]</code> to a <code>LuaRef</code> returns a special temporary object +called a <em>table proxy</em> which supports all the operations which can +be performed on a <code>LuaRef</code>. In addition, assignments made to +table proxies change the underlying table. Because table proxies are +compiler-created temporary objects, you don't work with them directly. A +LuaBridge table proxy should not be confused with the Lua proxy table +technique described in the book "Programming in Lua"; the LuaBridge table +proxy is simply an intermediate C++ class object that works behind the +scenes to make table manipulation syntax conform to C++ idioms. These +operations all invoke table proxies: +</p> + +<pre> +LuaRef v (L); +v = newTable (L); + +v ["name"] = "John Doe"; // string key, string value +v [1] = 200; // integer key, integer value +v [2] = newTable (L); // integer key, LuaRef value +v [3] = v [1]; // assign 200 to integer index 3 +v [1] = 100; // v[1] is 100, v[3] is still 200 +v [3] = v [2]; // v[2] and v[3] reference the same table +v [2] = Nil (); // Removes the value with key = 2. The table + // is still referenced by v[3]. +</pre> + +</section> + +<!--========================================================================--> + +<section> + +<h2>4.3 - <span id="s4.3">Calling Lua</span></h2> + +<p> +Table proxies and <code>LuaRef</code> objects provide a convenient syntax +for invoking <code>lua_pcall</code> on suitable referenced object. This +includes C functions, Lua functions, or Lua objects with an appropriate +<code>__call</code> metamethod set. The provided implementation supports +up to eight parameters (although more can be supported by adding new +functions). Any convertible C++ type can be passed as a parameter in its +native format. The return value of the function call is provided as a +<code>LuaRef</code>, which may be <strong>nil</strong>. +</p> + +<pre class="split"> +LuaRef same = getGlobal (L, "same"); + +// These all evaluate to true +same (1,1); +!same (1,2); +same ("text", "text"); +!same (1, "text"); +same (1, 1, 2); // third param ignored +</pre> + +<pre class="split"> +function same (arg1, arg) + return arg1 == arg2 +end +</pre> + +<p> +Table proxies support all of the Lua call notation that <code>LuaRef</code> +supports, making these statements possible: +</p> + +<pre class="split"> +LuaRef v = getGlobal (L, "t"); + +t[1](); +t[2]("a", "b"); +t[2](t[1]); // Call t[3] with the value in t[2] +t[4]=t[3](); // Call t[3] and store the result in t[4]. + +t [t[5]()] = "wow"; // Store "wow" at the key returned by + // the call to t[5] +</pre> + +<pre class="split"> +t = {} +t[1] = function () print ("hello") end +t[2] = function (u, v) print (u, v) end +t[3] = "foo" +</pre> + +<!--========================================================================--> + +<h3>4.3.1 - <span id="s4.3.1">Class LuaException</span></h3> + +<section > + +<p> +When <code>LuaRef</code> is used to call into Lua using the <code>()</code> +operator it issues a protected call using <code>lua_pcall</code>. LuaBridge +uses the C++ exception handling mechanism, throwing a <code>LuaException</code> +object: +</p> + +<pre class="split"> +LuaRef f (L) = getGlobal (L, "fail"); + +try { + f (); +} +catch (LuaException const& e) { + std::cerr && e.what (); +} +</pre> + +<pre class="split"> +function fail () + error ("A problem occurred") +end +</pre> + +</section> + +<!--========================================================================--> + +</section> + +<!--========================================================================--> + +</section> + +<section> + +<h1>5 - <span id="s5">Security</span></h1> + +<p> +The metatables and userdata that LuaBridge creates in the `lua_State*` are +protected using a security system, to eliminate the possibility of undefined +behavior resulting from scripted manipulation of the environment. The +security system has these components: +</p> + +<ul class="bullets"> +<li> +Class and const class tables use the <em>table proxy</em> technique. The +corresponding metatables have <code>__index</code> and <code>__newindex</code> +metamethods, so these class tables are immutable from Lua. +<li> +Metatables have <code>__metatable</code> set to a boolean value. Scripts +cannot obtain the metatable from a LuaBridge object. +<li> +Classes are mapped to metatables through the registry, which Lua scripts +cannot access. The global environment does not expose metatables +<li> +Metatables created by LuaBridge are tagged with a lightuserdata key which +is unique in the process. Other libraries cannot forge a LuaBridge +metatable. +</ul> + +<p> +This security system can be easily bypassed if scripts are given access to +the debug library (or functionality similar to it, i.e. a raw `getmetatable`). +The security system can also be defeated by C code in the host, either by +revealing the unique lightuserdata key to another module or by putting a +LuaBridge metatable in a place that can be accessed by scripts. +</p> + +<p> +When a class member function is called, or class property member accessed, +the `this` pointer is type-checked. This is because member functions exposed +to Lua are just plain functions that usually get called with the Lua colon +notation, which passes the object in question as the first parameter. Lua's +dynamic typing makes this type-checking mandatory to prevent undefined +behavior resulting from improper use. +</p> + +<p> +If a type check error occurs, LuaBridge uses the <code>lua_error</code> +mechanism to trigger a failure. A host program can always recover from +an error through the use of <code>lua_pcall</code>; proper usage of +LuaBridge will never result in undefined behavior. +</p> + +</section> + +<!--========================================================================--> + +</body> +</html> + diff --git a/3rdparty/luabridge/README.md b/3rdparty/luabridge/README.md new file mode 100644 index 00000000000..ea18eca3c3e --- /dev/null +++ b/3rdparty/luabridge/README.md @@ -0,0 +1,76 @@ +<a href="http://lua.org"> +<img src="http://vinniefalco.github.com/LuaBridgeDemo/powered-by-lua.png"> +</a><br> + +# LuaBridge 2.0 + +[LuaBridge][1] is a lightweight and dependency-free library for mapping data, +functions, and classes back and forth between C++ and [Lua][2] (a powerful, +fast, lightweight, embeddable scripting language) . LuaBridge has been tested +and works with Lua revisions starting from 5.1.5., although it should work in +any version of Lua from 5.1.0 as well as [LuaJit][3]. + +LuaBridge offers the following features: + +- [MIT Licensed][4] +- A printable [Reference Manual][5]. +- Headers-only: No Makefile, no .cpp files, just one #include! +- Simple, light, and nothing else needed (like Boost). +- No macros, settings, or configuration scripts needed. +- Supports different object lifetime management models. +- Convenient, type-safe access to the Lua stack. +- Automatic function parameter type binding. +- Easy access to Lua objects like tables and functions. +- Written in a clear and easy to debug style. +- Does not require C++11. + +Please read the [LuaBridge Reference Manual][5] for more details on the API. + +## LuaBridge Demo and Unit Tests + +LuaBridge provides both a command line program and a stand-alone graphical +program for compiling and running the test suite. The graphical program brings +up an interactive window where you can enter execute Lua statements in a +persistent environment. This application is cross platform and works on +Windows, Mac OS, iOS, Android, and GNU/Linux systems with X11. The stand-alone +program should work anywhere. Both of these applications include LuaBridge, +Lua version 5.2, and the code necessary to produce a cross platform graphic +application. They are all together in a separate repository, with no +additional dependencies, available on Github at [LuaBridge Demo and Tests][6]. +This is what the GUI application looks like, along with the C++ code snippet +for registering the two classes: + +<a href="https://github.com/vinniefalco/LuaBridgeDemo"> +<img src="http://vinniefalco.github.com/LuaBridgeDemo/LuaBridgeDemoScreenshot1.0.2.png"> +</a><br> + +## Official Repository + +LuaBridge is published under the terms of the [MIT License][4]. + +The original version of LuaBridge was written by Nathan Reed. The project has +been taken over by [Vinnie Falco][7], who added new functionality, wrote the new +documentation, and incorporated contributions from Nigel Atkinson. + +For questions, comments, or bug reports feel free to open a Github issue +or contact Vinnie Falco directly at the email address indicated below. + +Copyright 2012, [Vinnie Falco][7] (<[vinnie.falco@gmail.com][8]>)<br> +Copyright 2008, Nigel Atkinson<br> +Copyright 2007, Nathan Reed<br> + +Portions from The Loki Library:<br> +Copyright (C) 2001 by Andrei Alexandrescu + +Older versions of LuaBridge up to and including 0.2 are distributed under the +BSD 3-Clause License. See the corresponding license file in those versions +(distributed separately) for more details. + +[1]: https://github.com/vinniefalco/LuaBridge "LuaBridge" +[2]: http://lua.org "The Lua Programming Language" +[3]: http://luajit.org/ "The LuaJIT Probject" +[4]: http://www.opensource.org/licenses/mit-license.html "The MIT License" +[5]: http://vinniefalco.github.com/LuaBridge "LuaBridge Reference Manual" +[6]: https://github.com/vinniefalco/LuaBridgeDemo "LuaBridge Demo" +[7]: https://github.com/vinniefalco "Vinnie Falco's Github" +[8]: mailto:vinnie.falco@gmail.com "Vinnie Falco (Email)" diff --git a/3rdparty/luabridge/Source/LuaBridge/LuaBridge.h b/3rdparty/luabridge/Source/LuaBridge/LuaBridge.h new file mode 100644 index 00000000000..1928e9a1f03 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/LuaBridge.h @@ -0,0 +1,142 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#ifndef LUABRIDGE_LUABRIDGE_HEADER +#define LUABRIDGE_LUABRIDGE_HEADER + +// All #include dependencies are listed here +// instead of in the individual header files. +// +#include <cassert> +#include <sstream> +#include <stdexcept> +#include <string> +#include <typeinfo> + +#define LUABRIDGE_MAJOR_VERSION 2 +#define LUABRIDGE_MINOR_VERSION 0 +#define LUABRIDGE_VERSION 200 + +namespace luabridge +{ + +// Forward declaration +// +template <class T> +struct Stack; + +#include "detail/LuaHelpers.h" + +#include "detail/TypeTraits.h" +#include "detail/TypeList.h" +#include "detail/FuncTraits.h" +#include "detail/Constructor.h" +#include "detail/Stack.h" +#include "detail/ClassInfo.h" + +class LuaRef; + +#include "detail/LuaException.h" +#include "detail/LuaRef.h" +#include "detail/Iterator.h" + +//------------------------------------------------------------------------------ +/** + security options. +*/ +class Security +{ +public: + static bool hideMetatables () + { + return getSettings().hideMetatables; + } + + static void setHideMetatables (bool shouldHide) + { + getSettings().hideMetatables = shouldHide; + } + +private: + struct Settings + { + Settings () : hideMetatables (true) + { + } + + bool hideMetatables; + }; + + static Settings& getSettings () + { + static Settings settings; + return settings; + } +}; + +#include "detail/Userdata.h" +#include "detail/CFunctions.h" +#include "detail/Namespace.h" + +//------------------------------------------------------------------------------ +/** + Push an object onto the Lua stack. +*/ +template <class T> +inline void push (lua_State* L, T t) +{ + Stack <T>::push (L, t); +} + +//------------------------------------------------------------------------------ +/** + Set a global value in the lua_State. + + @note This works on any type specialized by `Stack`, including `LuaRef` and + its table proxies. +*/ +template <class T> +inline void setGlobal (lua_State* L, T t, char const* name) +{ + push (L, t); + lua_setglobal (L, name); +} + +//------------------------------------------------------------------------------ +/** + Change whether or not metatables are hidden (on by default). +*/ +inline void setHideMetatables (bool shouldHide) +{ + Security::setHideMetatables (shouldHide); +} + +} + +#endif diff --git a/3rdparty/luabridge/Source/LuaBridge/RefCountedObject.h b/3rdparty/luabridge/Source/LuaBridge/RefCountedObject.h new file mode 100644 index 00000000000..807b4606ce2 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/RefCountedObject.h @@ -0,0 +1,363 @@ +//============================================================================== +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2004-11 by Raw Material Software Ltd. + + This is a derivative work used by permission from part of + JUCE, available at http://www.rawaterialsoftware.com + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + This file incorporates work covered by the following copyright and + permission notice: + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-11 by Raw Material Software Ltd. +*/ +//============================================================================== + +#ifndef LUABRIDGE_REFCOUNTEDOBJECT_HEADER +#define LUABRIDGE_REFCOUNTEDOBJECT_HEADER + +//#define LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 + +#include <cassert> + +//============================================================================== +/** + Adds reference-counting to an object. + + To add reference-counting to a class, derive it from this class, and + use the RefCountedObjectPtr class to point to it. + + e.g. @code + class MyClass : public RefCountedObjectType + { + void foo(); + + // This is a neat way of declaring a typedef for a pointer class, + // rather than typing out the full templated name each time.. + typedef RefCountedObjectPtr<MyClass> Ptr; + }; + + MyClass::Ptr p = new MyClass(); + MyClass::Ptr p2 = p; + p = 0; + p2->foo(); + @endcode + + Once a new RefCountedObjectType has been assigned to a pointer, be + careful not to delete the object manually. +*/ +template <class CounterType> +class RefCountedObjectType +{ +public: + //============================================================================== + /** Increments the object's reference count. + + This is done automatically by the smart pointer, but is public just + in case it's needed for nefarious purposes. + */ + inline void incReferenceCount() const + { + ++refCount; + } + + /** Decreases the object's reference count. + + If the count gets to zero, the object will be deleted. + */ + inline void decReferenceCount() const + { + assert (getReferenceCount() > 0); + + if (--refCount == 0) + delete this; + } + + /** Returns the object's current reference count. */ + inline int getReferenceCount() const + { + return static_cast <int> (refCount); + } + +protected: + //============================================================================== + /** Creates the reference-counted object (with an initial ref count of zero). */ + RefCountedObjectType() : refCount () + { + } + + /** Destructor. */ + virtual ~RefCountedObjectType() + { + // it's dangerous to delete an object that's still referenced by something else! + assert (getReferenceCount() == 0); + } + +private: + //============================================================================== + CounterType mutable refCount; +}; + +//============================================================================== + +/** Non thread-safe reference counted object. + + This creates a RefCountedObjectType that uses a non-atomic integer + as the counter. +*/ +typedef RefCountedObjectType <int> RefCountedObject; + +//============================================================================== +/** + A smart-pointer class which points to a reference-counted object. + + The template parameter specifies the class of the object you want to point + to - the easiest way to make a class reference-countable is to simply make + it inherit from RefCountedObjectType, but if you need to, you could roll + your own reference-countable class by implementing a pair of methods called + incReferenceCount() and decReferenceCount(). + + When using this class, you'll probably want to create a typedef to + abbreviate the full templated name - e.g. + + @code + + typedef RefCountedObjectPtr <MyClass> MyClassPtr; + + @endcode +*/ +template <class ReferenceCountedObjectClass> +class RefCountedObjectPtr +{ +public: + /** The class being referenced by this pointer. */ + typedef ReferenceCountedObjectClass ReferencedType; + + //============================================================================== + /** Creates a pointer to a null object. */ + inline RefCountedObjectPtr() : referencedObject (0) + { + } + + /** Creates a pointer to an object. + + This will increment the object's reference-count if it is non-null. + */ + inline RefCountedObjectPtr (ReferenceCountedObjectClass* const refCountedObject) + : referencedObject (refCountedObject) + { + if (refCountedObject != 0) + refCountedObject->incReferenceCount(); + } + + /** Copies another pointer. + This will increment the object's reference-count (if it is non-null). + */ + inline RefCountedObjectPtr (const RefCountedObjectPtr& other) + : referencedObject (other.referencedObject) + { + if (referencedObject != 0) + referencedObject->incReferenceCount(); + } + +#if LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Takes-over the object from another pointer. */ + inline RefCountedObjectPtr (RefCountedObjectPtr&& other) + : referencedObject (other.referencedObject) + { + other.referencedObject = 0; + } +#endif + + /** Copies another pointer. + This will increment the object's reference-count (if it is non-null). + */ + template <class DerivedClass> + inline RefCountedObjectPtr (const RefCountedObjectPtr<DerivedClass>& other) + : referencedObject (static_cast <ReferenceCountedObjectClass*> (other.getObject())) + { + if (referencedObject != 0) + referencedObject->incReferenceCount(); + } + + /** Changes this pointer to point at a different object. + + The reference count of the old object is decremented, and it might be + deleted if it hits zero. The new object's count is incremented. + */ + RefCountedObjectPtr& operator= (const RefCountedObjectPtr& other) + { + return operator= (other.referencedObject); + } + + /** Changes this pointer to point at a different object. + + The reference count of the old object is decremented, and it might be + deleted if it hits zero. The new object's count is incremented. + */ + template <class DerivedClass> + RefCountedObjectPtr& operator= (const RefCountedObjectPtr<DerivedClass>& other) + { + return operator= (static_cast <ReferenceCountedObjectClass*> (other.getObject())); + } + +#if LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Takes-over the object from another pointer. */ + RefCountedObjectPtr& operator= (RefCountedObjectPtr&& other) + { + std::swap (referencedObject, other.referencedObject); + return *this; + } +#endif + + /** Changes this pointer to point at a different object. + + The reference count of the old object is decremented, and it might be + deleted if it hits zero. The new object's count is incremented. + */ + RefCountedObjectPtr& operator= (ReferenceCountedObjectClass* const newObject) + { + if (referencedObject != newObject) + { + if (newObject != 0) + newObject->incReferenceCount(); + + ReferenceCountedObjectClass* const oldObject = referencedObject; + referencedObject = newObject; + + if (oldObject != 0) + oldObject->decReferenceCount(); + } + + return *this; + } + + /** Destructor. + + This will decrement the object's reference-count, and may delete it if it + gets to zero. + */ + inline ~RefCountedObjectPtr() + { + if (referencedObject != 0) + referencedObject->decReferenceCount(); + } + + /** Returns the object that this pointer references. + The pointer returned may be zero, of course. + */ + inline operator ReferenceCountedObjectClass*() const + { + return referencedObject; + } + + // the -> operator is called on the referenced object + inline ReferenceCountedObjectClass* operator->() const + { + return referencedObject; + } + + /** Returns the object that this pointer references. + The pointer returned may be zero, of course. + */ + inline ReferenceCountedObjectClass* getObject() const + { + return referencedObject; + } + +private: + //============================================================================== + ReferenceCountedObjectClass* referencedObject; +}; + +/** Compares two ReferenceCountedObjectPointers. */ +template <class ReferenceCountedObjectClass> +bool operator== (const RefCountedObjectPtr<ReferenceCountedObjectClass>& object1, ReferenceCountedObjectClass* const object2) +{ + return object1.getObject() == object2; +} + +/** Compares two ReferenceCountedObjectPointers. */ +template <class ReferenceCountedObjectClass> +bool operator== (const RefCountedObjectPtr<ReferenceCountedObjectClass>& object1, const RefCountedObjectPtr<ReferenceCountedObjectClass>& object2) +{ + return object1.getObject() == object2.getObject(); +} + +/** Compares two ReferenceCountedObjectPointers. */ +template <class ReferenceCountedObjectClass> +bool operator== (ReferenceCountedObjectClass* object1, RefCountedObjectPtr<ReferenceCountedObjectClass>& object2) +{ + return object1 == object2.getObject(); +} + +/** Compares two ReferenceCountedObjectPointers. */ +template <class ReferenceCountedObjectClass> +bool operator!= (const RefCountedObjectPtr<ReferenceCountedObjectClass>& object1, const ReferenceCountedObjectClass* object2) +{ + return object1.getObject() != object2; +} + +/** Compares two ReferenceCountedObjectPointers. */ +template <class ReferenceCountedObjectClass> +bool operator!= (const RefCountedObjectPtr<ReferenceCountedObjectClass>& object1, RefCountedObjectPtr<ReferenceCountedObjectClass>& object2) +{ + return object1.getObject() != object2.getObject(); +} + +/** Compares two ReferenceCountedObjectPointers. */ +template <class ReferenceCountedObjectClass> +bool operator!= (ReferenceCountedObjectClass* object1, RefCountedObjectPtr<ReferenceCountedObjectClass>& object2) +{ + return object1 != object2.getObject(); +} + +//============================================================================== + +namespace luabridge +{ + +// forward declaration +template <class T> +struct ContainerTraits; + +template <class T> +struct ContainerTraits <RefCountedObjectPtr <T> > +{ + typedef T Type; + + static T* get (RefCountedObjectPtr <T> const& c) + { + return c.getObject (); + } +}; + +} + +//============================================================================== + +#endif + diff --git a/3rdparty/luabridge/Source/LuaBridge/RefCountedPtr.h b/3rdparty/luabridge/Source/LuaBridge/RefCountedPtr.h new file mode 100644 index 00000000000..7c27ca4dcd9 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/RefCountedPtr.h @@ -0,0 +1,251 @@ +//============================================================================== +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#ifndef LUABRIDGE_REFCOUNTEDPTR_HEADER +#define LUABRIDGE_REFCOUNTEDPTR_HEADER + +#ifdef _MSC_VER +# include <hash_map> +#else +# include <stdint.h> +# include <ext/hash_map> +#endif + +//============================================================================== +/** + Support for our RefCountedPtr. +*/ +struct RefCountedPtrBase +{ + // Declaration of container for the refcounts +#ifdef _MSC_VER + typedef stdext::hash_map <const void *, int> RefCountsType; +#else + struct ptr_hash + { + size_t operator () (const void * const v) const + { + static __gnu_cxx::hash<unsigned int> H; + return H(uintptr_t(v)); + } + }; + typedef __gnu_cxx::hash_map<const void *, int, ptr_hash> RefCountsType; +#endif + +protected: + inline RefCountsType& getRefCounts () + { + static RefCountsType refcounts; + return refcounts ; + } +}; + +//============================================================================== +/** + A reference counted smart pointer. + + The api is compatible with boost::RefCountedPtr and std::RefCountedPtr, in the + sense that it implements a strict subset of the functionality. + + This implementation uses a hash table to look up the reference count + associated with a particular pointer. + + @tparam T The class type. + + @todo Decompose RefCountedPtr using a policy. At a minimum, the underlying + reference count should be policy based (to support atomic operations) + and the delete behavior should be policy based (to support custom + disposal methods). + + @todo Provide an intrusive version of RefCountedPtr. +*/ +template <class T> +class RefCountedPtr : private RefCountedPtrBase +{ +public: + template <typename Other> + struct rebind + { + typedef RefCountedPtr <Other> other; + }; + + /** Construct as nullptr or from existing pointer to T. + + @param p The optional, existing pointer to assign from. + */ + RefCountedPtr (T* p = 0) : m_p (p) + { + ++getRefCounts () [m_p]; + } + + /** Construct from another RefCountedPtr. + + @param rhs The RefCountedPtr to assign from. + */ + RefCountedPtr (RefCountedPtr <T> const& rhs) : m_p (rhs.get()) + { + ++getRefCounts () [m_p]; + } + + /** Construct from a RefCountedPtr of a different type. + + @invariant A pointer to U must be convertible to a pointer to T. + + @param rhs The RefCountedPtr to assign from. + @tparam U The other object type. + */ + template <typename U> + RefCountedPtr (RefCountedPtr <U> const& rhs) : m_p (static_cast <T*> (rhs.get())) + { + ++getRefCounts () [m_p]; + } + + /** Release the object. + + If there are no more references then the object is deleted. + */ + ~RefCountedPtr () + { + reset(); + } + + /** Assign from another RefCountedPtr. + + @param rhs The RefCountedPtr to assign from. + @return A reference to the RefCountedPtr. + */ + RefCountedPtr <T>& operator= (RefCountedPtr <T> const& rhs) + { + if (m_p != rhs.m_p) + { + reset (); + m_p = rhs.m_p; + ++getRefCounts () [m_p]; + } + return *this; + } + + /** Assign from another RefCountedPtr of a different type. + + @note A pointer to U must be convertible to a pointer to T. + + @tparam U The other object type. + @param rhs The other RefCountedPtr to assign from. + @return A reference to the RefCountedPtr. + */ + template <typename U> + RefCountedPtr <T>& operator= (RefCountedPtr <U> const& rhs) + { + reset (); + m_p = static_cast <T*> (rhs.get()); + ++getRefCounts () [m_p]; + return *this; + } + + /** Retrieve the raw pointer. + + @return A pointer to the object. + */ + T* get () const + { + return m_p; + } + + /** Retrieve the raw pointer. + + @return A pointer to the object. + */ + T* operator* () const + { + return m_p; + } + + /** Retrieve the raw pointer. + + @return A pointer to the object. + */ + T* operator-> () const + { + return m_p; + } + + /** Determine the number of references. + + @note This is not thread-safe. + + @return The number of active references. + */ + long use_count () const + { + return getRefCounts () [m_p]; + } + + /** Release the pointer. + + The reference count is decremented. If the reference count reaches + zero, the object is deleted. + */ + void reset () + { + if (m_p != 0) + { + if (--getRefCounts () [m_p] <= 0) + delete m_p; + + m_p = 0; + } + } + +private: + T* m_p; +}; + +//============================================================================== + +namespace luabridge +{ + +// forward declaration +template <class T> +struct ContainerTraits; + +template <class T> +struct ContainerTraits <RefCountedPtr <T> > +{ + typedef T Type; + + static T* get (RefCountedPtr <T> const& c) + { + return c.get (); + } +}; + +} + +#endif diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/CFunctions.h b/3rdparty/luabridge/Source/LuaBridge/detail/CFunctions.h new file mode 100644 index 00000000000..0497b6bb4b9 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/CFunctions.h @@ -0,0 +1,442 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +// We use a structure so we can define everything in the header. +// +struct CFunc +{ + //---------------------------------------------------------------------------- + /** + __index metamethod for a namespace or class static members. + + This handles: + Retrieving functions and class static methods, stored in the metatable. + Reading global and class static data, stored in the __propget table. + Reading global and class properties, stored in the __propget table. + */ + static int indexMetaMethod (lua_State* L) + { + int result = 0; + lua_getmetatable (L, 1); // push metatable of arg1 + for (;;) + { + lua_pushvalue (L, 2); // push key arg2 + lua_rawget (L, -2); // lookup key in metatable + if (lua_isnil (L, -1)) // not found + { + lua_pop (L, 1); // discard nil + rawgetfield (L, -1, "__propget"); // lookup __propget in metatable + lua_pushvalue (L, 2); // push key arg2 + lua_rawget (L, -2); // lookup key in __propget + lua_remove (L, -2); // discard __propget + if (lua_iscfunction (L, -1)) + { + lua_remove (L, -2); // discard metatable + lua_pushvalue (L, 1); // push arg1 + lua_call (L, 1, 1); // call cfunction + result = 1; + break; + } + else + { + assert (lua_isnil (L, -1)); + lua_pop (L, 1); // discard nil and fall through + } + } + else + { + assert (lua_istable (L, -1) || lua_iscfunction (L, -1)); + lua_remove (L, -2); + result = 1; + break; + } + + rawgetfield (L, -1, "__parent"); + if (lua_istable (L, -1)) + { + // Remove metatable and repeat the search in __parent. + lua_remove (L, -2); + } + else + { + // Discard metatable and return nil. + assert (lua_isnil (L, -1)); + lua_remove (L, -2); + result = 1; + break; + } + } + + return result; + } + + //---------------------------------------------------------------------------- + /** + __newindex metamethod for a namespace or class static members. + + The __propset table stores proxy functions for assignment to: + Global and class static data. + Global and class properties. + */ + static int newindexMetaMethod (lua_State* L) + { + int result = 0; + lua_getmetatable (L, 1); // push metatable of arg1 + for (;;) + { + rawgetfield (L, -1, "__propset"); // lookup __propset in metatable + assert (lua_istable (L, -1)); + lua_pushvalue (L, 2); // push key arg2 + lua_rawget (L, -2); // lookup key in __propset + lua_remove (L, -2); // discard __propset + if (lua_iscfunction (L, -1)) // ensure value is a cfunction + { + lua_remove (L, -2); // discard metatable + lua_pushvalue (L, 3); // push new value arg3 + lua_call (L, 1, 0); // call cfunction + result = 0; + break; + } + else + { + assert (lua_isnil (L, -1)); + lua_pop (L, 1); + } + + rawgetfield (L, -1, "__parent"); + if (lua_istable (L, -1)) + { + // Remove metatable and repeat the search in __parent. + lua_remove (L, -2); + } + else + { + assert (lua_isnil (L, -1)); + lua_pop (L, 2); + result = luaL_error (L,"no writable variable '%s'", lua_tostring (L, 2)); + } + } + + return result; + } + + //---------------------------------------------------------------------------- + /** + lua_CFunction to report an error writing to a read-only value. + + The name of the variable is in the first upvalue. + */ + static int readOnlyError (lua_State* L) + { + std::string s; + + s = s + "'" + lua_tostring (L, lua_upvalueindex (1)) + "' is read-only"; + + return luaL_error (L, s.c_str ()); + } + + //---------------------------------------------------------------------------- + /** + lua_CFunction to get a variable. + + This is used for global variables or class static data members. + + The pointer to the data is in the first upvalue. + */ + template <class T> + static int getVariable (lua_State* L) + { + assert (lua_islightuserdata (L, lua_upvalueindex (1))); + T const* ptr = static_cast <T const*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (ptr != 0); + Stack <T>::push (L, *ptr); + return 1; + } + + //---------------------------------------------------------------------------- + /** + lua_CFunction to set a variable. + + This is used for global variables or class static data members. + + The pointer to the data is in the first upvalue. + */ + template <class T> + static int setVariable (lua_State* L) + { + assert (lua_islightuserdata (L, lua_upvalueindex (1))); + T* ptr = static_cast <T*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (ptr != 0); + *ptr = Stack <T>::get (L, 1); + return 0; + } + + //---------------------------------------------------------------------------- + /** + lua_CFunction to call a function with a return value. + + This is used for global functions, global properties, class static methods, + and class static properties. + + The function pointer is in the first upvalue. + */ + template <class FnPtr, + class ReturnType = typename FuncTraits <FnPtr>::ReturnType> + struct Call + { + typedef typename FuncTraits <FnPtr>::Params Params; + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList <Params> args (L); + Stack <typename FuncTraits <FnPtr>::ReturnType>::push (L, FuncTraits <FnPtr>::call (fnptr, args)); + return 1; + } + }; + + //---------------------------------------------------------------------------- + /** + lua_CFunction to call a function with no return value. + + This is used for global functions, global properties, class static methods, + and class static properties. + + The function pointer is in the first upvalue. + */ + template <class FnPtr> + struct Call <FnPtr, void> + { + typedef typename FuncTraits <FnPtr>::Params Params; + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList <Params> args (L); + FuncTraits <FnPtr>::call (fnptr, args); + return 0; + } + }; + + //---------------------------------------------------------------------------- + /** + lua_CFunction to call a class member function with a return value. + + The member function pointer is in the first upvalue. + The class userdata object is at the top of the Lua stack. + */ + template <class MemFnPtr, + class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType> + struct CallMember + { + typedef typename FuncTraits <MemFnPtr>::ClassType T; + typedef typename FuncTraits <MemFnPtr>::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T* const t = Userdata::get <T> (L, 1, false); + MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList <Params, 2> args (L); + Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args)); + return 1; + } + }; + + template <class MemFnPtr, + class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType> + struct CallConstMember + { + typedef typename FuncTraits <MemFnPtr>::ClassType T; + typedef typename FuncTraits <MemFnPtr>::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T const* const t = Userdata::get <T> (L, 1, true); + MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList <Params, 2> args(L); + Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args)); + return 1; + } + }; + + //---------------------------------------------------------------------------- + /** + lua_CFunction to call a class member function with no return value. + + The member function pointer is in the first upvalue. + The class userdata object is at the top of the Lua stack. + */ + template <class MemFnPtr> + struct CallMember <MemFnPtr, void> + { + typedef typename FuncTraits <MemFnPtr>::ClassType T; + typedef typename FuncTraits <MemFnPtr>::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T* const t = Userdata::get <T> (L, 1, false); + MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList <Params, 2> args (L); + FuncTraits <MemFnPtr>::call (t, fnptr, args); + return 0; + } + }; + + template <class MemFnPtr> + struct CallConstMember <MemFnPtr, void> + { + typedef typename FuncTraits <MemFnPtr>::ClassType T; + typedef typename FuncTraits <MemFnPtr>::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T const* const t = Userdata::get <T> (L, 1, true); + MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList <Params, 2> args (L); + FuncTraits <MemFnPtr>::call (t, fnptr, args); + return 0; + } + }; + + //-------------------------------------------------------------------------- + /** + lua_CFunction to call a class member lua_CFunction. + + The member function pointer is in the first upvalue. + The class userdata object is at the top of the Lua stack. + */ + template <class T> + struct CallMemberCFunction + { + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + typedef int (T::*MFP)(lua_State* L); + T* const t = Userdata::get <T> (L, 1, false); + MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + return (t->*fnptr) (L); + } + }; + + template <class T> + struct CallConstMemberCFunction + { + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + typedef int (T::*MFP)(lua_State* L); + T const* const t = Userdata::get <T> (L, 1, true); + MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + return (t->*fnptr) (L); + } + }; + + //-------------------------------------------------------------------------- + + // SFINAE Helpers + + template <class MemFnPtr, bool isConst> + struct CallMemberFunctionHelper + { + static void add (lua_State* L, char const* name, MemFnPtr mf) + { + new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); + lua_pushcclosure (L, &CallConstMember <MemFnPtr>::f, 1); + lua_pushvalue (L, -1); + rawsetfield (L, -5, name); // const table + rawsetfield (L, -3, name); // class table + } + }; + + template <class MemFnPtr> + struct CallMemberFunctionHelper <MemFnPtr, false> + { + static void add (lua_State* L, char const* name, MemFnPtr mf) + { + new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); + lua_pushcclosure (L, &CallMember <MemFnPtr>::f, 1); + rawsetfield (L, -3, name); // class table + } + }; + + //-------------------------------------------------------------------------- + /** + __gc metamethod for a class. + */ + template <class C> + static int gcMetaMethod (lua_State* L) + { + Userdata* const ud = Userdata::getExact <C> (L, 1); + ud->~Userdata (); + return 0; + } + + //-------------------------------------------------------------------------- + /** + lua_CFunction to get a class data member. + + The pointer-to-member is in the first upvalue. + The class userdata object is at the top of the Lua stack. + */ + template <class C, typename T> + static int getProperty (lua_State* L) + { + C const* const c = Userdata::get <C> (L, 1, true); + T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1))); + Stack <T>::push (L, c->**mp); + return 1; + } + + //-------------------------------------------------------------------------- + /** + lua_CFunction to set a class data member. + + The pointer-to-member is in the first upvalue. + The class userdata object is at the top of the Lua stack. + */ + template <class C, typename T> + static int setProperty (lua_State* L) + { + C* const c = Userdata::get <C> (L, 1, false); + T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1))); + c->**mp = Stack <T>::get (L, 2); + return 0; + } +}; diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/ClassInfo.h b/3rdparty/luabridge/Source/LuaBridge/detail/ClassInfo.h new file mode 100644 index 00000000000..8d580694777 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/ClassInfo.h @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +/** Unique Lua registry keys for a class. + + Each registered class inserts three keys into the registry, whose + values are the corresponding static, class, and const metatables. This + allows a quick and reliable lookup for a metatable from a template type. +*/ +template <class T> +class ClassInfo +{ +public: + /** Get the key for the static table. + + The static table holds the static data members, static properties, and + static member functions for a class. + */ + static void const* getStaticKey () + { + static char value; + return &value; + } + + /** Get the key for the class table. + + The class table holds the data members, properties, and member functions + of a class. Read-only data and properties, and const member functions are + also placed here (to save a lookup in the const table). + */ + static void const* getClassKey () + { + static char value; + return &value; + } + + /** Get the key for the const table. + + The const table holds read-only data members and properties, and const + member functions of a class. + */ + static void const* getConstKey () + { + static char value; + return &value; + } +}; + diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/Constructor.h b/3rdparty/luabridge/Source/LuaBridge/detail/Constructor.h new file mode 100644 index 00000000000..7b2dad05986 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/Constructor.h @@ -0,0 +1,204 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#ifndef LUABRIDGE_CONSTRUCTOR_HEADER +#define LUABRIDGE_CONSTRUCTOR_HEADER + +/* +* Constructor generators. These templates allow you to call operator new and +* pass the contents of a type/value list to the Constructor. Like the +* function pointer containers, these are only defined up to 8 parameters. +*/ + +/** Constructor generators. + + These templates call operator new with the contents of a type/value + list passed to the Constructor with up to 8 parameters. Two versions + of call() are provided. One performs a regular new, the other performs + a placement new. +*/ +template <class T, typename List> +struct Constructor {}; + +template <class T> +struct Constructor <T, None> +{ + static T* call (TypeListValues <None> const&) + { + return new T; + } + static T* call (void* mem, TypeListValues <None> const&) + { + return new (mem) T; + } +}; + +template <class T, class P1> +struct Constructor <T, TypeList <P1> > +{ + static T* call (const TypeListValues<TypeList <P1> > &tvl) + { + return new T(tvl.hd); + } + static T* call (void* mem, const TypeListValues<TypeList <P1> > &tvl) + { + return new (mem) T(tvl.hd); + } +}; + +template <class T, class P1, class P2> +struct Constructor <T, TypeList <P1, TypeList <P2> > > +{ + static T* call (const TypeListValues<TypeList <P1, TypeList <P2> > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd); + } + static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2> > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd); + } +}; + +template <class T, class P1, class P2, class P3> +struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3> > > > +{ + static T* call (const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3> > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3> > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } +}; + +template <class T, class P1, class P2, class P3, class P4> +struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3, + TypeList <P4> > > > > +{ + static T* call (const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4> > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4> > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } +}; + +template <class T, class P1, class P2, class P3, class P4, + class P5> +struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3, + TypeList <P4, TypeList <P5> > > > > > +{ + static T* call (const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4, TypeList <P5> > > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4, TypeList <P5> > > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class P1, class P2, class P3, class P4, + class P5, class P6> +struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3, + TypeList <P4, TypeList <P5, TypeList <P6> > > > > > > +{ + static T* call (const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class P1, class P2, class P3, class P4, + class P5, class P6, class P7> +struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3, + TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > > +{ + static T* call (const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, + TypeList <P7> > > > > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, + TypeList <P7> > > > > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class P1, class P2, class P3, class P4, + class P5, class P6, class P7, class P8> +struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3, + TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, + TypeList <P8> > > > > > > > > +{ + static T* call (const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, + TypeList <P7, TypeList <P8> > > > > > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2, + TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, + TypeList <P7, TypeList <P8> > > > > > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +#endif diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/FuncTraits.h b/3rdparty/luabridge/Source/LuaBridge/detail/FuncTraits.h new file mode 100644 index 00000000000..7eccb61832b --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/FuncTraits.h @@ -0,0 +1,852 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +/** + Since the throw specification is part of a function signature, the FuncTraits + family of templates needs to be specialized for both types. The + LUABRIDGE_THROWSPEC macro controls whether we use the 'throw ()' form, or + 'noexcept' (if C++11 is available) to distinguish the functions. +*/ +#if defined (__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__clang__) || defined(__GNUC__) || \ + (defined (_MSC_VER) && (_MSC_VER >= 1700)) +// Do not define LUABRIDGE_THROWSPEC since the Xcode and gcc compilers do not +// distinguish the throw specification in the function signature. +#else +// Visual Studio 10 and earlier pay too much mind to useless throw() spec. +// +# define LUABRIDGE_THROWSPEC throw() +#endif + +//============================================================================== +/** + Traits for function pointers. + + There are three types of functions: global, non-const member, and const + member. These templates determine the type of function, which class type it + belongs to if it is a class member, the const-ness if it is a member + function, and the type information for the return value and argument list. + + Expansions are provided for functions with up to 8 parameters. This can be + manually extended, or expanded to an arbitrary amount using C++11 features. +*/ +template <class MemFn, class D = MemFn> +struct FuncTraits +{ +}; + +/* Ordinary function pointers. */ + +template <class R, class D> +struct FuncTraits <R (*) (), D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef None Params; + static R call (D fp, TypeListValues <Params>) + { + return fp (); + } +}; + +template <class R, class P1, class D> +struct FuncTraits <R (*) (P1), D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1> Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd); + } +}; + +template <class R, class P1, class P2, class D> +struct FuncTraits <R (*) (P1, P2), D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2> > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class D> +struct FuncTraits <R (*) (P1, P2, P3), D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4), D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class P5, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4, P5), D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6), D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7), D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7, P8), D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +/* Non-const member function pointers. */ + +template <class T, class R, class D> +struct FuncTraits <R (T::*) (), D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef None Params; + static R call (T* obj, D fp, TypeListValues <Params>) + { + return (obj->*fp)(); + } +}; + +template <class T, class R, class P1, class D> +struct FuncTraits <R (T::*) (P1), D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1> Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd); + } +}; + +template <class T, class R, class P1, class P2, class D> +struct FuncTraits <R (T::*) (P1, P2), D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2> > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class D> +struct FuncTraits <R (T::*) (P1, P2, P3), D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4), D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5), D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6), D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7), D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8), D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +/* Const member function pointers. */ + +template <class T, class R, class D> +struct FuncTraits <R (T::*) () const, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef None Params; + static R call (T const* obj, D fp, TypeListValues <Params>) + { + return (obj->*fp)(); + } +}; + +template <class T, class R, class P1, class D> +struct FuncTraits <R (T::*) (P1) const, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1> Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd); + } +}; + +template <class T, class R, class P1, class P2, class D> +struct FuncTraits <R (T::*) (P1, P2) const, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2> > Params; + static R call (T const* obj, R (T::*fp) (P1, P2) const, + TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class D> +struct FuncTraits <R (T::*) (P1, P2, P3) const, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4) const, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) const, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) const, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) const, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) const, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +#if defined (LUABRIDGE_THROWSPEC) + +/* Ordinary function pointers. */ + +template <class R, class D> +struct FuncTraits <R (*) () LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef None Params; + static R call (D fp, TypeListValues <Params> const&) + { + return fp (); + } +}; + +template <class R, class P1, class D> +struct FuncTraits <R (*) (P1) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1> Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd); + } +}; + +template <class R, class P1, class P2, class D> +struct FuncTraits <R (*) (P1, P2) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2> > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class D> +struct FuncTraits <R (*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class P5, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> +struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; + static R call (D fp, TypeListValues <Params> tvl) + { + return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +/* Non-const member function pointers with THROWSPEC. */ + +template <class T, class R, class D> +struct FuncTraits <R (T::*) () LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef None Params; + static R call (T* obj, D fp, TypeListValues <Params> const&) + { + return (obj->*fp)(); + } +}; + +template <class T, class R, class P1, class D> +struct FuncTraits <R (T::*) (P1) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1> Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd); + } +}; + +template <class T, class R, class P1, class P2, class D> +struct FuncTraits <R (T::*) (P1, P2) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2> > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class D> +struct FuncTraits <R (T::*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; + static R call (T* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +/* Const member function pointers with THROWSPEC. */ + +template <class T, class R, class D> +struct FuncTraits <R (T::*) () const LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef None Params; + static R call (T const* obj, D fp, TypeListValues <Params>) + { + return (obj->*fp)(); + } +}; + +template <class T, class R, class P1, class D> +struct FuncTraits <R (T::*) (P1) const LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1> Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd); + } +}; + +template <class T, class R, class P1, class P2, class D> +struct FuncTraits <R (T::*) (P1, P2) const LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2> > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class D> +struct FuncTraits <R (T::*) (P1, P2, P3) const LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4) const LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) const LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) const LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) const LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> +struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) const LUABRIDGE_THROWSPEC, D> +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; + static R call (T const* obj, D fp, TypeListValues <Params> tvl) + { + return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +#endif diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/Iterator.h b/3rdparty/luabridge/Source/LuaBridge/detail/Iterator.h new file mode 100644 index 00000000000..d883fb3989a --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/Iterator.h @@ -0,0 +1,114 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +/** Allows table iteration. +*/ +class Iterator +{ +private: + lua_State* m_L; + LuaRef m_table; + LuaRef m_key; + LuaRef m_value; + + void next () + { + m_table.push(m_L); + m_key.push (m_L); + if (lua_next (m_L, -2)) + { + m_value.pop (m_L); + m_key.pop (m_L); + } + else + { + m_key = Nil(); + m_value = Nil(); + } + lua_pop(m_L, 1); + } + +public: + explicit Iterator (LuaRef table) + : m_L (table.state ()) + , m_table (table) + , m_key (table.state ()) // m_key is nil + , m_value (table.state ()) // m_value is nil + { + next (); // get the first (key, value) pair from table + } + + lua_State* state () const + { + return m_L; + } + + LuaRef operator* () const + { + return m_value; + } + + LuaRef operator-> () const + { + return m_value; + } + + Iterator& operator++ () + { + if (isNil()) + { + // if the iterator reaches the end, do nothing + return *this; + } + else + { + next(); + return *this; + } + } + + inline bool isNil () const + { + return m_key.isNil (); + } + + inline LuaRef key () const + { + return m_key; + } + + inline LuaRef value () const + { + return m_value; + } + +private: + // Don't use postfix increment, it is less efficient + Iterator operator++ (int); +}; + diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/LuaException.h b/3rdparty/luabridge/Source/LuaBridge/detail/LuaException.h new file mode 100644 index 00000000000..a0944961ced --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/LuaException.h @@ -0,0 +1,113 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com> + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +class LuaException : public std::exception +{ +private: + lua_State* m_L; + std::string m_what; + +public: + //---------------------------------------------------------------------------- + /** + Construct a LuaException after a lua_pcall(). + */ + LuaException (lua_State* L, int /*code*/) + : m_L (L) + { + whatFromStack (); + } + + //---------------------------------------------------------------------------- + + LuaException (lua_State *L, + char const*, + char const*, + long) + : m_L (L) + { + whatFromStack (); + } + + //---------------------------------------------------------------------------- + + ~LuaException() throw () + { + } + + //---------------------------------------------------------------------------- + + char const* what() const throw () + { + return m_what.c_str(); + } + + //============================================================================ + /** + Throw an exception. + + This centralizes all the exceptions thrown, so that we can set + breakpoints before the stack is unwound, or otherwise customize the + behavior. + */ + template <class Exception> + static void Throw (Exception e) + { + throw e; + } + + //---------------------------------------------------------------------------- + /** + Wrapper for lua_pcall that throws. + */ + static void pcall (lua_State* L, int nargs = 0, int nresults = 0, int msgh = 0) + { + int code = lua_pcall (L, nargs, nresults, msgh); + + if (code != LUABRIDGE_LUA_OK) + Throw (LuaException (L, code)); + } + + //---------------------------------------------------------------------------- + +protected: + void whatFromStack () + { + if (lua_gettop (m_L) > 0) + { + char const* s = lua_tostring (m_L, -1); + m_what = s ? s : ""; + } + else + { + // stack is empty + m_what = "missing error"; + } + } +}; diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/LuaHelpers.h b/3rdparty/luabridge/Source/LuaBridge/detail/LuaHelpers.h new file mode 100644 index 00000000000..7bc84eb1642 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/LuaHelpers.h @@ -0,0 +1,143 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +// These are for Lua versions prior to 5.2.0. +// +#if LUA_VERSION_NUM < 502 +inline int lua_absindex (lua_State* L, int idx) +{ + if (idx > LUA_REGISTRYINDEX && idx < 0) + return lua_gettop (L) + idx + 1; + else + return idx; +} + +inline void lua_rawgetp (lua_State* L, int idx, void const* p) +{ + idx = lua_absindex (L, idx); + lua_pushlightuserdata (L, const_cast <void*> (p)); + lua_rawget (L,idx); +} + +inline void lua_rawsetp (lua_State* L, int idx, void const* p) +{ + idx = lua_absindex (L, idx); + lua_pushlightuserdata (L, const_cast <void*> (p)); + // put key behind value + lua_insert (L, -2); + lua_rawset (L, idx); +} + +#define LUA_OPEQ 1 +#define LUA_OPLT 2 +#define LUA_OPLE 3 + +inline int lua_compare (lua_State* L, int idx1, int idx2, int op) +{ + switch (op) + { + case LUA_OPEQ: + return lua_equal (L, idx1, idx2); + break; + + case LUA_OPLT: + return lua_lessthan (L, idx1, idx2); + break; + + case LUA_OPLE: + return lua_equal (L, idx1, idx2) || lua_lessthan (L, idx1, idx2); + break; + + default: + return 0; + }; +} + +inline int get_length (lua_State* L, int idx) +{ + return int (lua_objlen (L, idx)); +} + +#else +inline int get_length (lua_State* L, int idx) +{ + lua_len (L, idx); + int len = int (luaL_checknumber (L, -1)); + lua_pop (L, 1); + return len; +} + +#endif + +#ifndef LUA_OK +# define LUABRIDGE_LUA_OK 0 +#else +# define LUABRIDGE_LUA_OK LUA_OK +#endif + +/** Get a table value, bypassing metamethods. +*/ +inline void rawgetfield (lua_State* L, int index, char const* key) +{ + assert (lua_istable (L, index)); + index = lua_absindex (L, index); + lua_pushstring (L, key); + lua_rawget (L, index); +} + +/** Set a table value, bypassing metamethods. +*/ +inline void rawsetfield (lua_State* L, int index, char const* key) +{ + assert (lua_istable (L, index)); + index = lua_absindex (L, index); + lua_pushstring (L, key); + lua_insert (L, -2); + lua_rawset (L, index); +} + +/** Returns true if the value is a full userdata (not light). +*/ +inline bool isfulluserdata (lua_State* L, int index) +{ + return lua_isuserdata (L, index) && !lua_islightuserdata (L, index); +} + +/** Test lua_State objects for global equality. + + This can determine if two different lua_State objects really point + to the same global state, such as when using coroutines. + + @note This is used for assertions. +*/ +inline bool equalstates (lua_State* L1, lua_State* L2) +{ + return lua_topointer (L1, LUA_REGISTRYINDEX) == + lua_topointer (L2, LUA_REGISTRYINDEX); +} diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/LuaRef.h b/3rdparty/luabridge/Source/LuaBridge/detail/LuaRef.h new file mode 100644 index 00000000000..e726bcafe7b --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/LuaRef.h @@ -0,0 +1,1215 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com> + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +//------------------------------------------------------------------------------ +/** + Type tag for representing LUA_TNIL. + + Construct one of these using `Nil()` to represent a Lua nil. This is faster + than creating a reference in the registry to nil. Example: + + LuaRef t (LuaRef::createTable (L)); + ... + t ["k"] = Nil(); // assign nil +*/ +struct Nil +{ +}; + +//------------------------------------------------------------------------------ +/** + Lightweight reference to a Lua object. + + The reference is maintained for the lifetime of the C++ object. +*/ +class LuaRef +{ +private: + class Proxy; + friend struct Stack <Proxy>; + + //---------------------------------------------------------------------------- + /** + Pop the Lua stack. + + Pops the specified number of stack items on destruction. We use this + when returning objects, to avoid an explicit temporary variable, since + the destructor executes after the return statement. For example: + + template <class U> + U cast (lua_State* L) + { + StackPop p (L, 1); + ... + return U (); // dtor called after this line + } + + @note The `StackPop` object must always be a named local variable. + */ + class StackPop + { + public: + /** Create a StackPop object. + + @param count The number of stack entries to pop on destruction. + */ + StackPop (lua_State* L, int count) + : m_L (L) + , m_count (count) + { + } + + ~StackPop () + { + lua_pop (m_L, m_count); + } + + private: + lua_State* m_L; + int m_count; + }; + + //---------------------------------------------------------------------------- + /** + A proxy for representing table values. + */ + class Proxy + { + private: + lua_State* m_L; + int m_tableRef; + int m_keyRef; + + public: + //-------------------------------------------------------------------------- + /** + Construct a Proxy from a table value. + + The table is in the registry, and the key is at the top of the stack. + The key is popped off the stack. + */ + Proxy (lua_State* L, int tableRef) + : m_L (L) + , m_tableRef (tableRef) + , m_keyRef (luaL_ref (L, LUA_REGISTRYINDEX)) + { + } + + //-------------------------------------------------------------------------- + /** + Create a Proxy via copy constructor. + + It is best to avoid code paths that invoke this, because it creates + an extra temporary Lua reference. Typically this is done by passing + the Proxy parameter as a `const` reference. + */ + Proxy (Proxy const& other) + : m_L (other.m_L) + , m_tableRef (other.m_tableRef) + { + // If this assert goes off it means code is taking this path, + // which is better avoided. + // + assert (0); + + lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_keyRef); + m_keyRef = luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + //-------------------------------------------------------------------------- + /** + Destroy the proxy. + + This does not destroy the table value. + */ + ~Proxy () + { + luaL_unref (m_L, LUA_REGISTRYINDEX, m_keyRef); + } + + //-------------------------------------------------------------------------- + /** + Return a reference to the table value. + */ + int createRef () const + { + push (m_L); + return luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + //-------------------------------------------------------------------------- + /** + Assign a new value to this table key. + + This may invoke metamethods. + */ + template <class T> + Proxy& operator= (T v) + { + StackPop p (m_L, 1); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); + Stack <T>::push (m_L, v); + lua_rawset (m_L, -3); + return *this; + } + + //-------------------------------------------------------------------------- + /** + Assign a new value to this table key. + + The assignment is raw, no metamethods are invoked. + */ + template <class T> + Proxy& rawset (T v) + { + StackPop p (m_L, 1); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); + Stack <T>::push (m_L, v); + lua_settable (m_L, -3); + return *this; + } + + //========================================================================== + // + // This group of member functions mirrors the member functions in LuaRef. + + /** Retrieve the lua_State associated with the table value. + */ + lua_State* state () const + { + return m_L; + } + + //-------------------------------------------------------------------------- + /** + Push the value onto the Lua stack. + */ + void push (lua_State* L) const + { + assert (equalstates (L, m_L)); + lua_rawgeti (L, LUA_REGISTRYINDEX, m_tableRef); + lua_rawgeti (L, LUA_REGISTRYINDEX, m_keyRef); + lua_gettable (L, -2); + lua_remove (L, -2); // remove the table + } + + //-------------------------------------------------------------------------- + /** + Determine the object type. + + The return values are the same as for `lua_type`. + */ + int type () const + { + int result; + push (m_L); + result = lua_type (m_L, -1); + lua_pop (m_L, 1); + return result; + } + + inline bool isNil () const { return type () == LUA_TNIL; } + inline bool isNumber () const { return type () == LUA_TNUMBER; } + inline bool isString () const { return type () == LUA_TSTRING; } + inline bool isTable () const { return type () == LUA_TTABLE; } + inline bool isFunction () const { return type () == LUA_TFUNCTION; } + inline bool isUserdata () const { return type () == LUA_TUSERDATA; } + inline bool isThread () const { return type () == LUA_TTHREAD; } + inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; } + + //-------------------------------------------------------------------------- + /** + Perform an explicit conversion. + */ + template <class T> + T cast () const + { + StackPop p (m_L, 1); + push (m_L); + + // lua_gettop is used because Userdata::getClass() doesn't handle + // negative stack indexes. + // + return Stack <T>::get (m_L, lua_gettop (m_L)); + } + + //-------------------------------------------------------------------------- + /** + Universal implicit conversion operator. + + NOTE: Visual Studio 2010 and 2012 have a bug where this function + is not used. See: + + http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014 + https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile + + // This code snippet fails to compile in vs2010,vs2012 + struct S { + template <class T> inline operator T () const { return T (); } + }; + int main () { + S () || false; + return 0; + } + */ + template <class T> + inline operator T () const + { + return cast <T> (); + } + + //-------------------------------------------------------------------------- + /** + Universal comparison operators. + */ + /** @{ */ + template <class T> + bool operator== (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1; + } + + template <class T> + bool operator< (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -2, -1, LUA_OPLT) == 1; + } + + template <class T> + bool operator<= (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -2, -1, LUA_OPLE) == 1; + } + + template <class T> + bool operator> (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -1, -2, LUA_OPLT) == 1; + } + + template <class T> + bool operator>= (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -1, -2, LUA_OPLE) == 1; + } + + template <class T> + bool rawequal (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_rawequal (m_L, -1, -2) == 1; + } + /** @} */ + + //-------------------------------------------------------------------------- + /** + Access a table value using a key. + + This invokes metamethods. + */ + template <class T> + Proxy operator[] (T key) const + { + return LuaRef (*this) [key]; + } + + //-------------------------------------------------------------------------- + /** + Access a table value using a key. + + The operation is raw, metamethods are not invoked. The result is + passed by value and may not be modified. + */ + template <class T> + LuaRef rawget (T key) const + { + StackPop (m_L, 1); + push (m_L); + Stack <T>::push (m_L, key); + lua_rawget (m_L, -2); + return LuaRef (m_L, FromStack ()); + } + + //-------------------------------------------------------------------------- + /** + Append a value to the table. + + If the table is a sequence this will add another element to it. + */ + template <class T> + void append (T v) const + { + push (m_L); + Stack <T>::push (m_L, v); + luaL_ref (m_L, -2); + lua_pop (m_L, 1); + } + + //-------------------------------------------------------------------------- + /** + Call the length operator. + + This is identical to applying the Lua # operator. + */ + int length () const + { + StackPop p (m_L, 1); + push (m_L); + return get_length (m_L, -1); + } + + //-------------------------------------------------------------------------- + /** + Call Lua code. + + These overloads allow Lua code to be called with up to 8 parameters. + The return value is provided as a LuaRef (which may be LUA_REFNIL). + If an error occurs, a LuaException is thrown. + */ + /** @{ */ + LuaRef const operator() () const + { + push (m_L); + LuaException::pcall (m_L, 0, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1> + LuaRef const operator() (P1 p1) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + LuaException::pcall (m_L, 1, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2> + LuaRef const operator() (P1 p1, P2 p2) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + LuaException::pcall (m_L, 2, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3> + LuaRef const operator() (P1 p1, P2 p2, P3 p3) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + LuaException::pcall (m_L, 3, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + LuaException::pcall (m_L, 4, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4, class P5> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + Stack <P5>::push (m_L, p5); + LuaException::pcall (m_L, 5, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4, class P5, class P6> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + Stack <P5>::push (m_L, p5); + Stack <P6>::push (m_L, p6); + LuaException::pcall (m_L, 6, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4, class P5, class P6, class P7> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + Stack <P5>::push (m_L, p5); + Stack <P6>::push (m_L, p6); + Stack <P7>::push (m_L, p7); + LuaException::pcall (m_L, 7, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + Stack <P5>::push (m_L, p5); + Stack <P6>::push (m_L, p6); + Stack <P7>::push (m_L, p7); + Stack <P8>::push (m_L, p8); + LuaException::pcall (m_L, 8, 1); + return LuaRef (m_L, FromStack ()); + } + /** @} */ + + //========================================================================== + }; + +private: + friend struct Stack <LuaRef>; + + //---------------------------------------------------------------------------- + /** + Type tag for stack construction. + */ + struct FromStack { }; + + //---------------------------------------------------------------------------- + /** + Create a reference to an object at the top of the Lua stack and pop it. + + This constructor is private and not invoked directly. + Instead, use the `fromStack` function. + + @note The object is popped. + */ + LuaRef (lua_State* L, FromStack) + : m_L (L) + { + m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + //---------------------------------------------------------------------------- + /** + Create a reference to an object on the Lua stack. + + This constructor is private and not invoked directly. + Instead, use the `fromStack` function. + + @note The object is not popped. + */ + LuaRef (lua_State* L, int index, FromStack) + : m_L (L) + { + lua_pushvalue (m_L, index); + m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + //---------------------------------------------------------------------------- + + // This type of construction is disallowed, since we don't have a `lua_State`. + // + template <class T> + LuaRef (T) + { + } + + //---------------------------------------------------------------------------- + /** + Create a reference to this ref. + + This is used internally. + */ + int createRef () const + { + if (m_ref != LUA_REFNIL) + { + push (m_L); + return luaL_ref (m_L, LUA_REGISTRYINDEX); + } + else + { + return LUA_REFNIL; + } + } + +public: + //---------------------------------------------------------------------------- + /** + Create a nil reference. + + The LuaRef may be assigned later. + */ + LuaRef (lua_State* L) + : m_L (L) + , m_ref (LUA_REFNIL) + { + } + + //---------------------------------------------------------------------------- + /** + Create a reference to a value. + */ + template <class T> + LuaRef (lua_State* L, T v) + : m_L (L) + { + Stack <T>::push (m_L, v); + m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + //---------------------------------------------------------------------------- + /** + Create a reference to a table value. + */ + LuaRef (Proxy const& v) + : m_L (v.state ()) + , m_ref (v.createRef ()) + { + } + + //---------------------------------------------------------------------------- + /** + Create a new reference to an existing reference. + */ + LuaRef (LuaRef const& other) + : m_L (other.m_L) + , m_ref (other.createRef ()) + { + } + + //---------------------------------------------------------------------------- + /** + Destroy a reference. + + The corresponding Lua registry reference will be released. + + @note If the state refers to a thread, it is the responsibility of the + caller to ensure that the thread still exists when the LuaRef + is destroyed. + */ + ~LuaRef () + { + luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); + } + + //---------------------------------------------------------------------------- + /** + Return a LuaRef from a stack item. + + The stack item is not popped. + */ + static LuaRef fromStack (lua_State* L, int index) + { + lua_pushvalue (L, index); + return LuaRef (L, FromStack ()); + } + + //---------------------------------------------------------------------------- + /** + Create a new empty table and return a reference to it. + + It is also possible to use the free function `newTable`. + + @see ::getGlobal + */ + static LuaRef newTable (lua_State* L) + { + lua_newtable (L); + return LuaRef (L, FromStack ()); + } + + //---------------------------------------------------------------------------- + /** + Return a reference to a named global. + + It is also possible to use the free function `getGlobal`. + + @see ::getGlobal + */ + static LuaRef getGlobal (lua_State *L, char const* name) + { + lua_getglobal (L, name); + return LuaRef (L, FromStack ()); + } + + //---------------------------------------------------------------------------- + /** + Assign a different value to this LuaRef. + */ + template <class T> + LuaRef& operator= (T rhs) + { + luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); + Stack <T>::push (m_L, rhs); + m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); + return *this; + } + + //---------------------------------------------------------------------------- + /** + Assign another LuaRef to this LuaRef. + */ + LuaRef& operator= (LuaRef const& rhs) + { + luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); + rhs.push (m_L); + m_L = rhs.state (); + m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); + return *this; + } + + //---------------------------------------------------------------------------- + /** + converts to a string using luas tostring function + */ + std::string tostring() const + { + lua_getglobal (m_L, "tostring"); + push (m_L); + lua_call (m_L, 1, 1); + const char* str = lua_tostring(m_L, 1); + lua_pop(m_L, 1); + return std::string(str); + } + + //---------------------------------------------------------------------------- + /** + Print a text description of the value to a stream. + + This is used for diagnostics. + */ + void print (std::ostream& os) const + { + switch (type ()) + { + case LUA_TNIL: + os << "nil"; + break; + + case LUA_TNUMBER: + os << cast <lua_Number> (); + break; + + case LUA_TBOOLEAN: + os << (cast <bool> () ? "true" : "false"); + break; + + case LUA_TSTRING: + os << '"' << cast <std::string> () << '"'; + break; + + case LUA_TTABLE: + os << "table: " << tostring(); + break; + + case LUA_TFUNCTION: + os << "function: " << tostring(); + break; + + case LUA_TUSERDATA: + os << "userdata: " << tostring(); + break; + + case LUA_TTHREAD: + os << "thread: " << tostring(); + break; + + case LUA_TLIGHTUSERDATA: + os << "lightuserdata: " << tostring(); + break; + + default: + os << "unknown"; + break; + } + } + + //============================================================================ + // + // This group of member functions is mirrored in Proxy + // + + /** Retrieve the lua_State associated with the reference. + */ + lua_State* state () const + { + return m_L; + } + + //---------------------------------------------------------------------------- + /** + Place the object onto the Lua stack. + */ + void push (lua_State* L) const + { + assert (equalstates (L, m_L)); + lua_rawgeti (L, LUA_REGISTRYINDEX, m_ref); + } + + //---------------------------------------------------------------------------- + /** + Pop the top of Lua stack and assign the ref to m_ref + */ + void pop (lua_State* L) + { + assert (equalstates (L, m_L)); + luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); + m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + //---------------------------------------------------------------------------- + /** + Determine the object type. + + The return values are the same as for `lua_type`. + */ + /** @{ */ + int type () const + { + int result; + if (m_ref != LUA_REFNIL) + { + push (m_L); + result = lua_type (m_L, -1); + lua_pop (m_L, 1); + } + else + { + result = LUA_TNIL; + } + + return result; + } + + // should never happen + //inline bool isNone () const { return m_ref == LUA_NOREF; } + + inline bool isNil () const { return type () == LUA_TNIL; } + inline bool isNumber () const { return type () == LUA_TNUMBER; } + inline bool isString () const { return type () == LUA_TSTRING; } + inline bool isTable () const { return type () == LUA_TTABLE; } + inline bool isFunction () const { return type () == LUA_TFUNCTION; } + inline bool isUserdata () const { return type () == LUA_TUSERDATA; } + inline bool isThread () const { return type () == LUA_TTHREAD; } + inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; } + /** @} */ + + //---------------------------------------------------------------------------- + /** + Perform an explicit conversion. + */ + template <class T> + T cast () const + { + StackPop p (m_L, 1); + push (m_L); + + // lua_gettop is used because Userdata::getClass() doesn't handle + // negative stack indexes. + // + return Stack <T>::get (m_L, lua_gettop (m_L)); + } + + //---------------------------------------------------------------------------- + /** + Universal implicit conversion operator. + + NOTE: Visual Studio 2010 and 2012 have a bug where this function + is not used. See: + + http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014 + https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile + + // This code snippet fails to compile in vs2010,vs2012 + struct S { + template <class T> inline operator T () const { return T (); } + }; + int main () { + S () || false; + return 0; + } + */ + template <class T> + inline operator T () const + { + return cast <T> (); + } + + //---------------------------------------------------------------------------- + /** + Universal comparison operators. + */ + /** @{ */ + template <class T> + bool operator== (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1; + } + + template <class T> + bool operator< (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -2, -1, LUA_OPLT) == 1; + } + + template <class T> + bool operator<= (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -2, -1, LUA_OPLE) == 1; + } + + template <class T> + bool operator> (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -1, -2, LUA_OPLT) == 1; + } + + template <class T> + bool operator>= (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_compare (m_L, -1, -2, LUA_OPLE) == 1; + } + + template <class T> + bool rawequal (T rhs) const + { + StackPop p (m_L, 2); + push (m_L); + Stack <T>::push (m_L, rhs); + return lua_rawequal (m_L, -1, -2) == 1; + } + /** @} */ + + //---------------------------------------------------------------------------- + /** + Append a value to the table. + + If the table is a sequence this will add another element to it. + */ + template <class T> + void append (T v) const + { + push (m_L); + Stack <T>::push (m_L, v); + luaL_ref (m_L, -2); + lua_pop (m_L, 1); + } + + //---------------------------------------------------------------------------- + /** + Call the length operator. + + This is identical to applying the Lua # operator. + */ + int length () const + { + StackPop p (m_L, 1); + push (m_L); + return get_length (m_L, -1); + } + + //---------------------------------------------------------------------------- + /** + Access a table value using a key. + + This invokes metamethods. + */ + template <class T> + Proxy operator[] (T key) const + { + Stack <T>::push (m_L, key); + return Proxy (m_L, m_ref); + } + + //---------------------------------------------------------------------------- + /** + Call Lua code. + + These overloads allow Lua code to be called with up to 8 parameters. + The return value is provided as a LuaRef (which may be LUA_REFNIL). + If an error occurs, a LuaException is thrown. + */ + /** @{ */ + LuaRef const operator() () const + { + push (m_L); + LuaException::pcall (m_L, 0, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1> + LuaRef const operator() (P1 p1) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + LuaException::pcall (m_L, 1, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2> + LuaRef const operator() (P1 p1, P2 p2) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + LuaException::pcall (m_L, 2, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3> + LuaRef const operator() (P1 p1, P2 p2, P3 p3) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + LuaException::pcall (m_L, 3, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + LuaException::pcall (m_L, 4, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4, class P5> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + Stack <P5>::push (m_L, p5); + LuaException::pcall (m_L, 5, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4, class P5, class P6> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + Stack <P5>::push (m_L, p5); + Stack <P6>::push (m_L, p6); + LuaException::pcall (m_L, 6, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4, class P5, class P6, class P7> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + Stack <P5>::push (m_L, p5); + Stack <P6>::push (m_L, p6); + Stack <P7>::push (m_L, p7); + LuaException::pcall (m_L, 7, 1); + return LuaRef (m_L, FromStack ()); + } + + template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> + LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const + { + push (m_L); + Stack <P1>::push (m_L, p1); + Stack <P2>::push (m_L, p2); + Stack <P3>::push (m_L, p3); + Stack <P4>::push (m_L, p4); + Stack <P5>::push (m_L, p5); + Stack <P6>::push (m_L, p6); + Stack <P7>::push (m_L, p7); + Stack <P8>::push (m_L, p8); + LuaException::pcall (m_L, 8, 1); + return LuaRef (m_L, FromStack ()); + } + /** @} */ + + //============================================================================ + +private: + lua_State* m_L; + int m_ref; +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for Nil +*/ +template <> +struct Stack <Nil> +{ +public: + static inline void push (lua_State* L, Nil) + { + lua_pushnil (L); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for LuaRef. +*/ +template <> +struct Stack <LuaRef> +{ +public: + // The value is const& to prevent a copy construction. + // + static inline void push (lua_State* L, LuaRef const& v) + { + v.push (L); + } + + static inline LuaRef get (lua_State* L, int index) + { + return LuaRef (L, index, LuaRef::FromStack ()); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for Proxy. +*/ +template <> +struct Stack <LuaRef::Proxy> +{ +public: + // The value is const& to prevent a copy construction. + // + static inline void push (lua_State* L, LuaRef::Proxy const& v) + { + v.push (L); + } +}; + +//------------------------------------------------------------------------------ +/** + Create a reference to a new, empty table. + + This is a syntactic abbreviation for LuaRef::newTable(). +*/ +inline LuaRef newTable (lua_State* L) +{ + return LuaRef::newTable (L); +} + +//------------------------------------------------------------------------------ +/** + Create a reference to a value in the global table. + + This is a syntactic abbreviation for LuaRef::getGlobal(). +*/ +inline LuaRef getGlobal (lua_State *L, char const* name) +{ + return LuaRef::getGlobal (L, name); +} + +//------------------------------------------------------------------------------ +/** + Write a LuaRef to a stream. + + This allows LuaRef and table proxies to work with streams. +*/ +inline std::ostream& operator<< (std::ostream& os, LuaRef const& ref) +{ + ref.print (os); + return os; +} + +//------------------------------------------------------------------------------ + +// more C++-like cast syntax +// +template<class T> +inline T LuaRef_cast(LuaRef const& lr) +{ + return lr.cast<T>(); +} diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/Namespace.h b/3rdparty/luabridge/Source/LuaBridge/detail/Namespace.h new file mode 100644 index 00000000000..ff22e6b092c --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/Namespace.h @@ -0,0 +1,1136 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +/** Provides C++ to Lua registration capabilities. + + This class is not instantiated directly, call `getGlobalNamespace` to start + the registration process. +*/ +class Namespace +{ +private: + Namespace& operator= (Namespace const& other); + + lua_State* const L; + int mutable m_stackSize; + +private: + //============================================================================ + /** + Error reporting. + + VF: This function looks handy, why aren't we using it? + */ +#if 0 + static int luaError (lua_State* L, std::string message) + { + assert (lua_isstring (L, lua_upvalueindex (1))); + std::string s; + + // Get information on the caller's caller to format the message, + // so the error appears to originate from the Lua source. + lua_Debug ar; + int result = lua_getstack (L, 2, &ar); + if (result != 0) + { + lua_getinfo (L, "Sl", &ar); + s = ar.short_src; + if (ar.currentline != -1) + { + // poor mans int to string to avoid <strstrream>. + lua_pushnumber (L, ar.currentline); + s = s + ":" + lua_tostring (L, -1) + ": "; + lua_pop (L, 1); + } + } + + s = s + message; + + return luaL_error (L, s.c_str ()); + } +#endif + + //---------------------------------------------------------------------------- + /** + Pop the Lua stack. + */ + void pop (int n) const + { + if (m_stackSize >= n && lua_gettop (L) >= n) + { + lua_pop (L, n); + m_stackSize -= n; + } + else + { + throw std::logic_error ("invalid stack"); + } + } + +private: + /** + Factored base to reduce template instantiations. + */ + class ClassBase + { + private: + ClassBase& operator= (ClassBase const& other); + + protected: + friend class Namespace; + + lua_State* const L; + int mutable m_stackSize; + + protected: + //-------------------------------------------------------------------------- + /** + __index metamethod for a class. + + This implements member functions, data members, and property members. + Functions are stored in the metatable and const metatable. Data members + and property members are in the __propget table. + + If the key is not found, the search proceeds up the hierarchy of base + classes. + */ + static int indexMetaMethod (lua_State* L) + { + int result = 0; + + assert (lua_isuserdata (L, 1)); // warn on security bypass + lua_getmetatable (L, 1); // get metatable for object + for (;;) + { + lua_pushvalue (L, 2); // push key arg2 + lua_rawget (L, -2); // lookup key in metatable + if (lua_iscfunction (L, -1)) // ensure its a cfunction + { + lua_remove (L, -2); // remove metatable + result = 1; + break; + } + else if (lua_isnil (L, -1)) + { + lua_pop (L, 1); + } + else + { + lua_pop (L, 2); + throw std::logic_error ("not a cfunction"); + } + + rawgetfield (L, -1, "__propget"); // get __propget table + if (lua_istable (L, -1)) // ensure it is a table + { + lua_pushvalue (L, 2); // push key arg2 + lua_rawget (L, -2); // lookup key in __propget + lua_remove (L, -2); // remove __propget + if (lua_iscfunction (L, -1)) // ensure its a cfunction + { + lua_remove (L, -2); // remove metatable + lua_pushvalue (L, 1); // push class arg1 + lua_call (L, 1, 1); + result = 1; + break; + } + else if (lua_isnil (L, -1)) + { + lua_pop (L, 1); + } + else + { + lua_pop (L, 2); + + // We only put cfunctions into __propget. + throw std::logic_error ("not a cfunction"); + } + } + else + { + lua_pop (L, 2); + + // __propget is missing, or not a table. + throw std::logic_error ("missing __propget table"); + } + + // Repeat the lookup in the __parent metafield, + // or return nil if the field doesn't exist. + rawgetfield (L, -1, "__parent"); + if (lua_istable (L, -1)) + { + // Remove metatable and repeat the search in __parent. + lua_remove (L, -2); + } + else if (lua_isnil (L, -1)) + { + result = 1; + break; + } + else + { + lua_pop (L, 2); + + throw std::logic_error ("__parent is not a table"); + } + } + + return result; + } + + //-------------------------------------------------------------------------- + /** + __newindex metamethod for classes. + + This supports writable variables and properties on class objects. The + corresponding object is passed in the first parameter to the set function. + */ + static int newindexMetaMethod (lua_State* L) + { + int result = 0; + + lua_getmetatable (L, 1); + + for (;;) + { + // Check __propset + rawgetfield (L, -1, "__propset"); + if (!lua_isnil (L, -1)) + { + lua_pushvalue (L, 2); + lua_rawget (L, -2); + if (!lua_isnil (L, -1)) + { + // found it, call the setFunction. + assert (lua_isfunction (L, -1)); + lua_pushvalue (L, 1); + lua_pushvalue (L, 3); + lua_call (L, 2, 0); + result = 0; + break; + } + lua_pop (L, 1); + } + lua_pop (L, 1); + + // Repeat the lookup in the __parent metafield. + rawgetfield (L, -1, "__parent"); + if (lua_isnil (L, -1)) + { + // Either the property or __parent must exist. + result = luaL_error (L, + "no member named '%s'", lua_tostring (L, 2)); + } + lua_remove (L, -2); + } + + return result; + } + + //-------------------------------------------------------------------------- + /** + Create the const table. + */ + void createConstTable (char const* name) + { + lua_newtable (L); + lua_pushvalue (L, -1); + lua_setmetatable (L, -2); + lua_pushboolean (L, 1); + lua_rawsetp (L, -2, getIdentityKey ()); + lua_pushstring (L, (std::string ("const ") + name).c_str ()); + rawsetfield (L, -2, "__type"); + lua_pushcfunction (L, &indexMetaMethod); + rawsetfield (L, -2, "__index"); + lua_pushcfunction (L, &newindexMetaMethod); + rawsetfield (L, -2, "__newindex"); + lua_newtable (L); + rawsetfield (L, -2, "__propget"); + + if (Security::hideMetatables ()) + { + lua_pushnil (L); + rawsetfield (L, -2, "__metatable"); + } + } + + //-------------------------------------------------------------------------- + /** + Create the class table. + + The Lua stack should have the const table on top. + */ + void createClassTable (char const* name) + { + lua_newtable (L); + lua_pushvalue (L, -1); + lua_setmetatable (L, -2); + lua_pushboolean (L, 1); + lua_rawsetp (L, -2, getIdentityKey ()); + lua_pushstring (L, name); + rawsetfield (L, -2, "__type"); + lua_pushcfunction (L, &indexMetaMethod); + rawsetfield (L, -2, "__index"); + lua_pushcfunction (L, &newindexMetaMethod); + rawsetfield (L, -2, "__newindex"); + lua_newtable (L); + rawsetfield (L, -2, "__propget"); + lua_newtable (L); + rawsetfield (L, -2, "__propset"); + + lua_pushvalue (L, -2); + rawsetfield (L, -2, "__const"); // point to const table + + lua_pushvalue (L, -1); + rawsetfield (L, -3, "__class"); // point const table to class table + + if (Security::hideMetatables ()) + { + lua_pushnil (L); + rawsetfield (L, -2, "__metatable"); + } + } + + //-------------------------------------------------------------------------- + /** + Create the static table. + + The Lua stack should have: + -1 class table + -2 const table + -3 enclosing namespace + */ + void createStaticTable (char const* name) + { + lua_newtable (L); + lua_newtable (L); + lua_pushvalue (L, -1); + lua_setmetatable (L, -3); + lua_insert (L, -2); + rawsetfield (L, -5, name); + +#if 0 + lua_pushlightuserdata (L, this); + lua_pushcclosure (L, &tostringMetaMethod, 1); + rawsetfield (L, -2, "__tostring"); +#endif + lua_pushcfunction (L, &CFunc::indexMetaMethod); + rawsetfield (L, -2, "__index"); + lua_pushcfunction (L, &CFunc::newindexMetaMethod); + rawsetfield (L, -2, "__newindex"); + lua_newtable (L); + rawsetfield (L, -2, "__propget"); + lua_newtable (L); + rawsetfield (L, -2, "__propset"); + + lua_pushvalue (L, -2); + rawsetfield (L, -2, "__class"); // point to class table + + if (Security::hideMetatables ()) + { + lua_pushnil (L); + rawsetfield (L, -2, "__metatable"); + } + } + + //========================================================================== + /** + lua_CFunction to construct a class object wrapped in a container. + */ + template <class Params, class C> + static int ctorContainerProxy (lua_State* L) + { + typedef typename ContainerTraits <C>::Type T; + ArgList <Params, 2> args (L); + T* const p = Constructor <T, Params>::call (args); + UserdataSharedHelper <C, false>::push (L, p); + return 1; + } + + //-------------------------------------------------------------------------- + /** + lua_CFunction to construct a class object in-place in the userdata. + */ + template <class Params, class T> + static int ctorPlacementProxy (lua_State* L) + { + ArgList <Params, 2> args (L); + Constructor <T, Params>::call (UserdataValue <T>::place (L), args); + return 1; + } + + //-------------------------------------------------------------------------- + /** + Pop the Lua stack. + */ + void pop (int n) const + { + if (m_stackSize >= n && lua_gettop (L) >= n) + { + lua_pop (L, n); + m_stackSize -= n; + } + else + { + throw std::logic_error ("invalid stack"); + } + } + + public: + //-------------------------------------------------------------------------- + explicit ClassBase (lua_State* L_) + : L (L_) + , m_stackSize (0) + { + } + + //-------------------------------------------------------------------------- + /** + Copy Constructor. + */ + ClassBase (ClassBase const& other) + : L (other.L) + , m_stackSize (0) + { + m_stackSize = other.m_stackSize; + other.m_stackSize = 0; + } + + ~ClassBase () + { + pop (m_stackSize); + } + }; + + //============================================================================ + // + // Class + // + //============================================================================ + /** + Provides a class registration in a lua_State. + + After contstruction the Lua stack holds these objects: + -1 static table + -2 class table + -3 const table + -4 (enclosing namespace) + */ + template <class T> + class Class : public ClassBase + { + public: + //========================================================================== + /** + Register a new class or add to an existing class registration. + */ + Class (char const* name, Namespace const* parent) : ClassBase (parent->L) + { + m_stackSize = parent->m_stackSize + 3; + parent->m_stackSize = 0; + + assert (lua_istable (L, -1)); + rawgetfield (L, -1, name); + + if (lua_isnil (L, -1)) + { + lua_pop (L, 1); + + createConstTable (name); + lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); + rawsetfield (L, -2, "__gc"); + + createClassTable (name); + lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); + rawsetfield (L, -2, "__gc"); + + createStaticTable (name); + + // Map T back to its tables. + lua_pushvalue (L, -1); + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ()); + lua_pushvalue (L, -2); + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); + lua_pushvalue (L, -3); + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); + } + else + { + rawgetfield (L, -1, "__class"); + rawgetfield (L, -1, "__const"); + + // Reverse the top 3 stack elements + lua_insert (L, -3); + lua_insert (L, -2); + } + } + + //========================================================================== + /** + Derive a new class. + */ + Class (char const* name, Namespace const* parent, void const* const staticKey) + : ClassBase (parent->L) + { + m_stackSize = parent->m_stackSize + 3; + parent->m_stackSize = 0; + + assert (lua_istable (L, -1)); + + createConstTable (name); + lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); + rawsetfield (L, -2, "__gc"); + + createClassTable (name); + lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); + rawsetfield (L, -2, "__gc"); + + createStaticTable (name); + + lua_rawgetp (L, LUA_REGISTRYINDEX, staticKey); + assert (lua_istable (L, -1)); + rawgetfield (L, -1, "__class"); + assert (lua_istable (L, -1)); + rawgetfield (L, -1, "__const"); + assert (lua_istable (L, -1)); + + rawsetfield (L, -6, "__parent"); + rawsetfield (L, -4, "__parent"); + rawsetfield (L, -2, "__parent"); + + lua_pushvalue (L, -1); + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ()); + lua_pushvalue (L, -2); + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); + lua_pushvalue (L, -3); + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); + } + + //-------------------------------------------------------------------------- + /** + Continue registration in the enclosing namespace. + */ + Namespace endClass () + { + return Namespace (this); + } + + //-------------------------------------------------------------------------- + /** + Add or replace a static data member. + */ + template <class U> + Class <T>& addStaticData (char const* name, U* pu, bool isWritable = true) + { + assert (lua_istable (L, -1)); + + rawgetfield (L, -1, "__propget"); + assert (lua_istable (L, -1)); + lua_pushlightuserdata (L, pu); + lua_pushcclosure (L, &CFunc::getVariable <U>, 1); + rawsetfield (L, -2, name); + lua_pop (L, 1); + + rawgetfield (L, -1, "__propset"); + assert (lua_istable (L, -1)); + if (isWritable) + { + lua_pushlightuserdata (L, pu); + lua_pushcclosure (L, &CFunc::setVariable <U>, 1); + } + else + { + lua_pushstring (L, name); + lua_pushcclosure (L, &CFunc::readOnlyError, 1); + } + rawsetfield (L, -2, name); + lua_pop (L, 1); + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a static property member. + + If the set function is null, the property is read-only. + */ + template <class U> + Class <T>& addStaticProperty (char const* name, U (*get)(), void (*set)(U) = 0) + { + typedef U (*get_t)(); + typedef void (*set_t)(U); + + assert (lua_istable (L, -1)); + + rawgetfield (L, -1, "__propget"); + assert (lua_istable (L, -1)); + new (lua_newuserdata (L, sizeof (get))) get_t (get); + lua_pushcclosure (L, &CFunc::Call <U (*) (void)>::f, 1); + rawsetfield (L, -2, name); + lua_pop (L, 1); + + rawgetfield (L, -1, "__propset"); + assert (lua_istable (L, -1)); + if (set != 0) + { + new (lua_newuserdata (L, sizeof (set))) set_t (set); + lua_pushcclosure (L, &CFunc::Call <void (*) (U)>::f, 1); + } + else + { + lua_pushstring (L, name); + lua_pushcclosure (L, &CFunc::readOnlyError, 1); + } + rawsetfield (L, -2, name); + lua_pop (L, 1); + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a static member function. + */ + template <class FP> + Class <T>& addStaticFunction (char const* name, FP const fp) + { + new (lua_newuserdata (L, sizeof (fp))) FP (fp); + lua_pushcclosure (L, &CFunc::Call <FP>::f, 1); + rawsetfield (L, -2, name); + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a lua_CFunction. + */ + Class <T>& addStaticCFunction (char const* name, int (*const fp)(lua_State*)) + { + lua_pushcfunction (L, fp); + rawsetfield (L, -2, name); + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a data member. + */ + template <class U> + Class <T>& addData (char const* name, const U T::* mp, bool isWritable = true) + { + typedef const U T::*mp_t; + + // Add to __propget in class and const tables. + { + rawgetfield (L, -2, "__propget"); + rawgetfield (L, -4, "__propget"); + new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp); + lua_pushcclosure (L, &CFunc::getProperty <T,U>, 1); + lua_pushvalue (L, -1); + rawsetfield (L, -4, name); + rawsetfield (L, -2, name); + lua_pop (L, 2); + } + + if (isWritable) + { + // Add to __propset in class table. + rawgetfield (L, -2, "__propset"); + assert (lua_istable (L, -1)); + new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp); + lua_pushcclosure (L, &CFunc::setProperty <T,U>, 1); + rawsetfield (L, -2, name); + lua_pop (L, 1); + } + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a property member. + */ + template <class TG, class TS> + Class <T>& addProperty (char const* name, TG (T::* get) () const, void (T::* set) (TS)) + { + // Add to __propget in class and const tables. + { + rawgetfield (L, -2, "__propget"); + rawgetfield (L, -4, "__propget"); + typedef TG (T::*get_t) () const; + new (lua_newuserdata (L, sizeof (get_t))) get_t (get); + lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1); + lua_pushvalue (L, -1); + rawsetfield (L, -4, name); + rawsetfield (L, -2, name); + lua_pop (L, 2); + } + + { + // Add to __propset in class table. + rawgetfield (L, -2, "__propset"); + assert (lua_istable (L, -1)); + typedef void (T::* set_t) (TS); + new (lua_newuserdata (L, sizeof (set_t))) set_t (set); + lua_pushcclosure (L, &CFunc::CallMember <set_t>::f, 1); + rawsetfield (L, -2, name); + lua_pop (L, 1); + } + + return *this; + } + + // read-only + template <class TG> + Class <T>& addProperty (char const* name, TG (T::* get) () const) + { + // Add to __propget in class and const tables. + rawgetfield (L, -2, "__propget"); + rawgetfield (L, -4, "__propget"); + typedef TG (T::*get_t) () const; + new (lua_newuserdata (L, sizeof (get_t))) get_t (get); + lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1); + lua_pushvalue (L, -1); + rawsetfield (L, -4, name); + rawsetfield (L, -2, name); + lua_pop (L, 2); + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a property member, by proxy. + + When a class is closed for modification and does not provide (or cannot + provide) the function signatures necessary to implement get or set for + a property, this will allow non-member functions act as proxies. + + Both the get and the set functions require a T const* and T* in the first + argument respectively. + */ + template <class TG, class TS> + Class <T>& addProperty (char const* name, TG (*get) (T const*), void (*set) (T*, TS)) + { + // Add to __propget in class and const tables. + { + rawgetfield (L, -2, "__propget"); + rawgetfield (L, -4, "__propget"); + typedef TG (*get_t) (T const*); + new (lua_newuserdata (L, sizeof (get_t))) get_t (get); + lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1); + lua_pushvalue (L, -1); + rawsetfield (L, -4, name); + rawsetfield (L, -2, name); + lua_pop (L, 2); + } + + if (set != 0) + { + // Add to __propset in class table. + rawgetfield (L, -2, "__propset"); + assert (lua_istable (L, -1)); + typedef void (*set_t) (T*, TS); + new (lua_newuserdata (L, sizeof (set_t))) set_t (set); + lua_pushcclosure (L, &CFunc::Call <set_t>::f, 1); + rawsetfield (L, -2, name); + lua_pop (L, 1); + } + + return *this; + } + + // read-only + template <class TG, class TS> + Class <T>& addProperty (char const* name, TG (*get) (T const*)) + { + // Add to __propget in class and const tables. + rawgetfield (L, -2, "__propget"); + rawgetfield (L, -4, "__propget"); + typedef TG (*get_t) (T const*); + new (lua_newuserdata (L, sizeof (get_t))) get_t (get); + lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1); + lua_pushvalue (L, -1); + rawsetfield (L, -4, name); + rawsetfield (L, -2, name); + lua_pop (L, 2); + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a member function. + */ + template <class MemFn> + Class <T>& addFunction (char const* name, MemFn mf) + { + CFunc::CallMemberFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf); + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a member lua_CFunction. + */ + Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*)) + { + typedef int (T::*MFP)(lua_State*); + assert (lua_istable (L, -1)); + new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp); + lua_pushcclosure (L, &CFunc::CallMemberCFunction <T>::f, 1); + rawsetfield (L, -3, name); // class table + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a const member lua_CFunction. + */ + Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*) const) + { + typedef int (T::*MFP)(lua_State*) const; + assert (lua_istable (L, -1)); + new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp); + lua_pushcclosure (L, &CFunc::CallConstMemberCFunction <T>::f, 1); + lua_pushvalue (L, -1); + rawsetfield (L, -5, name); // const table + rawsetfield (L, -3, name); // class table + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a primary Constructor. + + The primary Constructor is invoked when calling the class type table + like a function. + + The template parameter should be a function pointer type that matches + the desired Constructor (since you can't take the address of a Constructor + and pass it as an argument). + */ + template <class MemFn, class C> + Class <T>& addConstructor () + { + lua_pushcclosure (L, + &ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0); + rawsetfield(L, -2, "__call"); + + return *this; + } + + template <class MemFn> + Class <T>& addConstructor () + { + lua_pushcclosure (L, + &ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0); + rawsetfield(L, -2, "__call"); + + return *this; + } + }; + +private: + //---------------------------------------------------------------------------- + /** + Open the global namespace for registrations. + */ + explicit Namespace (lua_State* L_) + : L (L_) + , m_stackSize (0) + { + lua_getglobal (L, "_G"); + ++m_stackSize; + } + + //---------------------------------------------------------------------------- + /** + Open a namespace for registrations. + + The namespace is created if it doesn't already exist. + The parent namespace is at the top of the Lua stack. + */ + Namespace (char const* name, Namespace const* parent) + : L (parent->L) + , m_stackSize (0) + { + m_stackSize = parent->m_stackSize + 1; + parent->m_stackSize = 0; + + assert (lua_istable (L, -1)); + rawgetfield (L, -1, name); + if (lua_isnil (L, -1)) + { + lua_pop (L, 1); + + lua_newtable (L); + lua_pushvalue (L, -1); + lua_setmetatable (L, -2); + lua_pushcfunction (L, &CFunc::indexMetaMethod); + rawsetfield (L, -2, "__index"); + lua_pushcfunction (L, &CFunc::newindexMetaMethod); + rawsetfield (L, -2, "__newindex"); + lua_newtable (L); + rawsetfield (L, -2, "__propget"); + lua_newtable (L); + rawsetfield (L, -2, "__propset"); + lua_pushvalue (L, -1); + rawsetfield (L, -3, name); +#if 0 + lua_pushcfunction (L, &tostringMetaMethod); + rawsetfield (L, -2, "__tostring"); +#endif + } + } + + //---------------------------------------------------------------------------- + /** + Creates a continued registration from a child namespace. + */ + explicit Namespace (Namespace const* child) + : L (child->L) + , m_stackSize (0) + { + m_stackSize = child->m_stackSize - 1; + child->m_stackSize = 1; + child->pop (1); + + // It is not necessary or valid to call + // endNamespace() for the global namespace! + // + assert (m_stackSize != 0); + } + + //---------------------------------------------------------------------------- + /** + Creates a continued registration from a child class. + */ + explicit Namespace (ClassBase const* child) + : L (child->L) + , m_stackSize (0) + { + m_stackSize = child->m_stackSize - 3; + child->m_stackSize = 3; + child->pop (3); + } + +public: + //---------------------------------------------------------------------------- + /** + Copy Constructor. + + Ownership of the stack is transferred to the new object. This happens + when the compiler emits temporaries to hold these objects while chaining + registrations across namespaces. + */ + Namespace (Namespace const& other) : L (other.L) + { + m_stackSize = other.m_stackSize; + other.m_stackSize = 0; + } + + //---------------------------------------------------------------------------- + /** + Closes this namespace registration. + */ + ~Namespace () + { + pop (m_stackSize); + } + + //---------------------------------------------------------------------------- + /** + Open the global namespace. + */ + static Namespace getGlobalNamespace (lua_State* L) + { + return Namespace (L); + } + + //---------------------------------------------------------------------------- + /** + Open a new or existing namespace for registrations. + */ + Namespace beginNamespace (char const* name) + { + return Namespace (name, this); + } + + //---------------------------------------------------------------------------- + /** + Continue namespace registration in the parent. + + Do not use this on the global namespace. + */ + Namespace endNamespace () + { + return Namespace (this); + } + + //---------------------------------------------------------------------------- + /** + Add or replace a variable. + */ + template <class T> + Namespace& addVariable (char const* name, T* pt, bool isWritable = true) + { + assert (lua_istable (L, -1)); + + rawgetfield (L, -1, "__propget"); + assert (lua_istable (L, -1)); + lua_pushlightuserdata (L, pt); + lua_pushcclosure (L, &CFunc::getVariable <T>, 1); + rawsetfield (L, -2, name); + lua_pop (L, 1); + + rawgetfield (L, -1, "__propset"); + assert (lua_istable (L, -1)); + if (isWritable) + { + lua_pushlightuserdata (L, pt); + lua_pushcclosure (L, &CFunc::setVariable <T>, 1); + } + else + { + lua_pushstring (L, name); + lua_pushcclosure (L, &CFunc::readOnlyError, 1); + } + rawsetfield (L, -2, name); + lua_pop (L, 1); + + return *this; + } + + //---------------------------------------------------------------------------- + /** + Add or replace a property. + + If the set function is omitted or null, the property is read-only. + */ + template <class TG, class TS> + Namespace& addProperty (char const* name, TG (*get) (), void (*set)(TS) = 0) + { + assert (lua_istable (L, -1)); + + rawgetfield (L, -1, "__propget"); + assert (lua_istable (L, -1)); + typedef TG (*get_t) (); + new (lua_newuserdata (L, sizeof (get_t))) get_t (get); + lua_pushcclosure (L, &CFunc::Call <TG (*) (void)>::f, 1); + rawsetfield (L, -2, name); + lua_pop (L, 1); + + rawgetfield (L, -1, "__propset"); + assert (lua_istable (L, -1)); + if (set != 0) + { + typedef void (*set_t) (TS); + new (lua_newuserdata (L, sizeof (set_t))) set_t (set); + lua_pushcclosure (L, &CFunc::Call <void (*) (TS)>::f, 1); + } + else + { + lua_pushstring (L, name); + lua_pushcclosure (L, &CFunc::readOnlyError, 1); + } + rawsetfield (L, -2, name); + lua_pop (L, 1); + + return *this; + } + + //---------------------------------------------------------------------------- + /** + Add or replace a free function. + */ + template <class FP> + Namespace& addFunction (char const* name, FP const fp) + { + assert (lua_istable (L, -1)); + + new (lua_newuserdata (L, sizeof (fp))) FP (fp); + lua_pushcclosure (L, &CFunc::Call <FP>::f, 1); + rawsetfield (L, -2, name); + + return *this; + } + + //---------------------------------------------------------------------------- + /** + Add or replace a lua_CFunction. + */ + Namespace& addCFunction (char const* name, int (*const fp)(lua_State*)) + { + lua_pushcfunction (L, fp); + rawsetfield (L, -2, name); + + return *this; + } + + //---------------------------------------------------------------------------- + /** + Open a new or existing class for registrations. + */ + template <class T> + Class <T> beginClass (char const* name) + { + return Class <T> (name, this); + } + + //---------------------------------------------------------------------------- + /** + Derive a new class for registrations. + + To continue registrations for the class later, use beginClass(). + Do not call deriveClass() again. + */ + template <class T, class U> + Class <T> deriveClass (char const* name) + { + return Class <T> (name, this, ClassInfo <U>::getStaticKey ()); + } +}; + +//------------------------------------------------------------------------------ +/** + Retrieve the global namespace. + + It is recommended to put your namespace inside the global namespace, and + then add your classes and functions to it, rather than adding many classes + and functions directly to the global namespace. +*/ +inline Namespace getGlobalNamespace (lua_State* L) +{ + return Namespace::getGlobalNamespace (L); +} diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/Stack.h b/3rdparty/luabridge/Source/LuaBridge/detail/Stack.h new file mode 100644 index 00000000000..9d6f61a2ba6 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/Stack.h @@ -0,0 +1,469 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +//------------------------------------------------------------------------------ +/** + Receive the lua_State* as an argument. +*/ +template <> +struct Stack <lua_State*> +{ + static lua_State* get (lua_State* L, int) + { + return L; + } +}; + +//------------------------------------------------------------------------------ +/** + Push a lua_CFunction. +*/ +template <> +struct Stack <lua_CFunction> +{ + static void push (lua_State* L, lua_CFunction f) + { + lua_pushcfunction (L, f); + } + + static lua_CFunction get (lua_State* L, int index) + { + return lua_tocfunction (L, index); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `int`. +*/ +template <> +struct Stack <int> +{ + static inline void push (lua_State* L, int value) + { + lua_pushinteger (L, static_cast <lua_Integer> (value)); + } + + static inline int get (lua_State* L, int index) + { + return static_cast <int> (luaL_checkinteger (L, index)); + } +}; + +template <> +struct Stack <int const&> +{ + static inline void push (lua_State* L, int value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline int get (lua_State* L, int index) + { + return static_cast <int > (luaL_checknumber (L, index)); + } +}; +//------------------------------------------------------------------------------ +/** + Stack specialization for `unsigned int`. +*/ +template <> +struct Stack <unsigned int> +{ + static inline void push (lua_State* L, unsigned int value) + { + lua_pushinteger (L, static_cast <lua_Integer> (value)); + } + + static inline unsigned int get (lua_State* L, int index) + { + return static_cast <unsigned int> (luaL_checkinteger (L, index)); + } +}; + +template <> +struct Stack <unsigned int const&> +{ + static inline void push (lua_State* L, unsigned int value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline unsigned int get (lua_State* L, int index) + { + return static_cast <unsigned int > (luaL_checknumber (L, index)); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `unsigned char`. +*/ +template <> +struct Stack <unsigned char> +{ + static inline void push (lua_State* L, unsigned char value) + { + lua_pushinteger (L, static_cast <lua_Integer> (value)); + } + + static inline unsigned char get (lua_State* L, int index) + { + return static_cast <unsigned char> (luaL_checkinteger (L, index)); + } +}; + +template <> +struct Stack <unsigned char const&> +{ + static inline void push (lua_State* L, unsigned char value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline unsigned char get (lua_State* L, int index) + { + return static_cast <unsigned char> (luaL_checknumber (L, index)); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `short`. +*/ +template <> +struct Stack <short> +{ + static inline void push (lua_State* L, short value) + { + lua_pushinteger (L, static_cast <lua_Integer> (value)); + } + + static inline short get (lua_State* L, int index) + { + return static_cast <short> (luaL_checkinteger (L, index)); + } +}; + +template <> +struct Stack <short const&> +{ + static inline void push (lua_State* L, short value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline short get (lua_State* L, int index) + { + return static_cast <short> (luaL_checknumber (L, index)); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `unsigned short`. +*/ +template <> +struct Stack <unsigned short> +{ + static inline void push (lua_State* L, unsigned short value) + { + lua_pushinteger (L, static_cast <lua_Integer> (value)); + } + + static inline unsigned short get (lua_State* L, int index) + { + return static_cast <unsigned short> (luaL_checkinteger (L, index)); + } +}; + +template <> +struct Stack <unsigned short const&> +{ + static inline void push (lua_State* L, unsigned short value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline unsigned short get (lua_State* L, int index) + { + return static_cast <unsigned short> (luaL_checknumber (L, index)); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `long`. +*/ +template <> +struct Stack <long> +{ + static inline void push (lua_State* L, long value) + { + lua_pushinteger (L, static_cast <lua_Integer> (value)); + } + + static inline long get (lua_State* L, int index) + { + return static_cast <long> (luaL_checkinteger (L, index)); + } +}; + +template <> +struct Stack <long const&> +{ + static inline void push (lua_State* L, long value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline long get (lua_State* L, int index) + { + return static_cast <long> (luaL_checknumber (L, index)); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `unsigned long`. +*/ +template <> +struct Stack <unsigned long> +{ + static inline void push (lua_State* L, unsigned long value) + { + lua_pushinteger (L, static_cast <lua_Integer> (value)); + } + + static inline unsigned long get (lua_State* L, int index) + { + return static_cast <unsigned long> (luaL_checkinteger (L, index)); + } +}; + +template <> +struct Stack <unsigned long const&> +{ + static inline void push (lua_State* L, unsigned long value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline unsigned long get (lua_State* L, int index) + { + return static_cast <unsigned long> (luaL_checknumber (L, index)); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `float`. +*/ +template <> +struct Stack <float> +{ + static inline void push (lua_State* L, float value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline float get (lua_State* L, int index) + { + return static_cast <float> (luaL_checknumber (L, index)); + } +}; + +template <> +struct Stack <float const&> +{ + static inline void push (lua_State* L, float value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline float get (lua_State* L, int index) + { + return static_cast <float> (luaL_checknumber (L, index)); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `double`. +*/ +template <> struct Stack <double> +{ + static inline void push (lua_State* L, double value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline double get (lua_State* L, int index) + { + return static_cast <double> (luaL_checknumber (L, index)); + } +}; + +template <> struct Stack <double const&> +{ + static inline void push (lua_State* L, double value) + { + lua_pushnumber (L, static_cast <lua_Number> (value)); + } + + static inline double get (lua_State* L, int index) + { + return static_cast <double> (luaL_checknumber (L, index)); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `bool`. +*/ +template <> +struct Stack <bool> { + static inline void push (lua_State* L, bool value) + { + lua_pushboolean (L, value ? 1 : 0); + } + + static inline bool get (lua_State* L, int index) + { + return lua_toboolean (L, index) ? true : false; + } +}; + +template <> +struct Stack <bool const&> { + static inline void push (lua_State* L, bool value) + { + lua_pushboolean (L, value ? 1 : 0); + } + + static inline bool get (lua_State* L, int index) + { + return lua_toboolean (L, index) ? true : false; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `char`. +*/ +template <> +struct Stack <char> +{ + static inline void push (lua_State* L, char value) + { + char str [2] = { value, 0 }; + lua_pushstring (L, str); + } + + static inline char get (lua_State* L, int index) + { + return luaL_checkstring (L, index) [0]; + } +}; + +template <> +struct Stack <char const&> +{ + static inline void push (lua_State* L, char value) + { + char str [2] = { value, 0 }; + lua_pushstring (L, str); + } + + static inline char get (lua_State* L, int index) + { + return luaL_checkstring (L, index) [0]; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `float`. +*/ +template <> +struct Stack <char const*> +{ + static inline void push (lua_State* L, char const* str) + { + if (str != 0) + lua_pushstring (L, str); + else + lua_pushnil (L); + } + + static inline char const* get (lua_State* L, int index) + { + return lua_isnil (L, index) ? 0 : luaL_checkstring (L, index); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `std::string`. +*/ +template <> +struct Stack <std::string> +{ + static inline void push (lua_State* L, std::string const& str) + { + lua_pushlstring (L, str.c_str (), str.size()); + } + + static inline std::string get (lua_State* L, int index) + { + size_t len; + const char *str = luaL_checklstring(L, index, &len); + return std::string (str, len); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `std::string const&`. +*/ +template <> +struct Stack <std::string const&> +{ + static inline void push (lua_State* L, std::string const& str) + { + lua_pushstring (L, str.c_str(), str.size()); + } + + static inline std::string get (lua_State* L, int index) + { + size_t len; + const char *str = luaL_checklstring(L, index, &len); + return std::string (str, len); + } +}; diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/TypeList.h b/3rdparty/luabridge/Source/LuaBridge/detail/TypeList.h new file mode 100644 index 00000000000..21f850e89df --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/TypeList.h @@ -0,0 +1,174 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + This file incorporates work covered by the following copyright and + permission notice: + + The Loki Library + Copyright (c) 2001 by Andrei Alexandrescu + This code accompanies the book: + Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design + Patterns Applied". Copyright (c) 2001. Addison-Wesley. + Permission to use, copy, modify, distribute and sell this software for any + purpose is hereby granted without fee, provided that the above copyright + notice appear in all copies and that both that copyright notice and this + permission notice appear in supporting documentation. + The author or Addison-Welsey Longman make no representations about the + suitability of this software for any purpose. It is provided "as is" + without express or implied warranty. +*/ +//============================================================================== + +/** + None type means void parameters or return value. +*/ +typedef void None; + +template <typename Head, typename Tail = None> +struct TypeList +{ +}; + +/** + A TypeList with actual values. +*/ +template <typename List> +struct TypeListValues +{ + static std::string const tostring (bool) + { + return ""; + } +}; + +/** + TypeListValues recursive template definition. +*/ +template <typename Head, typename Tail> +struct TypeListValues <TypeList <Head, Tail> > +{ + Head hd; + TypeListValues <Tail> tl; + + TypeListValues (Head hd_, TypeListValues <Tail> const& tl_) + : hd (hd_), tl (tl_) + { + } + + static std::string const tostring (bool comma = false) + { + std::string s; + + if (comma) + s = ", "; + + s = s + typeid (Head).name (); + + return s + TypeListValues <Tail>::tostring (true); + } +}; + +// Specializations of type/value list for head types that are references and +// const-references. We need to handle these specially since we can't count +// on the referenced object hanging around for the lifetime of the list. + +template <typename Head, typename Tail> +struct TypeListValues <TypeList <Head&, Tail> > +{ + Head hd; + TypeListValues <Tail> tl; + + TypeListValues (Head& hd_, TypeListValues <Tail> const& tl_) + : hd (hd_), tl (tl_) + { + } + + static std::string const tostring (bool comma = false) + { + std::string s; + + if (comma) + s = ", "; + + s = s + typeid (Head).name () + "&"; + + return s + TypeListValues <Tail>::tostring (true); + } +}; + +template <typename Head, typename Tail> +struct TypeListValues <TypeList <Head const&, Tail> > +{ + Head hd; + TypeListValues <Tail> tl; + + TypeListValues (Head const& hd_, const TypeListValues <Tail>& tl_) + : hd (hd_), tl (tl_) + { + } + + static std::string const tostring (bool comma = false) + { + std::string s; + + if (comma) + s = ", "; + + s = s + typeid (Head).name () + " const&"; + + return s + TypeListValues <Tail>::tostring (true); + } +}; + +//============================================================================== +/** + Subclass of a TypeListValues constructable from the Lua stack. +*/ + +template <typename List, int Start = 1> +struct ArgList +{ +}; + +template <int Start> +struct ArgList <None, Start> : public TypeListValues <None> +{ + ArgList (lua_State*) + { + } +}; + +template <typename Head, typename Tail, int Start> +struct ArgList <TypeList <Head, Tail>, Start> + : public TypeListValues <TypeList <Head, Tail> > +{ + ArgList (lua_State* L) + : TypeListValues <TypeList <Head, Tail> > (Stack <Head>::get (L, Start), + ArgList <Tail, Start + 1> (L)) + { + } +}; diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/TypeTraits.h b/3rdparty/luabridge/Source/LuaBridge/detail/TypeTraits.h new file mode 100644 index 00000000000..5dd077194f1 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/TypeTraits.h @@ -0,0 +1,125 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#ifndef LUABRIDGE_TYPEINFO_HEADER +#define LUABRIDGE_TYPEINFO_HEADER + +//------------------------------------------------------------------------------ +/** + Container traits. + + Unspecialized ContainerTraits has the isNotContainer typedef for SFINAE. + All user defined containers must supply an appropriate specialization for + ContinerTraits (without the typedef isNotContainer). The containers that + come with LuaBridge also come with the appropriate ContainerTraits + specialization. See the corresponding declaration for details. + + A specialization of ContainerTraits for some generic type ContainerType + looks like this: + + template <class T> + struct ContainerTraits <ContainerType <T> > + { + typedef typename T Type; + + static T* get (ContainerType <T> const& c) + { + return c.get (); // Implementation-dependent on ContainerType + } + }; +*/ +template <class T> +struct ContainerTraits +{ + typedef bool isNotContainer; +}; + +//------------------------------------------------------------------------------ +/** + Type traits. + + Specializations return information about a type. +*/ +struct TypeTraits +{ + /** Determine if type T is a container. + + To be considered a container, there must be a specialization of + ContainerTraits with the required fields. + */ + template <typename T> + class isContainer + { + private: + typedef char yes[1]; // sizeof (yes) == 1 + typedef char no [2]; // sizeof (no) == 2 + + template <typename C> + static no& test (typename C::isNotContainer*); + + template <typename> + static yes& test (...); + + public: + static const bool value = sizeof (test <ContainerTraits <T> >(0)) == sizeof (yes); + }; + + /** Determine if T is const qualified. + */ + /** @{ */ + template <class T> + struct isConst + { + static bool const value = false; + }; + + template <class T> + struct isConst <T const> + { + static bool const value = true; + }; + /** @} */ + + /** Remove the const qualifier from T. + */ + /** @{ */ + template <class T> + struct removeConst + { + typedef T Type; + }; + + template <class T> + struct removeConst <T const> + { + typedef T Type; + }; + /**@}*/ +}; + +#endif diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/Userdata.h b/3rdparty/luabridge/Source/LuaBridge/detail/Userdata.h new file mode 100644 index 00000000000..19451bd7d3e --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/Userdata.h @@ -0,0 +1,817 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +//============================================================================== +/** + Return the identity pointer for our lightuserdata tokens. + + LuaBridge metatables are tagged with a security "token." The token is a + lightuserdata created from the identity pointer, used as a key in the + metatable. The value is a boolean = true, although any value could have been + used. + + Because of Lua's dynamic typing and our improvised system of imposing C++ + class structure, there is the possibility that executing scripts may + knowingly or unknowingly cause invalid data to get passed to the C functions + created by LuaBridge. In particular, our security model addresses the + following: + + Notes: + 1. Scripts cannot create a userdata (ignoring the debug lib). + 2. Scripts cannot create a lightuserdata (ignoring the debug lib). + 3. Scripts cannot set the metatable on a userdata. + 4. Our identity key is a unique pointer in the process. + 5. Our metatables have a lightuserdata identity key / value pair. + 6. Our metatables have "__metatable" set to a boolean = false. + 7. Our lightuserdata is unique. +*/ +inline void* getIdentityKey () +{ + static char value; + return &value; +} + +/** + Interface to a class pointer retrievable from a userdata. +*/ +class Userdata +{ +protected: + void* m_p; // subclasses must set this + + //-------------------------------------------------------------------------- + /** + Get an untyped pointer to the contained class. + */ + inline void* const getPointer () + { + return m_p; + } + +private: + //-------------------------------------------------------------------------- + /** + Validate and retrieve a Userdata on the stack. + + The Userdata must exactly match the corresponding class table or + const table, or else a Lua error is raised. This is used for the + __gc metamethod. + */ + static Userdata* getExactClass (lua_State* L, + int narg, + void const* classKey) + { + Userdata* ud = 0; + int const index = lua_absindex (L, narg); + + bool mismatch = false; + char const* got = 0; + + lua_rawgetp (L, LUA_REGISTRYINDEX, classKey); + assert (lua_istable (L, -1)); + + // Make sure we have a userdata. + if (!lua_isuserdata (L, index)) + mismatch = true; + + // Make sure it's metatable is ours. + if (!mismatch) + { + lua_getmetatable (L, index); + lua_rawgetp (L, -1, getIdentityKey ()); + if (lua_isboolean (L, -1)) + { + lua_pop (L, 1); + } + else + { + lua_pop (L, 2); + mismatch = true; + } + } + + if (!mismatch) + { + if (lua_rawequal (L, -1, -2)) + { + // Matches class table. + lua_pop (L, 2); + ud = static_cast <Userdata*> (lua_touserdata (L, index)); + } + else + { + rawgetfield (L, -2, "__const"); + if (lua_rawequal (L, -1, -2)) + { + // Matches const table + lua_pop (L, 3); + ud = static_cast <Userdata*> (lua_touserdata (L, index)); + } + else + { + // Mismatch, but its one of ours so get a type name. + rawgetfield (L, -2, "__type"); + lua_insert (L, -4); + lua_pop (L, 2); + got = lua_tostring (L, -2); + mismatch = true; + } + } + } + + if (mismatch) + { + rawgetfield (L, -1, "__type"); + assert (lua_type (L, -1) == LUA_TSTRING); + char const* const expected = lua_tostring (L, -1); + + if (got == 0) + got = lua_typename (L, lua_type (L, index)); + + char const* const msg = lua_pushfstring ( + L, "%s expected, got %s", expected, got); + + if (narg > 0) + luaL_argerror (L, narg, msg); + else + lua_error (L); + } + + return ud; + } + + //-------------------------------------------------------------------------- + /** + Validate and retrieve a Userdata on the stack. + + The Userdata must be derived from or the same as the given base class, + identified by the key. If canBeConst is false, generates an error if + the resulting Userdata represents to a const object. We do the type check + first so that the error message is informative. + */ + static Userdata* getClass (lua_State* L, + int index, + void const* baseClassKey, + bool canBeConst) + { + assert (index > 0); + Userdata* ud = 0; + + bool mismatch = false; + char const* got = 0; + + lua_rawgetp (L, LUA_REGISTRYINDEX, baseClassKey); + assert (lua_istable (L, -1)); + + // Make sure we have a userdata. + if (lua_isuserdata (L, index)) + { + // Make sure it's metatable is ours. + lua_getmetatable (L, index); + lua_rawgetp (L, -1, getIdentityKey ()); + if (lua_isboolean (L, -1)) + { + lua_pop (L, 1); + + // If __const is present, object is NOT const. + rawgetfield (L, -1, "__const"); + assert (lua_istable (L, -1) || lua_isnil (L, -1)); + bool const isConst = lua_isnil (L, -1); + lua_pop (L, 1); + + // Replace the class table with the const table if needed. + if (isConst) + { + rawgetfield (L, -2, "__const"); + assert (lua_istable (L, -1)); + lua_replace (L, -3); + } + + for (;;) + { + if (lua_rawequal (L, -1, -2)) + { + lua_pop (L, 2); + + // Match, now check const-ness. + if (isConst && !canBeConst) + { + luaL_argerror (L, index, "cannot be const"); + } + else + { + ud = static_cast <Userdata*> (lua_touserdata (L, index)); + break; + } + } + else + { + // Replace current metatable with it's base class. + rawgetfield (L, -1, "__parent"); +/* +ud +class metatable +ud metatable +ud __parent (nil) +*/ + + if (lua_isnil (L, -1)) + { + lua_remove (L, -1); + // Mismatch, but its one of ours so get a type name. + rawgetfield (L, -1, "__type"); + lua_insert (L, -3); + lua_pop (L, 1); + got = lua_tostring (L, -2); + mismatch = true; + break; + } + else + { + lua_remove (L, -2); + } + } + } + } + else + { + lua_pop (L, 2); + mismatch = true; + } + } + else + { + mismatch = true; + } + + if (mismatch) + { + assert (lua_type (L, -1) == LUA_TTABLE); + rawgetfield (L, -1, "__type"); + assert (lua_type (L, -1) == LUA_TSTRING); + char const* const expected = lua_tostring (L, -1); + + if (got == 0) + got = lua_typename (L, lua_type (L, index)); + + char const* const msg = lua_pushfstring ( + L, "%s expected, got %s", expected, got); + + luaL_argerror (L, index, msg); + } + + return ud; + } + +public: + virtual ~Userdata () { } + + //-------------------------------------------------------------------------- + /** + Returns the Userdata* if the class on the Lua stack matches. + + If the class does not match, a Lua error is raised. + */ + template <class T> + static inline Userdata* getExact (lua_State* L, int index) + { + return getExactClass (L, index, ClassInfo <T>::getClassKey ()); + } + + //-------------------------------------------------------------------------- + /** + Get a pointer to the class from the Lua stack. + + If the object is not the class or a subclass, or it violates the + const-ness, a Lua error is raised. + */ + template <class T> + static inline T* get (lua_State* L, int index, bool canBeConst) + { + if (lua_isnil (L, index)) + return 0; + else + return static_cast <T*> (getClass (L, index, + ClassInfo <T>::getClassKey (), canBeConst)->getPointer ()); + } +}; + +//---------------------------------------------------------------------------- +/** + Wraps a class object stored in a Lua userdata. + + The lifetime of the object is managed by Lua. The object is constructed + inside the userdata using placement new. +*/ +template <class T> +class UserdataValue : public Userdata +{ +private: + UserdataValue <T> (UserdataValue <T> const&); + UserdataValue <T> operator= (UserdataValue <T> const&); + + char m_storage [sizeof (T)]; + + inline T* getObject () + { + // If this fails to compile it means you forgot to provide + // a Container specialization for your container! + // + return reinterpret_cast <T*> (&m_storage [0]); + } + +private: + /** + Used for placement construction. + */ + UserdataValue () + { + m_p = getObject (); + } + + ~UserdataValue () + { + getObject ()->~T (); + } + +public: + /** + Push a T via placement new. + + The caller is responsible for calling placement new using the + returned uninitialized storage. + */ + static void* place (lua_State* const L) + { + UserdataValue <T>* const ud = new ( + lua_newuserdata (L, sizeof (UserdataValue <T>))) UserdataValue <T> (); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); + // If this goes off it means you forgot to register the class! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + return ud->getPointer (); + } + + /** + Push T via copy construction from U. + */ + template <class U> + static inline void push (lua_State* const L, U const& u) + { + new (place (L)) U (u); + } +}; + +//---------------------------------------------------------------------------- +/** + Wraps a pointer to a class object inside a Lua userdata. + + The lifetime of the object is managed by C++. +*/ +class UserdataPtr : public Userdata +{ +private: + UserdataPtr (UserdataPtr const&); + UserdataPtr operator= (UserdataPtr const&); + +private: + /** Push non-const pointer to object using metatable key. + */ + static void push (lua_State* L, void* const p, void const* const key) + { + if (p) + { + new (lua_newuserdata (L, sizeof (UserdataPtr))) UserdataPtr (p); + lua_rawgetp (L, LUA_REGISTRYINDEX, key); + // If this goes off it means you forgot to register the class! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } + + /** Push const pointer to object using metatable key. + */ + static void push (lua_State* L, void const* const p, void const* const key) + { + if (p) + { + new (lua_newuserdata (L, sizeof (UserdataPtr))) + UserdataPtr (const_cast <void*> (p)); + lua_rawgetp (L, LUA_REGISTRYINDEX, key); + // If this goes off it means you forgot to register the class! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } + + explicit UserdataPtr (void* const p) + { + m_p = p; + + // Can't construct with a null pointer! + // + assert (m_p != 0); + } + +public: + /** Push non-const pointer to object. + */ + template <class T> + static inline void push (lua_State* const L, T* const p) + { + if (p) + push (L, p, ClassInfo <T>::getClassKey ()); + else + lua_pushnil (L); + } + + /** Push const pointer to object. + */ + template <class T> + static inline void push (lua_State* const L, T const* const p) + { + if (p) + push (L, p, ClassInfo <T>::getConstKey ()); + else + lua_pushnil (L); + } +}; + +//============================================================================ +/** + Wraps a container thet references a class object. + + The template argument C is the container type, ContainerTraits must be + specialized on C or else a compile error will result. +*/ +template <class C> +class UserdataShared : public Userdata +{ +private: + UserdataShared (UserdataShared <C> const&); + UserdataShared <C>& operator= (UserdataShared <C> const&); + + typedef typename TypeTraits::removeConst < + typename ContainerTraits <C>::Type>::Type T; + + C m_c; + +private: + ~UserdataShared () + { + } + +public: + /** + Construct from a container to the class or a derived class. + */ + template <class U> + explicit UserdataShared (U const& u) : m_c (u) + { + m_p = const_cast <void*> (reinterpret_cast <void const*> ( + (ContainerTraits <C>::get (m_c)))); + } + + /** + Construct from a pointer to the class or a derived class. + */ + template <class U> + explicit UserdataShared (U* u) : m_c (u) + { + m_p = const_cast <void*> (reinterpret_cast <void const*> ( + (ContainerTraits <C>::get (m_c)))); + } +}; + +//---------------------------------------------------------------------------- +// +// SFINAE helpers. +// + +// non-const objects +template <class C, bool makeObjectConst> +struct UserdataSharedHelper +{ + typedef typename TypeTraits::removeConst < + typename ContainerTraits <C>::Type>::Type T; + + static void push (lua_State* L, C const& c) + { + if (ContainerTraits <C>::get (c) != 0) + { + new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); + // If this goes off it means the class T is unregistered! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } + + static void push (lua_State* L, T* const t) + { + if (t) + { + new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); + // If this goes off it means the class T is unregistered! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } +}; + +// const objects +template <class C> +struct UserdataSharedHelper <C, true> +{ + typedef typename TypeTraits::removeConst < + typename ContainerTraits <C>::Type>::Type T; + + static void push (lua_State* L, C const& c) + { + if (ContainerTraits <C>::get (c) != 0) + { + new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); + // If this goes off it means the class T is unregistered! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } + + static void push (lua_State* L, T* const t) + { + if (t) + { + new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); + // If this goes off it means the class T is unregistered! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } +}; + +/** + Pass by container. + + The container controls the object lifetime. Typically this will be a + lifetime shared by C++ and Lua using a reference count. Because of type + erasure, containers like std::shared_ptr will not work. Containers must + either be of the intrusive variety, or in the style of the RefCountedPtr + type provided by LuaBridge (that uses a global hash table). +*/ +template <class C, bool byContainer> +struct StackHelper +{ + static inline void push (lua_State* L, C const& c) + { + UserdataSharedHelper <C, + TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, c); + } + + typedef typename TypeTraits::removeConst < + typename ContainerTraits <C>::Type>::Type T; + + static inline C get (lua_State* L, int index) + { + return Userdata::get <T> (L, index, true); + } +}; + +/** + Pass by value. + + Lifetime is managed by Lua. A C++ function which accesses a pointer or + reference to an object outside the activation record in which it was + retrieved may result in undefined behavior if Lua garbage collected it. +*/ +template <class T> +struct StackHelper <T, false> +{ + static inline void push (lua_State* L, T const& t) + { + UserdataValue <T>::push (L, t); + } + + static inline T const& get (lua_State* L, int index) + { + return *Userdata::get <T> (L, index, true); + } +}; + +//============================================================================== + +/** + Lua stack conversions for class objects passed by value. +*/ +template <class T> +struct Stack +{ +public: + static inline void push (lua_State* L, T const& t) + { + StackHelper <T, + TypeTraits::isContainer <T>::value>::push (L, t); + } + + static inline T get (lua_State* L, int index) + { + return StackHelper <T, + TypeTraits::isContainer <T>::value>::get (L, index); + } +}; + +//------------------------------------------------------------------------------ +/** + Lua stack conversions for pointers and references to class objects. + + Lifetime is managed by C++. Lua code which remembers a reference to the + value may result in undefined behavior if C++ destroys the object. The + handling of the const and volatile qualifiers happens in UserdataPtr. +*/ + +// pointer +template <class T> +struct Stack <T*> +{ + static inline void push (lua_State* L, T* const p) + { + UserdataPtr::push (L, p); + } + + static inline T* const get (lua_State* L, int index) + { + return Userdata::get <T> (L, index, false); + } +}; + +// Strips the const off the right side of * +template <class T> +struct Stack <T* const> +{ + static inline void push (lua_State* L, T* const p) + { + UserdataPtr::push (L, p); + } + + static inline T* const get (lua_State* L, int index) + { + return Userdata::get <T> (L, index, false); + } +}; + +// pointer to const +template <class T> +struct Stack <T const*> +{ + static inline void push (lua_State* L, T const* const p) + { + UserdataPtr::push (L, p); + } + + static inline T const* const get (lua_State* L, int index) + { + return Userdata::get <T> (L, index, true); + } +}; + +// Strips the const off the right side of * +template <class T> +struct Stack <T const* const> +{ + static inline void push (lua_State* L, T const* const p) + { + UserdataPtr::push (L, p); + } + + static inline T const* const get (lua_State* L, int index) + { + return Userdata::get <T> (L, index, true); + } +}; + +// reference +template <class T> +struct Stack <T&> +{ + static inline void push (lua_State* L, T& t) + { + UserdataPtr::push (L, &t); + } + + static T& get (lua_State* L, int index) + { + T* const t = Userdata::get <T> (L, index, false); + if (!t) + luaL_error (L, "nil passed to reference"); + return *t; + } +}; + +template <class C, bool byContainer> +struct RefStackHelper +{ + typedef C return_type; + + static inline void push (lua_State* L, C const& t) + { + UserdataSharedHelper <C, + TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, t); + } + + typedef typename TypeTraits::removeConst < + typename ContainerTraits <C>::Type>::Type T; + + static return_type get (lua_State* L, int index) + { + return Userdata::get <T> (L, index, true); + } +}; + +template <class T> +struct RefStackHelper <T, false> +{ + typedef T const& return_type; + + static inline void push (lua_State* L, T const& t) + { + UserdataPtr::push (L, &t); + } + + static return_type get (lua_State* L, int index) + { + T const* const t = Userdata::get <T> (L, index, true); + + if (!t) + luaL_error (L, "nil passed to reference"); + return *t; + } + +}; + +// reference to const +template <class T> +struct Stack <T const&> +{ + typedef RefStackHelper <T, TypeTraits::isContainer <T>::value> helper_t; + + static inline void push (lua_State* L, T const& t) + { + helper_t::push (L, t); + } + + static typename helper_t::return_type get (lua_State* L, int index) + { + return helper_t::get (L, index); + } +}; diff --git a/3rdparty/luabridge/Source/LuaBridge/detail/dump.h b/3rdparty/luabridge/Source/LuaBridge/detail/dump.h new file mode 100644 index 00000000000..c0668035737 --- /dev/null +++ b/3rdparty/luabridge/Source/LuaBridge/detail/dump.h @@ -0,0 +1,28 @@ +#include <sstream> +#include <string> + +std::string dumpLuaState(lua_State *L) { + std::stringstream ostr; + int i; + int top = lua_gettop(L); + ostr << "top=" << top << ":\n"; + for (i = 1; i <= top; ++i) { + int t = lua_type(L, i); + switch(t) { + case LUA_TSTRING: + ostr << " " << i << ": '" << lua_tostring(L, i) << "'\n"; + break; + case LUA_TBOOLEAN: + ostr << " " << i << ": " << + (lua_toboolean(L, i) ? "true" : "false") << "\n"; + break; + case LUA_TNUMBER: + ostr << " " << i << ": " << lua_tonumber(L, i) << "\n"; + break; + default: + ostr << " " << i << ": TYPE=" << lua_typename(L, t) << "\n"; + break; + } + } + return ostr.str(); +} diff --git a/3rdparty/luabridge/index.html b/3rdparty/luabridge/index.html new file mode 100644 index 00000000000..5b10a29e425 --- /dev/null +++ b/3rdparty/luabridge/index.html @@ -0,0 +1,9 @@ +<!-- Simple redirect to bring up the reference manual. --> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> +<head> +<title>LuaBridge Reference Manual</title> +<meta http-equiv="REFRESH" content="0;url=Manual.html"></HEAD> +<BODY> +Redirecting to the <a HREF="Manual.html">LuaBridge reference manual</a>. +</BODY> |