mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
The docs are here.
This commit is contained in:
parent
c5e637c85b
commit
338278edf7
216
docs/Makefile
Normal file
216
docs/Makefile
Normal file
@ -0,0 +1,216 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = build
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||
endif
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " applehelp to make an Apple Help Book"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
.PHONY: html
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
.PHONY: dirhtml
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
.PHONY: singlehtml
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
.PHONY: pickle
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
.PHONY: json
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
.PHONY: htmlhelp
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
.PHONY: qthelp
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Sol.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Sol.qhc"
|
||||
|
||||
.PHONY: applehelp
|
||||
applehelp:
|
||||
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
|
||||
@echo
|
||||
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
|
||||
@echo "N.B. You won't be able to view it unless you put it in" \
|
||||
"~/Library/Documentation/Help or install it in your application" \
|
||||
"bundle."
|
||||
|
||||
.PHONY: devhelp
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/Sol"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Sol"
|
||||
@echo "# devhelp"
|
||||
|
||||
.PHONY: epub
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
.PHONY: latex
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
.PHONY: latexpdf
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
.PHONY: latexpdfja
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
.PHONY: text
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
.PHONY: man
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
.PHONY: texinfo
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
.PHONY: info
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
.PHONY: gettext
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
.PHONY: changes
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
.PHONY: linkcheck
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
.PHONY: doctest
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
||||
@echo "Testing of coverage in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/coverage/python.txt."
|
||||
|
||||
.PHONY: xml
|
||||
xml:
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
.PHONY: pseudoxml
|
||||
pseudoxml:
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
263
docs/make.bat
Normal file
263
docs/make.bat
Normal file
@ -0,0 +1,263 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% source
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
echo. coverage to run coverage check of the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
REM Check if sphinx-build is available and fallback to Python version if any
|
||||
%SPHINXBUILD% 1>NUL 2>NUL
|
||||
if errorlevel 9009 goto sphinx_python
|
||||
goto sphinx_ok
|
||||
|
||||
:sphinx_python
|
||||
|
||||
set SPHINXBUILD=python -m sphinx.__init__
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:sphinx_ok
|
||||
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Sol.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Sol.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "coverage" (
|
||||
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of coverage in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/coverage/python.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
10
docs/source/api/compatibility.rst
Normal file
10
docs/source/api/compatibility.rst
Normal file
@ -0,0 +1,10 @@
|
||||
compatibility.hpp
|
||||
=================
|
||||
Lua 5.3/5.2 compatibility for Lua 5.1/LuaJIT
|
||||
--------------------------------------------
|
||||
|
||||
This is a detail header used to maintain compatability with the 5.2 and 5.3 APIs. It contains code from the MIT-Licensed `Lua<http://www.Lua.org/>` code in some places and also from the `lua-compat<https://github.com/keplerproject/lua-compat-5.3>` repository by KeplerProject.
|
||||
|
||||
It is not fully documented as this header's only purpose is for internal use to make sure Sol compiles across all platforms / distributions with no errors or missing Lua functionality. If you think there's some compatibility features we are missing or if you are running into redefinition errors, please make an `issue in the issue tracker<https://github.com/ThePhD/sol2/issues/>`.
|
||||
|
||||
For the licenses, see :doc:`here<../licenses>`
|
103
docs/source/api/coroutine.rst
Normal file
103
docs/source/api/coroutine.rst
Normal file
@ -0,0 +1,103 @@
|
||||
coroutine
|
||||
=========
|
||||
resumable/yielding functions from Lua
|
||||
-------------------------------------
|
||||
|
||||
A ``coroutine`` is a :doc:`reference<reference>` to a function in Lua that can be called multiple times to yield a specific result. It is run on the :doc:`lua_State<state>` that was used to create it (see :doc:`thread<thread>` for an example on how to get a coroutine that runs on a thread separate from your usual "main" :doc:`lua_State<state>`).
|
||||
|
||||
The ``coroutine`` object is entirely similar to the :doc:`protected_function<protected_function>` object, with additional member functions to check if a coroutine has yielded (:doc:`call_status::yielded<types>`) and is thus runnable again, whether it has completed (:doc:`call_status::ok<types>`) and thus cannot yield anymore values, or whether it has suffered an error (see `status()` and :doc:`call_status<types>`'s error codes).
|
||||
|
||||
For example, you can work with a coroutine like this:
|
||||
|
||||
.. code-block:: lua
|
||||
:caption: co.lua
|
||||
|
||||
function loop()
|
||||
while counter ~= 30
|
||||
do
|
||||
coroutine.yield(counter);
|
||||
counter = counter + 1;
|
||||
end
|
||||
return counter
|
||||
end
|
||||
|
||||
This is a function that yields:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: main.cpp
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::coroutine);
|
||||
lua.script_file("co.lua");
|
||||
sol::coroutine cr = lua["loop"];
|
||||
|
||||
for (int counter = 0; // start from 0
|
||||
counter < 10 && cr; // we want 10 values, and we only want to run if the coroutine "cr" is valid
|
||||
// Alternative: counter < 10 && cr.valid()
|
||||
++counter) {
|
||||
// Call the coroutine, does the computation and then suspends
|
||||
int value = cr();
|
||||
}
|
||||
|
||||
Note that this code doesn't check for errors: to do so, you can call the function and assign it as ``auto result = cr();``, then check ``result.valid()`` as is the case with :doc:`protected_function<protected_function>`. Finally, you can run this coroutine on another thread by doing the following:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: main_with_thread.cpp
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::coroutine);
|
||||
lua.script_file("co.lua");
|
||||
sol::thread runner = sol::thread::create(lua.lua_state());
|
||||
sol::state_view runnerstate = runner.state();
|
||||
sol::coroutine cr = runnerstate["loop"];
|
||||
|
||||
for (int counter = 0; counter < 10 && cr; ++counter) {
|
||||
// Call the coroutine, does the computation and then suspends
|
||||
int value = cr();
|
||||
}
|
||||
|
||||
The following are the members of ``sol::coroutine``:
|
||||
|
||||
members
|
||||
-------
|
||||
|
||||
.. _status:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: returning the coroutine's status
|
||||
|
||||
call_status status() const noexcept;
|
||||
|
||||
Returns the status of a coroutine.
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: checks for an error
|
||||
|
||||
bool error() const noexcept;
|
||||
|
||||
Checks if an error occured when the coroutine was run.
|
||||
|
||||
.. _runnable:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: runnable and explicit operator bool
|
||||
|
||||
bool runnable () const noexcept;
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
These functions allow you to check if a coroutine can still be called (has more values to yield and has not errored). If you have a coroutine object ``coroutine my_co = /*...*/``, you can either check ``runnable()`` or do ``if ( my_co ) { /* use coroutine */ }``.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: calling a coroutine
|
||||
|
||||
template<typename... Args>
|
||||
protected_function_result operator()( Args&&... args );
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
decltype(auto) call( Args&&... args );
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
decltype(auto) operator()( types<Ret...>, Args&&... args );
|
||||
|
||||
Calls the coroutine. The second ``operator()`` lets you specify the templated return types using the ``my_co(sol::types<int, std::string>, ...)`` syntax. Check :ref:`status()<status>` afterwards for more information about the success of the run or just check the coroutine object in an ifs tatement, as shown :ref:`above<runnable>`.
|
15
docs/source/api/error.rst
Normal file
15
docs/source/api/error.rst
Normal file
@ -0,0 +1,15 @@
|
||||
error
|
||||
=====
|
||||
the single exception type
|
||||
-------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class error : public std::runtime_error {
|
||||
public:
|
||||
error(const std::string& str): std::runtime_error("Lua: error: " + str) {}
|
||||
};
|
||||
|
||||
If an eror is thrown by Sol, it is going to be of this type. We use this in a single place: the default ``at_panic`` function we bind on construction of a :doc:`sol::state<state>`. If you turn :doc:`off exceptions<../exceptions>`, the chances of you seeing this error are :doc:`nil<types>`.
|
||||
|
||||
As it derives from ``std::runtime_error``, which derives from ``std::exception``, you can catch it with a ``catch (const std::exception& )`` clause in your try/catch blocks.
|
52
docs/source/api/function.rst
Normal file
52
docs/source/api/function.rst
Normal file
@ -0,0 +1,52 @@
|
||||
function
|
||||
========
|
||||
calling functions bound to Lua
|
||||
------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class function : public reference;
|
||||
|
||||
Function is a correct-assuming version of :doc:`protected_function<protected_function>`, omitting the need for typechecks and error handling. It is the default function type of Sol. When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :doc:`function_result<proxy>` class that gets implicitly converted to the requested return type. For example:
|
||||
|
||||
.. code-block:: lua
|
||||
:caption: func_barks.lua
|
||||
:linenos:
|
||||
|
||||
bark_power = 11;
|
||||
|
||||
function woof ( bark_energy )
|
||||
return (bark_energy * (bark_power / 4))
|
||||
end
|
||||
|
||||
The following C++ code will call this function from this file and retrieve the return value:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
sol::state lua;
|
||||
|
||||
lua.script_file( "func_barks.lua" );
|
||||
|
||||
sol::function woof = lua["woof"];
|
||||
double numwoof = woof(20);
|
||||
|
||||
The call ``woof(20)`` generates a :doc:`function_result<proxy>`, which is then implicitly converted to an ``double`` after being called. The intermediate temporary ``function_result`` is then destructed, popping the Lua function call results off the Lua stack.
|
||||
|
||||
.. warning::
|
||||
|
||||
Do NOT save the return type of a :doc:`function_result<proxy>` with ``auto``, as in ``auto numwoof = woof(20);``, and do NOT store it anywhere. Unlike its counterpart :doc:`protected_function_result<proxy>`, ``function_result`` is NOT safe to store as it assumes that its return types are still at the top of the stack and when its destructor is called will pop the number of results the function was supposed to return off the top of the stack. If you mess with the Lua stack between saving ``function_result`` and it being destructed, you will be subject to an incredible number of surprising and hard-to-track bugs. Don't do it.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: call operator / function call
|
||||
|
||||
template<typename... Args>
|
||||
protected_function_result operator()( Args&&... args );
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
decltype(auto) call( Args&&... args );
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
decltype(auto) operator()( types<Ret...>, Args&&... args );
|
||||
|
||||
Calls the function. The second ``operator()`` lets you specify the templated return types using the ``my_func(sol::types<int, std::string>, ...)`` syntax. Function assumes there are no runtime errors, and thusly will call the ``atpanic`` function if an error does occur.
|
45
docs/source/api/object.rst
Normal file
45
docs/source/api/object.rst
Normal file
@ -0,0 +1,45 @@
|
||||
object
|
||||
======
|
||||
general-purpose safety reference to an existing object
|
||||
------------------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class object : reference;
|
||||
|
||||
|
||||
``object``'s goal is to allow someone to pass around the most generic form of a reference to something in Lua (or propogate a ``nil``). It is the logical extension of :doc:`sol::reference<reference>`, and is used in :doc:`sol::table<table>`'s iterators.
|
||||
|
||||
|
||||
members
|
||||
-------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: type conversion
|
||||
|
||||
template<typename T>
|
||||
decltype(auto) as() const;
|
||||
|
||||
Performs a cast of the item this reference refers to into the type ``T`` and returns it. It obeys the same rules as :doc:`sol::stack::get\<T><stack>`.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: type check
|
||||
|
||||
template<typename T>
|
||||
bool is() const;
|
||||
|
||||
Performs a type check using the :doc:`sol::stack::check<stack>` api, after checking if the reference is valid.
|
||||
|
||||
|
||||
non-members
|
||||
-----------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: functions: nil comparators
|
||||
|
||||
bool operator==(const object& lhs, const nil_t&);
|
||||
bool operator==(const nil_t&, const object& rhs);
|
||||
bool operator!=(const object& lhs, const nil_t&);
|
||||
bool operator!=(const nil_t&, const object& rhs);
|
||||
|
||||
These allow a person to compare an ``sol::object`` against ``nil``, which essentially checks if an object references a non-nil value, like so:
|
87
docs/source/api/overload.rst
Normal file
87
docs/source/api/overload.rst
Normal file
@ -0,0 +1,87 @@
|
||||
overload
|
||||
========
|
||||
calling different functions based on argument number/type
|
||||
---------------------------------------------------------
|
||||
|
||||
this function helps users make overloaded functions that can be called from Lua using 1 name but multiple arguments. It is meant to replace the spaghetti of code whre users mock this up by doing strange if statemetns and switches on what version of a function to call based on `luaL_check{number/udata/string}<http://www.Lua.org/manual/5.3/manual.html#luaL_checkinteger>`. Its use is simple: whereever you can pass a function type to Lua, whether its on a :doc:`usertype<usertype>` or if you are just setting any kind of function with ``set`` or ``set_function`` (for :doc:`table<table>` or :doc:`state(_view)<state>`), simply wrap up the functions you wish to be considered for overload resolution on one function like so:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
sol::overload( func1, func2, ... funcN );
|
||||
|
||||
|
||||
The functions can be any kind of function / function object (lambda). Given these functions and struct:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
struct pup {
|
||||
int barks = 0;
|
||||
|
||||
void bark () {
|
||||
++barks; // bark!
|
||||
}
|
||||
|
||||
bool is_cute () const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void ultra_bark( pup& p, int barks) {
|
||||
for (; barks --> 0;) p.bark();
|
||||
}
|
||||
|
||||
void picky_bark( pup& p, std::string s) {
|
||||
if ( s == "bark" )
|
||||
p.bark();
|
||||
}
|
||||
|
||||
You then use it just like you would for any other part of the api:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
sol::state lua;
|
||||
|
||||
lua.set_function( "bark", sol::overload(
|
||||
ultra_bark,
|
||||
[]() { return "the bark from nowhere"; }
|
||||
) );
|
||||
|
||||
lua.new_usertype<pup>( "pup",
|
||||
// regular function
|
||||
"is_cute", &pup::is_cute,
|
||||
// overloaded function
|
||||
"bark", sol::overloaded( &pup::bark, &ultra_bark )
|
||||
);
|
||||
|
||||
Thusly, doing the following in Lua:
|
||||
|
||||
.. code-block:: Lua
|
||||
:caption: pup.lua
|
||||
:linenos:
|
||||
|
||||
local barker = pup.new()
|
||||
pup.bark() -- calls member function pup::bark
|
||||
pup.bark(20) -- calls ultra_bark
|
||||
pup.bark("meow") -- picky_bark, no bark
|
||||
pup.bark("bark") -- picky_bark, bark
|
||||
|
||||
bark(pup, 20) -- calls ultra_bark
|
||||
local nowherebark = bark() -- calls lambda which returns that string
|
||||
|
||||
The actual class produced by ``sol::overload`` is essentially a type-wrapper around ``std::tuple`` that signals to the library that an overload is being created:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: create overloaded set
|
||||
:linenos:
|
||||
|
||||
template <typename... Args>
|
||||
struct overloaded_set : std::tuple<Args...> { /* ... */ };
|
||||
|
||||
template <typename... Args>
|
||||
overloaded_set<Args...> overload( Args&&... args );
|
||||
|
||||
.. note::
|
||||
|
||||
Please keep in mind that doing this bears a runtime cost to find the proper overload. The cost scales directly not exactly with the number of overloads, but the number of functions that have the same argument count as each other (Sol will early-eliminate any functions that do not match the argument count).
|
102
docs/source/api/protected_function.rst
Normal file
102
docs/source/api/protected_function.rst
Normal file
@ -0,0 +1,102 @@
|
||||
protected_function
|
||||
==================
|
||||
Lua function calls that trap errors and provide error handler
|
||||
-------------------------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class protected_function : public reference;
|
||||
|
||||
Inspired by a request from `starwing<https://github.com/starwing>` in the old repository, this class provides the same interface as :doc:`function<function>` but with heavy protection and a potential error handler for any Lua errors and C++ exceptions. When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :doc:`protected_function_result<proxy>` class that gets implicitly converted to the requested return type. For example:
|
||||
|
||||
.. code-block:: lua
|
||||
:caption: pfunc_barks.lua
|
||||
:linenos:
|
||||
|
||||
bark_power = 11;
|
||||
|
||||
function got_problems( error_msg )
|
||||
return "got_problems handler: " .. error_msg
|
||||
end
|
||||
|
||||
function woof ( bark_energy )
|
||||
if bark_energy < 20
|
||||
error("*whine*")
|
||||
end
|
||||
return (bark_energy * (bark_power / 4))
|
||||
end
|
||||
|
||||
The following C++ code will call this function from this file and retrieve the return value:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
sol::state lua;
|
||||
|
||||
lua.open_file( "pfunc_barks.lua" );
|
||||
|
||||
sol::protected_function problematicwoof = lua["woof"];
|
||||
problematicwoof.error_handler = lua["got_problems"];
|
||||
|
||||
auto firstwoof = problematic_woof(20);
|
||||
if ( firstwoof.valid() ) {
|
||||
// Can work with contents
|
||||
double numwoof = first_woof;
|
||||
}
|
||||
else{
|
||||
// An error has occured
|
||||
std::string error = first_woof;
|
||||
}
|
||||
|
||||
// errors, calls handler and then returns a string error from Lua at the top of the stack
|
||||
auto secondwoof = problematic_woof(19);
|
||||
if (secondwoof.valid()) {
|
||||
// Call succeeded
|
||||
double numwoof = firstwoof;
|
||||
}
|
||||
else {
|
||||
// Call failed
|
||||
// Note that if the handler was successfully called, this will include
|
||||
// the additional appended error message information of
|
||||
// "got_problems handler: " ...
|
||||
std::string error = secondwoof;
|
||||
}
|
||||
|
||||
This code is much more long-winded than its :doc:`function<function>` counterpart but allows a person to check for errors. The types here for ``auto`` are ``protected_function_result``. They are implicitly convertible to result types, like all :doc:`proxy-style<proxy>` types are.
|
||||
|
||||
members
|
||||
-------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: call operator / protected function call
|
||||
|
||||
template<typename... Args>
|
||||
protected_function_result operator()( Args&&... args );
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
decltype(auto) call( Args&&... args );
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
decltype(auto) operator()( types<Ret...>, Args&&... args );
|
||||
|
||||
Calls the function. The second ``operator()`` lets you specify the templated return types using the ``my_func(sol::types<int, std::string>, ...)`` syntax. If you specify no return type in any way, it produces s ``protected_function_result``.
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: default handlers
|
||||
|
||||
static const reference& get_default_handler ();
|
||||
static void set_default_handler( reference& ref );
|
||||
|
||||
Get and set the Lua entity that is used as the default error handler. The default is a no-ref error handler. You can change that by calling ``protected_function::set_default_handler( lua["my_handler"] );`` or similar: anything that produces a reference should be fine.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: variable: handler
|
||||
|
||||
reference error_handler;
|
||||
|
||||
The error-handler that is called should a runtime error that Lua can detect occurs. The error handler function needs to take a single string argument (use type std::string if you want to use a C++ function bound to lua as the error handler) and return a single string argument (again, return a std::string or string-alike argument from the C++ function if you're using one as the error handler). If :doc:`exceptions<../exceptions>` are enabled, Sol will attempt to convert the ``.what()`` argument of the exception into a string and then call the error handling function. It is a :doc:`reference<reference>`, as it must refer to something that exists in the lua registry or on the Lua stack. This is automatically set to the default error handler when ``protected_function`` is constructed.
|
||||
|
||||
.. note::
|
||||
|
||||
``protected_function_result`` safely pops its values off the stack when its destructor is called, keeping track of the index and number of arguments that were supposed to be returned. If you remove items below it using ``lua_remove``, for example, it will not behave as expected. Please do not perform fundamentally stack-rearranging operations until the destructor is called (pushing/popping above it is just fine).
|
158
docs/source/api/proxy.rst
Normal file
158
docs/source/api/proxy.rst
Normal file
@ -0,0 +1,158 @@
|
||||
proxy, (protected\_)function_result - proxy_base derivatives
|
||||
============================================================
|
||||
``table[x]`` and ``function(...)`` conversion struct
|
||||
----------------------------------------------------
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
template <typename Recurring>
|
||||
struct proxy_base;
|
||||
|
||||
template <typename Table, typename Key>
|
||||
struct proxy : proxy_base<...>;
|
||||
|
||||
struct function_result : proxy_base<...>;
|
||||
|
||||
struct protected_function_result: proxy_base<...>;
|
||||
|
||||
These classes provide implicit ``operator=`` (``set``) and ``operator T`` (``get``) support for items retrieved from the underlying Lua implementation in Sol, specifically :doc:`sol::table<table>` and the results of function calls on :doc:`sol::function<function>` and :doc:`sol::protected_function<protected_function>`.
|
||||
|
||||
|
||||
.. _proxy:
|
||||
|
||||
proxy
|
||||
-----
|
||||
|
||||
``proxy`` is returned by lookups into :doc:`sol::table<table>` and table-like entities. Because it is templated on key and table type, it would be hard to spell: you can capture it using the word ``auto`` if you feel like you need to carry it around for some reason before using it. ``proxy`` evaluates its arguments lazily, when you finally call ``get`` or ``set`` on it. Here are some examples given the following lua script.
|
||||
|
||||
.. code-block:: lua
|
||||
:linenos:
|
||||
:caption: lua nested table script
|
||||
|
||||
bark = {
|
||||
woof = {
|
||||
[2] = "arf!"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
After loading that file in or putting it in a string and reading the string directly in lua (see :doc:`state`), you can start kicking around with it in C++ like so:
|
||||
|
||||
.. code-block:: c++
|
||||
:linenos:
|
||||
|
||||
sol::state lua;
|
||||
|
||||
// produces proxy, implicitly converts to std::string, quietly destroys proxy
|
||||
std::string x = lua["bark"]["woof"][2];
|
||||
|
||||
|
||||
|
||||
``proxy`` lazy evaluation:
|
||||
|
||||
.. code-block:: c++
|
||||
:linenos:
|
||||
:caption: multi-get
|
||||
|
||||
auto x = lua["bark"];
|
||||
auto y = x["woof"];
|
||||
auto z = x[2];
|
||||
// retrivies value inside of lua table above
|
||||
std::string value = z; // "arf!"
|
||||
// Can change the value later...
|
||||
z = 20;
|
||||
// Yay, lazy-evaluation!
|
||||
int changed_value = z; // now it's 20!
|
||||
|
||||
|
||||
We don't recommend the above to be used across classes or between function: it's more of something you can do to save a reference to a value you like, call a script or run a lua function, and then get it afterwards. You can also set functions (and function objects :ref:`*<note 1>`) this way, and retrieve them as well.
|
||||
|
||||
.. code-block:: c++
|
||||
:linenos:
|
||||
|
||||
lua["bark_value"] = 24;
|
||||
lua["chase_tail"] = floof::chase_tail; // chase_tail is a free function
|
||||
|
||||
|
||||
members
|
||||
-------
|
||||
|
||||
.. code-block:: c++
|
||||
:caption: [overloaded] implicit conversion get
|
||||
|
||||
requires( sol::is_primitive_type<T>::value == true )
|
||||
template <typename T>
|
||||
operator T() const;
|
||||
|
||||
requires( sol::is_primitive_type<T>::value == false )
|
||||
template <typename T>
|
||||
operator T&() const;
|
||||
|
||||
Gets the value associated with the keys the proxy was generated and convers it to the type ``T``. Note that this function will always return ``T&``, a non-const reference, to types which are not based on :doc:`sol::reference<reference>` and not a :doc:`primitive lua type<types>`
|
||||
|
||||
.. code-block:: c++
|
||||
:caption: [overloaded] implicit set
|
||||
|
||||
requires( sol::detail::Function<Fx> == false )
|
||||
template <typename T>
|
||||
proxy& operator=( T&& value );
|
||||
|
||||
requires( sol::detail::Function<Fx> == true )
|
||||
template <typename Fx>
|
||||
proxy& operator=( Fx&& function );
|
||||
|
||||
Sets the value associated with the keys the proxy was generated with to ``value``. If this is a function, calls ``set_function``. If it is not, just calls ``set``. See :ref:`note<note 1>`
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
template <typename Fx>
|
||||
proxy& set_function( Fx&& fx );
|
||||
|
||||
Sets the value associated with the keys the proxy was generated with to a function ``fx``.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
template <typename T>
|
||||
T get( ) const;
|
||||
|
||||
Gets the value associated with the keys the proxy was generated and convers it to the type ``T``.
|
||||
|
||||
|
||||
.. _note 1:
|
||||
|
||||
Note: Function Objects and proxies
|
||||
----------------------------------
|
||||
|
||||
Consider the following:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
:caption: Note 1 Case
|
||||
|
||||
struct doge {
|
||||
int bark;
|
||||
|
||||
void operator()() {
|
||||
bark += 1;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua["object"] = doge{}; // bind constructed doge to "object"
|
||||
|
||||
When you use the ``lua["object"] = doge{};`` from above, keep in mind that Sol detects if this is a function *callable with any kind of arguments*. If ``doge`` has overriden ``return_type operator()( argument_types... )`` on itself, it may result in satisfying the ``requires`` constraint from above. This means that if you have a user-defined type you want to bind as a :doc:`userdata with usertype semantics<usertype>` with this syntax, it might get bound as a function and not as a user-defined type. use ``lua["object"].set(doge)`` directly to avoid this, or ``lua["object"].set_function(doge{})`` to perform this explicitly.
|
||||
|
||||
|
||||
.. _function_result:
|
||||
|
||||
function_result
|
||||
---------------
|
||||
|
||||
``function_result`` is a temporary-only, intermediate-only implicit conversion worker for when :doc:`function<function>` is called. It is *NOT* meant to be stored or captured with ``auto``. It provides fast access to the desired underlying value. It does not implement ``set`` / templated ``operator=``.
|
||||
|
||||
.. _protected_function_result:
|
||||
|
||||
protected_function_result
|
||||
-------------------------
|
||||
|
||||
``protected_function_result`` is a nicer version of ``function_result`` that can be used to detect errors. It sag\fe access to the desired underlying value. It does not implement ``set`` / templated ``operator=``.
|
51
docs/source/api/reference.rst
Normal file
51
docs/source/api/reference.rst
Normal file
@ -0,0 +1,51 @@
|
||||
reference
|
||||
=========
|
||||
general purpose reference to Lua object in registry
|
||||
---------------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: reference
|
||||
|
||||
class reference;
|
||||
|
||||
This type keeps around a reference to something that was on the stack and places it in the Lua registry. It is the backbone for all things that reference items on the stack and needs to keep them around beyond their appearance and lifetime on said Lua stack. Its progeny include :doc:`sol::coroutine<coroutine>`, :doc:`sol::function<function>`, :doc:`sol::<protected_function>`, :doc:`sol::object<object>`, :doc:`sol::table<table>`/:doc:`sol::global_table<table>`, :doc:`sol::<thread>`, and :doc:`sol::userdata<userdata>`.
|
||||
|
||||
|
||||
members
|
||||
-------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: push referred-to element from the stack
|
||||
|
||||
int push() const noexcept;
|
||||
|
||||
This function pushes the referred-to data onto the stack and returns how many things were pushed. Typically, it returns 1.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: reference value
|
||||
|
||||
int registry_index() const noexcept;
|
||||
|
||||
The value of the reference in the registry.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: functions: non-nil, non-null check
|
||||
|
||||
bool valid () const noexcept;
|
||||
explicit operator bool () const noexcept;
|
||||
|
||||
These functions check if the reference at ``T`` is valid: that is, if it is not :doc:`nil<types>` and if it is not non-existing (doesn't refer to anything, including nil) reference. The explicit operator bool allows you to use it in the context of an ``if ( my_obj )`` context.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: retrieves the type
|
||||
|
||||
type get_type() const noexcept;
|
||||
|
||||
Gets the :doc:`sol::type<types>` of the reference; that is, the Lua reference.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: lua_State* of the reference
|
||||
|
||||
lua_State* lua_state() const noexcept;
|
||||
|
||||
Gets the ``lua_State*`` this reference exists in.
|
37
docs/source/api/resolve.rst
Normal file
37
docs/source/api/resolve.rst
Normal file
@ -0,0 +1,37 @@
|
||||
resolve
|
||||
=======
|
||||
utility to pick overloaded C++ function calls
|
||||
---------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: resolve C++ overload
|
||||
|
||||
template <typename... Args, typename F>
|
||||
auto resolve( F f );
|
||||
|
||||
``resolve`` is a function that is meant to help users pick a single function out of a group of overloaded functions in C++. You can use it to pick overloads by specifying the signature as the first template argument. Given a collection of overloaded functions:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
int overloaded(int x);
|
||||
int overloaded(int x, int y);
|
||||
int overloaded(int x, int y, int z);
|
||||
|
||||
You can disambiguate them using ``resolve``:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
auto single = resolve<int(int)>( overloaded );
|
||||
|
||||
Note that this resolution is also built into ``set_function`` on :doc:`table<table>` and :doc:`state<state>`:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
sol::state lua;
|
||||
|
||||
lua.set_function<int(int)>("overloaded", overloaded);
|
||||
lua.set_function<int(int, int)>("overloaded", overloaded);
|
||||
lua.set_function<int(int, int, int)>("overloaded", overloaded);
|
132
docs/source/api/stack.rst
Normal file
132
docs/source/api/stack.rst
Normal file
@ -0,0 +1,132 @@
|
||||
stack namespace
|
||||
===============
|
||||
the nitty-gritty core abstraction layer over Lua
|
||||
------------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
namespace stack
|
||||
|
||||
If you find that the higher level abstractions are not meeting your needs, you may want to delve into the ``stack`` namespace to try and get more out of Sol. ``stack.hpp`` and the ``stack`` namespace define several utilities to work with Lua, including pushing / popping utilities, getters, type checkers, Lua call helpers and more. This namespace is not thoroughly documented as the majority of its interface is mercurial and subject to change between releases to either heavily boost performance or improve the Sol :doc:`api<top>`.
|
||||
|
||||
There are, however, a few :ref:`template customization points<extension_points>` that you may use for your purposes and a handful of potentially handy functions. These may help if you're trying to slim down the code you have to write, or if you want to make your types behave differently throughout the Sol stack. Note that overriding the defaults **can** throw out many of the safety guarantees Sol provides: therefore, modify the :ref:`extension points<extension_points>` at your own discretion.
|
||||
|
||||
functions
|
||||
---------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: get
|
||||
:name: stack-get
|
||||
|
||||
template <typename T>
|
||||
auto get( lua_State* L, int index = -1 )
|
||||
|
||||
Retrieves the value of the object at ``index`` in the stack. The return type varies based on ``T``: with primitive types, it is usually ``T``: for all unrecognized ``T``, it is generally a ``T&`` or whatever the extension point :ref:`stack::getter\<T><getter>` implementation returns. The type ``T`` has top-level ``const`` qualifiers and reference modifiers removed before being forwarded to the extension point :ref:`stack::getter\<T><getter>` struct.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: check
|
||||
|
||||
template <typename T>
|
||||
bool check( lua_State* L, int index = -1 )
|
||||
|
||||
template <typename T, typename Handler>
|
||||
bool check( lua_State* L, int index, Handler&& handler )
|
||||
|
||||
Checks if the object at ``index`` is of type ``T``. If it is not, it will call the ``handler`` function with the index, expected, and actual types.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: push
|
||||
|
||||
// push T inferred from call site, pass args... through to extension point
|
||||
template <typename T, typename... Args>
|
||||
int push( lua_State* L, T&& item, Args&&... args )
|
||||
|
||||
// push T that is explicitly specified, pass args... through to extension point
|
||||
template <typename T, typename Arg, typename... Args>
|
||||
int push( lua_State* L, Arg&& arg, Args&&... args )
|
||||
|
||||
// recursively call the the above "push" with T inferred, one for each argument
|
||||
template <typename... Args>
|
||||
int multi_push( lua_State* L, Args&&... args )
|
||||
|
||||
Based on how it is called, pushes a variable amount of objects onto the stack. in 99% of cases, returns for 1 object pushed onto the stack. For the case of a ``std::tuple<...>``, it recursively pushes each object contained inside the tuple, from left to right, resulting in a variable number of things pushed onto the stack (this enables multi-valued returns when binding a C++ function to a Lua). Can be called with ``sol::stack::push<T>( L, args... )`` to have arguments different from the type that wants to be pushed, or ``sol::stack::push( L, arg, args... )`` where ``T`` will be inferred from ``arg``. The final form of this function is ``sol::stack::multi_push``, which will call one ``sol::stack::push`` for each argument. The ``T`` that describes what to push is first sanitized by removing top-level ``const`` qualifiers and reference qualifiers before being forwarded to the extension point :ref:`stack::pusher\<T><pusher>` struct.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: set_field
|
||||
|
||||
template <bool global = false, typename Key, typename Value>
|
||||
void set_field( lua_State* L, Key&& k, Value&& v );
|
||||
|
||||
template <bool global = false, typename Key, typename Value>
|
||||
void set_field( lua_State* L, Key&& k, Value&& v, int objectindex);
|
||||
|
||||
Sets the field referenced by the key ``k`` to the given value ``v``, by pushing the key onto the stack, pushing the value onto the stack, and then doing the equivalent of ``lua_setfield`` for the object at the given ``objectindex``. Performs optimizations and calls faster verions of the function if the type of ``Key`` is considered a c-style string and/or if its also marked by the templated ``global`` argument to be a global.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: get_field
|
||||
|
||||
template <bool global = false, typename Key>
|
||||
void get_field( lua_State* L, Key&& k [, int objectindex] );
|
||||
|
||||
Gets the field referenced by the key ``k``, by pushing the key onto the stack, and then doing the equivalent of ``lua_getfield``. Performs optimizations and calls faster verions of the function if the type of ``Key`` is considered a c-style string and/or if its also marked by the templated ``global`` argument to be a global.
|
||||
|
||||
This function leaves the retrieved value on the stack.
|
||||
|
||||
.. _extension_points:
|
||||
|
||||
objects (extension points)
|
||||
--------------------------
|
||||
|
||||
The structs below are already overriden for a handful of types. If you try to mess with them for the types ``sol`` has already overriden them for, you're in for a world of thick template error traces and headaches. Overriding them for your own user defined types should be just fine, however.
|
||||
|
||||
.. _getter:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: struct: getter
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct getter {
|
||||
static T get (int index = -1) {
|
||||
// ...
|
||||
return // T, or something related to T.
|
||||
}
|
||||
};
|
||||
|
||||
This is an SFINAE-friendly struct that is meant to expose static function ``get`` that returns a ``T``, or something convertible to it. The default implementation assumes ``T`` is a usertype and pulls out a userdata from Lua before attempting to cast it to the desired ``T``. There are implementations for getting numbers (``std::is_floating``, ``std::is_integral``-matching types), getting ``std::string`` and ``const char*``, getting raw userdata with :doc:`userdata_value<types>` and anything as upvalues with :doc:`upvalue_index<types>`, getting raw `lua_CFunction`_ s, and finally pulling out Lua functions into ``std::function<R(Args...)>``. It is also defined for anything that derives from :doc:`sol::reference<reference>`.
|
||||
|
||||
.. _pusher:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: struct: pusher
|
||||
|
||||
template <typename X, typename = void>
|
||||
struct pusher {
|
||||
template <typename T>
|
||||
static int push ( lua_State* L, T&&, ... ) {
|
||||
// can optionally take more than just 1 argument
|
||||
// ...
|
||||
return // number of things pushed onto the stack
|
||||
}
|
||||
};
|
||||
|
||||
This is an SFINAE-friendly struct that is meant to expose static function ``push`` that returns the number of things pushed onto the stack. The default implementation assumes ``T`` is a usertype and pushes a userdata into Lua with a :doc:`usertype_traits\<T><usertype>` metatable associated with it. There are implementations for pushing numbers (``std::is_floating``, ``std::is_integral``-matching types), getting ``std::string`` and ``const char*``, getting raw userdata with :doc:`userdata<types>` and raw upvalues with :doc:`upvalue<types>`, getting raw `lua_CFunction`_ s, and finally pulling out Lua functions into ``sol::function``. It is also defined for anything that derives from :doc:`sol::reference<reference>`.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: struct: checker
|
||||
|
||||
template <typename T, type expected = lua_type_of<T>, typename = void>
|
||||
struct checker {
|
||||
template <typename Handler>
|
||||
static bool check ( lua_State* L, int index, Handler&& handler ) {
|
||||
// if the object in the Lua stack at index is a T, return true
|
||||
if ( ... ) return true;
|
||||
// otherwise, call the handler function,
|
||||
// with the required 4 arguments, then return false
|
||||
handler(L, index, expected, indextype);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
This is an SFINAE-friendly struct that is meant to expose static function ``check`` that returns the number of things pushed onto the stack. The default implementation simply checks whether the expected type passed in through the template is equal to the type of the object at the specified index in the Lua stack. The default implementation for types which are considered ``userdata`` go through a myriad of checks to support checking if a type is *actually* of type ``T`` or if its the base class of what it actually stored as a userdata in that index.
|
||||
|
||||
.. _lua_CFunction: http://www.Lua.org/manual/5.3/manual.html#lua_CFunction
|
75
docs/source/api/state.rst
Normal file
75
docs/source/api/state.rst
Normal file
@ -0,0 +1,75 @@
|
||||
state
|
||||
=====
|
||||
owning and non-owning state holders for registry and globals
|
||||
------------------------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class state_view;
|
||||
class state : state_view, std::unique_ptr<lua_State*>;
|
||||
|
||||
The most important class here is ``state_view``. This structure takes a ``lua_State*`` that was already created and gives you simple, easy access to Lua's interfaces without taking ownership. ``state`` derives from ``state_view``, inheriting all of this functionality, but has the additional purpose of creating a fresh ``lua_State*`` and managing its lifetime for you in the default constructor.
|
||||
|
||||
The majority of the members between ``state_view`` and :doc:`sol::table<table>` are identical, with added for this higher-level type. Therefore, all of the examples and notes in :doc:`sol::table<table>` apply here as well.
|
||||
|
||||
enumerations
|
||||
------------
|
||||
|
||||
.. _libenum:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: in-lua libraries
|
||||
|
||||
enum class lib : char {
|
||||
base,
|
||||
package,
|
||||
coroutine,
|
||||
string,
|
||||
os,
|
||||
math,
|
||||
table,
|
||||
debug,
|
||||
bit32,
|
||||
io,
|
||||
count // do not use
|
||||
};
|
||||
|
||||
This enumeration details the various base libraries that come with Lua. See the `standard lua libraries`_ for details about the various standard libraries.
|
||||
|
||||
|
||||
members
|
||||
-------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: open standard libraries/modules
|
||||
|
||||
template<typename... Args>
|
||||
void open_libraries(Args&&... args);
|
||||
|
||||
This function takes a number of :ref:`sol::lib<libenum>` as arguments and opens up the associated Lua core libraries.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: script / script_file
|
||||
|
||||
void script(const std::string& code);
|
||||
void script_file(const std::string& filename);
|
||||
|
||||
These functions run the desired blob of either code that is in a string, or code that comes from a filename, on the ``lua_State*``.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: global table / registry table
|
||||
|
||||
global_table globals() const;
|
||||
table registry() const;
|
||||
|
||||
Get either the global table or the Lua registry as a :doc:`sol::table<table>`, which allows you to modify either of them directly. Note that getting the global table from a ``state``/``state_view`` is usually unnecessary as it has all the exact same functions as a :doc:`sol::table<table>` anyhow.
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: Lua set_panic
|
||||
|
||||
void set_panic(lua_CFunction panic);
|
||||
|
||||
Overrides the panic function Lua calls when something unrecoverable or unexpected happens in the Lua VM. Must be a function of the that matches the ``int(*)(lua_State*)`` function signature.
|
||||
|
||||
.. _standard lua libraries: http://www.lua.org/manual/5.2/manual.html#6
|
115
docs/source/api/table.rst
Normal file
115
docs/source/api/table.rst
Normal file
@ -0,0 +1,115 @@
|
||||
table
|
||||
=====
|
||||
a representation of a Lua (meta)table
|
||||
-------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
template <bool global>
|
||||
class table_core;
|
||||
|
||||
typedef table_core<false> table;
|
||||
typedef table_core<true> global_table;
|
||||
|
||||
``sol::table`` is an extremely efficient manipulator of state that brings most of the magic of the Sol abstraction. Capable of doing multiple sets at once, multiple gets into a ``std::tuple``, being indexed into using ``[key]`` syntax and setting keys with a similar syntax (see: :doc:`here<proxy>`), ``sol::table`` is the corner of the interaction between Lua and C++.
|
||||
|
||||
There are two kinds of tables: the global table and non-global tables: however, both have the exact same interface and all ``sol::global_table`` s are convertible to regular ``sol::table`` s.
|
||||
|
||||
Tables are the core of Lua, and they are very much the core of Sol.
|
||||
|
||||
|
||||
members
|
||||
-------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: get / traversing get
|
||||
|
||||
template<typename... Args, typename... Keys>
|
||||
decltype(auto) get(Keys&&... keys) const;
|
||||
|
||||
template<typename T, typename... Keys>
|
||||
decltype(auto) traverse_get(Keys&&... keys) const;
|
||||
|
||||
These functions retrieve items from the table. The first one (``get``) can pull out *multiple* values, 1 for each key value passed into the function. In the case of multiple return values, it is returned in a ``std::tuple<Args...>``. It is similar to doing ``return table["a"], table["b"], table["c"]``. Because it returns a ``std::tuple``, you can use ``std::tie`` on a multi-get to retrieve all of the necessary variables. The second one (``traverse_get``) pulls out a *single* value, using each successive key provided to do another lookup into the last. It is similar to doing ``x = table["a"]["b"]["c"][...]``.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: set / traversing set
|
||||
|
||||
template<typename... Args>
|
||||
table& set(Args&&... args);
|
||||
|
||||
template<typename... Args>
|
||||
table& traverse_set(Args&&... args);
|
||||
|
||||
These functions set items into the table. The first one (``set``) can set *multiple* values, in the form ``Key, Value, Key, Value, ...``. It is similar to ``table["a"] = 1; table["b"] = 2, ...``. The second one (``traverse_set``) sets a *single* value, using all but the last argument as keys to do another lookup into the value retrieved prior to it. It is equivalent to ``table["a"]["b"][...] = final_value;``.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: setting a usertype
|
||||
|
||||
template<typename Class, typename... Args>
|
||||
table& new_usertype(const std::string& name, Args&&... args);
|
||||
template<typename Class, typename CTor0, typename... CTor, typename... Args>
|
||||
table& new_usertype(const std::string& name, Args&&... args);
|
||||
template<typename Class, typename... CArgs, typename... Args>
|
||||
table& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args);
|
||||
|
||||
This class of functions creates a new :doc:`usertype<usertype>` with the specified arguments, providing a few extra details for constructors. After creating a usertype with the specified argument, it passes it to :ref:`set_usertype<set_usertype>`.
|
||||
|
||||
.. _set_usertype:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: setting a pre-created usertype
|
||||
|
||||
template<typename T>
|
||||
table& set_usertype(usertype<T>& user);
|
||||
template<typename Key, typename T>
|
||||
table& set_usertype(Key&& key, usertype<T>& user);
|
||||
|
||||
Sets a previously created usertype with the specified ``key`` into the table. Note that if you do not specify a key, the implementation falls back to setting the usertype with a ``key`` of ``usertype_traits<T>::name``, which is an implementation-defined name that tends to be of the form ``{namespace_name 1}_[{namespace_name 2 ...}_{class name}``.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: begin / end for iteration
|
||||
|
||||
table_iterator begin () const;
|
||||
table_iterator end() const;
|
||||
table_iterator cbegin() const;
|
||||
table_iterator cend() const;
|
||||
|
||||
Provides `input iterators`_ for a table. This allows tables to work with single-pass, input-only algorithms (like ``std::for_each``).
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: iteration with a function
|
||||
|
||||
template <typename Fx>
|
||||
void for_each(Fx&& fx);
|
||||
|
||||
A functional ``for_each`` loop that calls the desired function. The passed in function must take either ``sol::object key, sol::object value`` or take a ``std::pair<sol::object, sol::object> key_value_pair``. This version can be a bit safer as allows the implementation to definitively pop the key/value off the Lua stack after each call of the function.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: operator[] access
|
||||
|
||||
template<typename T>
|
||||
proxy<table&, T> operator[](T&& key);
|
||||
template<typename T>
|
||||
proxy<const table&, T> operator[](T&& key) const;
|
||||
|
||||
Generates a :doc:`proxy<proxy>` that is templated on the table type and the key type. Enables lookup of items and their implicit conversion to a desired type.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: set a function with the specified key into lua
|
||||
|
||||
template<typename Key, typename Fx>
|
||||
state_view& set_function(Key&& key, Fx&& fx, [...]);
|
||||
|
||||
Sets the desired function to the specified key value. Note that it also allows for passing a member function plus a member object: however, using a lambda is almost always better when you want to bind a member function + class instance to a single function call in Lua.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: create a table with defaults
|
||||
|
||||
static table create(lua_State* L, int narr = 0, int nrec = 0);
|
||||
template <typename Key, typename Value, typename... Args>
|
||||
static table create(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args);
|
||||
|
||||
Creates a table, optionally with the specified values pre-set into the table. If ``narr`` or ``nrec`` are 0, then compile-time shenanigans are used to guess the amount of array entries (e.g., integer keys) and the amount of hashable entries (e.g., all other entries).
|
||||
|
||||
.. _input iterators: http://en.cppreference.com/w/cpp/concept/InputIterator
|
43
docs/source/api/thread.rst
Normal file
43
docs/source/api/thread.rst
Normal file
@ -0,0 +1,43 @@
|
||||
thread
|
||||
======
|
||||
a separate state that can contain and run functions
|
||||
---------------------------------------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class thread : public reference { /* ... */ };
|
||||
|
||||
``sol::thread`` is a separate runnable part of the Lua VM that can be used to execute work separately from the main thread, such as with :doc:`coroutines<coroutine>`. To take a table or a coroutine and run it specifically on the ``sol::thread`` you either pulled out of lua or created, just get that function through the :ref:`state of the thread<thread_state>`
|
||||
|
||||
members
|
||||
-------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: view into thread_state()'s state
|
||||
|
||||
state_view state() const;
|
||||
|
||||
This retrieves the current state of the thread, producing a :doc:`state_view<state>` that can be manipulated like any other. :doc:`Coroutines<coroutine>` pulled from Lua using the thread's state will be run on that thread specifically.
|
||||
|
||||
.. _thread_state:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: retrieve thread state object
|
||||
|
||||
lua_State* thread_state () const;
|
||||
|
||||
This function retrieves the ``lua_State*`` that represents the thread.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: current thread status
|
||||
|
||||
thread_status status () const;
|
||||
|
||||
Retrieves the :doc:`thread status<types>` that describes the current state of the thread.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: thread creation
|
||||
|
||||
static thread create (lua_State* L);
|
||||
|
||||
Creates a new thread from the given a ``lua_State*``.
|
29
docs/source/api/top.rst
Normal file
29
docs/source/api/top.rst
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
api reference manual
|
||||
====================
|
||||
|
||||
Browse the various function and classes :doc:`Sol<../index>` utilizes to make your life easier when working with Lua.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:caption: Sol API
|
||||
:name: apitoc
|
||||
:maxdepth: 1
|
||||
|
||||
compatibility
|
||||
coroutine
|
||||
error
|
||||
function
|
||||
protected_function
|
||||
object
|
||||
overload
|
||||
proxy
|
||||
reference
|
||||
resolve
|
||||
stack
|
||||
state
|
||||
table
|
||||
thread
|
||||
types
|
||||
usertype
|
||||
userdata
|
190
docs/source/api/types.rst
Normal file
190
docs/source/api/types.rst
Normal file
@ -0,0 +1,190 @@
|
||||
types
|
||||
=====
|
||||
nil, lua_primitive type traits, and other fundamentals
|
||||
------------------------------------------------------
|
||||
|
||||
The ``types.hpp`` header contains various fundamentals and utilities of Sol.
|
||||
|
||||
|
||||
enumerations
|
||||
------------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: syntax of a function called by Lua
|
||||
|
||||
enum class call_syntax {
|
||||
dot = 0,
|
||||
colon = 1
|
||||
};
|
||||
|
||||
This enumeration indicates the syntax a function was called with in a specific scenario. There are two ways to call a function: with ``obj:func_name( ... )`` or ``obj.func_name( ... );`` The first one passes "obj" as the first argument: the second one does not. In the case of usertypes, this is used to determine whether the call to a :doc:`constructor/initializer<usertype>` was called with a ``:`` or a ``.``, and not misalign the arguments.
|
||||
|
||||
.. _call_status:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: status of a Lua function call
|
||||
|
||||
enum class call_status : int {
|
||||
ok = LUA_OK,
|
||||
yielded = LUA_YIELD,
|
||||
runtime = LUA_ERRRUN,
|
||||
memory = LUA_ERRMEM,
|
||||
handler = LUA_ERRERR,
|
||||
gc = LUA_ERRGCMM
|
||||
};
|
||||
|
||||
This strongly-typed enumeration contains the errors potentially generated by a call to a :doc:`protected function<protected_function>` or a :doc:`coroutine<coroutine>`.
|
||||
|
||||
.. _thread_status:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: status of a Lua thread
|
||||
|
||||
enum class thread_status : int {
|
||||
normal = LUA_OK,
|
||||
yielded = LUA_YIELD,
|
||||
error_runtime = LUA_ERRRUN,
|
||||
error_memory = LUA_ERRMEM,
|
||||
error_gc = LUA_ERRGCMM,
|
||||
error_handler = LUA_ERRERR,
|
||||
dead,
|
||||
};
|
||||
|
||||
This enumeration contains the status of a thread. The ``thread_status::dead`` state is generated when the thread has nothing on its stack and it is not running anything.
|
||||
|
||||
.. _type:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: type enumeration
|
||||
|
||||
enum class type : int {
|
||||
none = LUA_TNONE,
|
||||
nil = LUA_TNIL,
|
||||
string = LUA_TSTRING,
|
||||
number = LUA_TNUMBER,
|
||||
thread = LUA_TTHREAD,
|
||||
boolean = LUA_TBOOLEAN,
|
||||
function = LUA_TFUNCTION,
|
||||
userdata = LUA_TUSERDATA,
|
||||
lightuserdata = LUA_TLIGHTUSERDATA,
|
||||
table = LUA_TTABLE,
|
||||
poly = none | nil | string | number | thread |
|
||||
table | boolean | function | userdata | lightuserdata
|
||||
};
|
||||
|
||||
The base types that Lua natively communicates in and understands. Note that "poly" isn't really a true type, it's just a symbol used in Sol for something whose type hasn't been checked (and you should almost never see it).
|
||||
|
||||
|
||||
type traits
|
||||
-----------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: lua_type_of trait
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct lua_type_of;
|
||||
|
||||
This type trait maps a C++ type to a :ref:`type enumation<type>` value. The default value is ``type::userdata``.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: primitive checking traits
|
||||
|
||||
template <typename T>
|
||||
struct is_lua_primitive;
|
||||
|
||||
template <typename T>
|
||||
struct is_proxy_primitive;
|
||||
|
||||
|
||||
This trait is used by :doc:`proxy<proxy>` to know which types should be returned as references to internal Lua memory (e.g., ``userdata`` types) and which ones to return as values (strings, numbers, :doc:`references<reference>`). ``std::reference_wrapper``, ``std::tuple<...>`` are returned as values, but their contents are/can be references. The default value is false.
|
||||
|
||||
.. nil:
|
||||
|
||||
special types
|
||||
-------------
|
||||
.. code-block:: cpp
|
||||
:caption: nil
|
||||
|
||||
strunil_t {};
|
||||
const nil_t nil {};
|
||||
bool operator==(nil_t, nil_t);
|
||||
bool operator!=(nil_t, nil_t);
|
||||
|
||||
``nil`` is a constant used to signify Lua's ``nil``, which is a type and object that something does not exist. It is comparable to itself, :doc:`sol::object<object>` and :doc:`proxy values<proxy>`.
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: non_null
|
||||
|
||||
template <typename T>
|
||||
struct non_null {};
|
||||
|
||||
A tag type that, when used with :doc:`stack::get\<non_null\<T*>><stack>`, does not perform a ``nil`` check when attempting to retrieve the userdata pointer.
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: type list
|
||||
|
||||
template <typename... Args>
|
||||
struct types;
|
||||
|
||||
A type list that, unlike ``std::tuple<Args...>``, does not actually contain anything. Used to indicate types and groups of types all over Sol.
|
||||
|
||||
|
||||
functions
|
||||
---------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: type_of
|
||||
|
||||
template<typename T>
|
||||
type type_of();
|
||||
|
||||
type type_of(lua_State* L, int index);
|
||||
|
||||
|
||||
These functions get the type of a C++ type ``T`` or the type at the specified index on the Lua stack.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: type checking convenience functions
|
||||
|
||||
int type_panic(lua_State* L, int index, type expected, type actual);
|
||||
|
||||
int no_panic(lua_State*, int, type, type) noexcept;
|
||||
|
||||
void type_error(lua_State* L, int expected, int actual);
|
||||
|
||||
void type_error(lua_State* L, type expected, type actual);
|
||||
|
||||
void type_assert(lua_State* L, int index, type expected, type actual);
|
||||
|
||||
void type_assert(lua_State* L, int index, type expected);
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: type name retrieval
|
||||
|
||||
std::string type_name(lua_State*L, type t);
|
||||
|
||||
Gets the Lua-specified name of the :ref:`type<type>`.
|
||||
|
||||
structs
|
||||
-------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct userdata_value {
|
||||
void* value;
|
||||
};
|
||||
|
||||
struct light_userdata_value {
|
||||
void* value;
|
||||
};
|
||||
|
||||
struct up_value_index {
|
||||
int index;
|
||||
};
|
||||
|
||||
|
||||
Types that differentiate between the two kinds of ``void*`` Lua hands back from its API: full userdata and light userdata, as well as a type that modifies the index passed to ``get`` to refer to `up values`_ These types can be used to trigger different underlying API calls to Lua when working with :doc:`stack<stack>` namespace and the ``push``/``get``/``pop``/``check`` functions.
|
||||
|
||||
.. _up values: http://www.Lua.org/manual/5.3/manual.html#4.4
|
13
docs/source/api/userdata.rst
Normal file
13
docs/source/api/userdata.rst
Normal file
@ -0,0 +1,13 @@
|
||||
userdata
|
||||
===========
|
||||
reference to a userdata
|
||||
-----------------------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: (light\_)userdata reference
|
||||
|
||||
class userdata : public reference;
|
||||
|
||||
class light_userdata : public reference;
|
||||
|
||||
These type is meant to hold a reference to a (light) userdata from Lua and make it easy to push an existing userdata onto the stack. It is essentially identical to :doc:`reference<reference>` in every way, just with a definitive C++ type.
|
252
docs/source/api/usertype.rst
Normal file
252
docs/source/api/usertype.rst
Normal file
@ -0,0 +1,252 @@
|
||||
usertype<T>
|
||||
===========
|
||||
structures and classes from C++ made available to Lua code
|
||||
----------------------------------------------------------
|
||||
|
||||
*Note: ``T`` refers to the type being turned into a usertype.*
|
||||
|
||||
While other frameworks extend lua's syntax or create Data Structure Languages (DSLs) to create classes in lua, :doc:`sol<../index>` instead offers the ability to generate easy bindings. These use metatables and userdata in lua for their implementation. Given this C++ class:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
struct ship {
|
||||
int bullets = 20;
|
||||
int life = 100;
|
||||
|
||||
bool shoot () {
|
||||
if (bullets > 0) {
|
||||
--bullets;
|
||||
// successfully shot
|
||||
return true;
|
||||
}
|
||||
// cannot shoot
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hurt (int by) {
|
||||
life -= by;
|
||||
// have we died?
|
||||
return life < 1;
|
||||
}
|
||||
};
|
||||
|
||||
You can bind the it to lua using the following C++ code:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
sol::state lua;
|
||||
|
||||
lua.new_usertype<ship>( "ship", // the name of the class, as you want it to be used in lua
|
||||
// List the member functions you wish to bind:
|
||||
// "name_of_item", &class_name::function_or_variable
|
||||
"shoot", &ship::shoot,
|
||||
"hurt", &ship::hurt,
|
||||
// bind variable types, too
|
||||
"life", &ship::bullets
|
||||
// names in lua don't have to be the same as C++,
|
||||
// but it probably helps if they're kept the same,
|
||||
// here we change it just to show its possible
|
||||
"bullet_count", &ship::bullets
|
||||
);
|
||||
|
||||
|
||||
Equivalently, you can also write:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
:emphasize-lines: 4,12
|
||||
|
||||
sol::state lua;
|
||||
|
||||
// Use constructor directly
|
||||
usertype<ship> shiptype(
|
||||
"shoot", &ship::shoot,
|
||||
"hurt", &ship::hurt,
|
||||
"life", &ship::bullets
|
||||
"bullet_count", &ship::bullets
|
||||
);
|
||||
|
||||
// set usertype explicitly, with the given name
|
||||
lua.set_usertype<ship>( "ship", shiptype );
|
||||
|
||||
// shiptype is now a useless skeleton type, just let it destruct naturally and don't use it again.
|
||||
|
||||
|
||||
Note that here, because the C++ class is default-constructible, it will automatically generate a creation function that can be called in lua called "new" that takes no arguments. You can use it like this in lua code:
|
||||
|
||||
.. code-block:: lua
|
||||
:linenos:
|
||||
|
||||
fwoosh = ship.new()
|
||||
local success = fwoosh:shoot() -- note the ":" that is there: this is mandatory for member function calls
|
||||
local is_dead = fwoosh:hit(20)
|
||||
-- check if it works
|
||||
print(is_dead) -- the ship is not dead at this point
|
||||
print(fwoosh.life .. "life left") -- 80 life left
|
||||
print(fwoosh.bullet_count) -- 19
|
||||
|
||||
|
||||
There are more advanced use cases for how to create and use a usertype, which are all based on how to use its constructor (see below).
|
||||
|
||||
enumerations
|
||||
------------
|
||||
|
||||
.. _meta_function_enum:
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: meta_function enumeration for names
|
||||
:linenos:
|
||||
|
||||
enum class meta_function {
|
||||
construct,
|
||||
index,
|
||||
new_index,
|
||||
mode,
|
||||
call,
|
||||
metatable,
|
||||
to_string,
|
||||
length,
|
||||
unary_minus,
|
||||
addition,
|
||||
subtraction,
|
||||
multiplication,
|
||||
division,
|
||||
modulus,
|
||||
power_of,
|
||||
involution = power_of,
|
||||
concatenation,
|
||||
equal_to,
|
||||
less_than,
|
||||
less_than_or_equal_to,
|
||||
garbage_collect,
|
||||
call_function,
|
||||
};
|
||||
|
||||
|
||||
Use this enumeration to specify names in a manner friendlier than memorizing the special lua metamethod names for each of these. Each binds to a specific operation indicated by the descriptive name of the enum.
|
||||
|
||||
members
|
||||
-------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: usertype<T> constructor
|
||||
|
||||
template<typename... Args>
|
||||
usertype<T>(Args&&... args);
|
||||
|
||||
|
||||
The constructor of usertype takes a variable number of arguments. It takes an even number of arguments (except in the case where the very first argument is passed as the :ref:`constructor<constructor>` or in the case of specifying a custom :ref:`destructor<destructor>`). Names can either be strings, :ref:`special meta_function enumerations<meta_function_enum>`, or one of the special indicators for initializers.
|
||||
|
||||
|
||||
.. _constructor:
|
||||
|
||||
* ``"{name}", constructors<Type-List-0, Type-List-1, ...>``
|
||||
- ``Type-List-N`` must be a ``sol::types<Args...>``, where ``Args...`` is a list of types that a constructor takes. Supports overloading by default
|
||||
- If you pass the ``constructors<...>`` argument first when constructing the usertype, then it will automatically be given a ``"{name}"`` of ``"new"``
|
||||
* ``"{name}", initializers( func1, func2, ... )``
|
||||
- Creates initializers that, given one or more functions, provides an overloaded lua function for creating a the specified type.
|
||||
+ The function must have the argument signature ``func T*, Arguments... )`` or ``func( T&, Arguments... )``, where the pointer or reference will point to a place of allocated memory that has an unitialized ``T``. Note that lua controls the memory.
|
||||
|
||||
.. _destructor:
|
||||
|
||||
* ``"__gc", sol::destructor( func )`` or ``sol::meta_function::garbage_collect, sol::destructor( func )``
|
||||
- Creates a custom destructor that takes an argument ``T*`` or ``T&`` and expects it to be destructed/destroyed. Note that lua controls the memory and thusly will deallocate the necessary space AFTER this function returns (e.g., do not call ``delete`` as that will attempt to deallocate memory you did not ``new``).
|
||||
- If you just want the default constructor, you can replace the second argument with ``sol::default_destructor``.
|
||||
- The usertype will throw if you specify a destructor specifically but do not map it to ``sol::meta_function::gc`` or a string equivalent to ``"__gc"``.
|
||||
* ``"{name}", &free_function``
|
||||
- Binds a free function / static class function / function object (lambda) to ``"{name}"``. The first argument must be ``T*`` or ``T&`` in this case.
|
||||
* ``"{name}", &type::function_name`` or ``"{name}", &type::member_variable``
|
||||
- Binds a typical member function or variable to ``"{name}"``. In the case of a member variable or member function, ``type`` must be ``T`` or a base of ``T``.
|
||||
* ``sol::base_classes, sol::bases<Bases...>``
|
||||
- Tells a usertype what its base classes are. If you have exceptions turned on, this need not be necessary: if you do not then you need this to have derived-to-base conversions work properly. See :ref:`inheritance<usertype_inheritance>`.
|
||||
|
||||
|
||||
overloading
|
||||
-----------
|
||||
|
||||
Functions set here support overloading. See :doc:`here<overload>` for an example.
|
||||
|
||||
|
||||
.. _usertype_inheritance:
|
||||
|
||||
inheritance
|
||||
-----------
|
||||
|
||||
Sol can adjust pointers from derived classes to base classes at runtime, but it has some caveats based on what you compile with:
|
||||
|
||||
.. _exceptions_enabled:
|
||||
|
||||
**With Exceptions Enabled**
|
||||
|
||||
You do not need to manually specify the base classes. We use a technique that infinitely scales and automatically casts derived pointers to their base classes by exploiting the necessity of exception type matching.
|
||||
|
||||
.. _exceptions_disabled:
|
||||
|
||||
**With Exceptions Disabled**
|
||||
|
||||
You must specify the ``sol::base_classes`` tag with the ``sol::bases<Types...>()`` argument, where ``Types...`` are all the base classes of the single type ``T`` that you are making a usertype out of. when you create the usertype. If you turn exceptions off and are also completely mad and turn off :doc:`run-time type information<../rtti>` as well, we fallback to a id-based systemthat still requires you to specifically list the base classes as well. For example:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
struct A {
|
||||
int a = 10;
|
||||
virtual int call() { return 0; }
|
||||
};
|
||||
struct B : A {
|
||||
int b = 11;
|
||||
virtual int call() { return 20; }
|
||||
};
|
||||
|
||||
Then, to register the base classes explicitly:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
:emphasize-lines: 5,6
|
||||
|
||||
sol::state lua;
|
||||
|
||||
lua.new_usertype<B>( "B",
|
||||
"call", &B::call,
|
||||
// List bases explicitly if you disable exceptions
|
||||
sol::base_classes, sol::bases<A>()
|
||||
);
|
||||
|
||||
Note that Sol does not support down-casting from a base class to a derived class at runtime.
|
||||
|
||||
inheritance + overloading
|
||||
-------------------------
|
||||
|
||||
While overloading is supported regardless of `inheritance<inheritance>` caveats or not, the current version of Sol has a first-match, first-call style of overloading when it comes to inheritance. Put the functions with the most derived arguments first to get the kind of matching you expect.
|
||||
|
||||
.. todo::
|
||||
|
||||
Later versions of Sol will introduce a kind of overload resolution system that will rank overloads and call the best one, which will unfortunately come at a small performance penalty if you explicitly use overloads of many functions that have the same arity (argument count).
|
||||
|
||||
traits
|
||||
------
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: usertype_traits<T>
|
||||
:linenos:
|
||||
|
||||
template<typename T>
|
||||
struct usertype_traits {
|
||||
static const std::string name;
|
||||
static const std::string metatable;
|
||||
static const std::string variable_metatable;
|
||||
static const std::string gc_table;
|
||||
};
|
||||
|
||||
|
||||
This trait is used to provide names for the various metatables and global tables used to perform cleanup and lookup. They are automatically generated at runtime. In the case of RTTI being present, Sol will attempt to demangle the name from ``std::type_info`` to produce a valid name. If RTTI is disabled, Sol attempts to parse the output of ``__PRETTY_FUCNTION__`` (``g++``/``clang++``) or ``_FUNCDSIG`` (``vc++``) to get the proper type name. If you have a special need you can override the names for your specific type.
|
||||
|
||||
|
||||
performance note
|
||||
----------------
|
||||
|
||||
.. note::
|
||||
|
||||
Note that performance for member function calls goes down by a fixed overhead if you also bind variables as well as member functions. This is purely a limitation of the lua implementation and there's, unfortunately, nothing that can be done about it. If you bind only functions and no variables, however, Sol will automatically optimize the lua runtime and give you the maximum performance possible. *Please consider ease of use and maintenance of code before you make everything into functions.*
|
18
docs/source/benchmarks.rst
Normal file
18
docs/source/benchmarks.rst
Normal file
@ -0,0 +1,18 @@
|
||||
benchmarks
|
||||
==========
|
||||
because somebody is going to ask eventually...
|
||||
----------------------------------------------
|
||||
|
||||
|
||||
These are some informal and formal benchmarks done by both the developers of sol and other library developers / users. We leave you to interpret the data as you see fit.
|
||||
|
||||
* `lua_binding_benchmarks`_ by satoren (developer of `kaguya`_) (`Sol`_ is the "sol2" entry)
|
||||
* `lua-bench`_ by ThePhD (developer of `Sol`_)
|
||||
|
||||
As of the writing of this documentation (March 11th, 2016), :doc:`Sol<index>` (Sol2) seems to take the cake in most categories for speed!
|
||||
|
||||
|
||||
.. _lua-bench: https://github.com/ThePhD/lua-bench
|
||||
.. _lua_binding_benchmarks: http://satoren.github.io/lua_binding_benchmark/
|
||||
.. _kaguya: https://github.com/satoren/kaguya
|
||||
.. _Sol: https://github.com/ThePhD/sol2
|
291
docs/source/conf.py
Normal file
291
docs/source/conf.py
Normal file
@ -0,0 +1,291 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Sol documentation build configuration file, created by
|
||||
# sphinx-quickstart on Mon Feb 29 21:49:51 2016.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.doctest',
|
||||
'sphinx.ext.todo'
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'Sol'
|
||||
copyright = '2016, ThePhD'
|
||||
author = 'ThePhD'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '2.0.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '2.0.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# The default highlighting language: default is python
|
||||
highlight_language = 'c++'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'alabaster'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (relative to this directory) to use as a favicon of
|
||||
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Language to be used for generating the HTML full-text search index.
|
||||
# Sphinx supports the following languages:
|
||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
|
||||
# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr'
|
||||
#html_search_language = 'en'
|
||||
|
||||
# A dictionary with options for the search language support, empty by default.
|
||||
# Now only 'ja' uses this config value
|
||||
#html_search_options = {'type': 'default'}
|
||||
|
||||
# The name of a javascript file (relative to the configuration directory) that
|
||||
# implements a search results scorer. If empty, the default will be used.
|
||||
#html_search_scorer = 'scorer.js'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Soldoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'Sol.tex', 'Sol Documentation',
|
||||
'ThePhD', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'sol', 'Sol Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'Sol', 'Sol Documentation',
|
||||
author, 'Sol', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
30
docs/source/exceptions.rst
Normal file
30
docs/source/exceptions.rst
Normal file
@ -0,0 +1,30 @@
|
||||
exceptions
|
||||
==========
|
||||
since somebody is going to ask about it...
|
||||
------------------------------------------
|
||||
|
||||
Yes, you can turn off exceptions in Sol with ``#define SOL_NO_EXCEPTIONS`` before including or by passing the command line argument that defines ``SOL_NO_EXCEPTIONS``. We don't recommend it unless you're playing with a Lua distro that also doesn't play nice with exceptions (like non-x64 versions of :ref:`LuaJIT<LuaJIT and exceptions>` ).
|
||||
|
||||
If you turn this off, the default `at_panic<http://www.Lua.org/manual/5.3/manual.html#4.6>` function :doc:`state<api/state>` set for you will not throw. Instead, the default Lua behavior of aborting will take place (and give you no chance of escape unless you implement your own at_panic function and decide to try ``longjmp`` out).
|
||||
|
||||
Note that this will also disable :doc:`protected_function<api/protected_function>`'s ability to catch C++ errors you throw from C++ functions bound to Lua that you are calling through that API. So, only turn off exceptions in Sol if you're sure you're never going to use them ever. Of course, if you are ALREADY not using Exceptions, you don't have to particularly worry about this and now you can use Sol!
|
||||
|
||||
If there is a place where a throw statement is called or a try/catch is used and it is not hidden behind a ``#ifndef SOL_NO_EXCEPTIONS`` block, please file an issue at `issue`_ or submit your very own pull request so everyone can benefit!
|
||||
|
||||
|
||||
inheritance
|
||||
-----------
|
||||
|
||||
Sol uses a nifty feature of exceptions to perform infinitely scaling, compiler-correct casting of derived pointers to their base classes. If you disable this and you want to have a :doc:`user-defined type<api/usertype>` that can be used with functions that take its base class or similar, you must specify those base classes manually using the :doc:`base_classes<api/usertype>` tag with the :doc:`bases\<Types...><api/usertype>` arguments when you create the usertype. If you turn exceptions off and are also completely mad and turn off :doc:`run-time type information<rtti>` as well, we fallback to a id-based base class system that still requires you to specifically list the base classes using the method mentioned previously. But if you have already turned off rtti and exceptions, you must really know what you're doing, so you should be just fine!
|
||||
|
||||
|
||||
.. _LuaJIT and exceptions:
|
||||
|
||||
LuaJIT and exceptions
|
||||
---------------------
|
||||
|
||||
It is important to note that a popular 5.1 distribution of Lua, LuaJIT, has some serious `caveats regarding exceptions<http://luajit.org/extensions.html#exceptions>`. LuaJIT's exception promises are flaky at best on x64 (64-bit) platforms, and entirely terrible on non-x64 (32-bit, ARM, etc.) platorms. The trampolines we have in place for all functions bound through conventional means in Sol will catch exceptions and turn them into Lua errors so that LuaJIT remainds unperturbed, but if you link up a C function directly yourself and throw, chances are you might have screwed the pooch.
|
||||
|
||||
Testing in `this closed issue<https://github.com/ThePhD/sol2/issues/28>` reveals that it doesn't play nice on 64-bit Linux in many cases either, especially when it hits an error internal to the interpreter (and does not go through Sol). We do have tests, however, that compile for our continuous integration check-ins that check this functionality across several compilers and platforms to keep you protected and given hard, strong guarantees for what happens if you throw in a function bound by Sol. If you stray outside the realm of Sol's protection, however... Good luck.
|
||||
|
||||
.. _issue: https://github.com/ThePhD/sol2/issues/
|
168
docs/source/features.rst
Normal file
168
docs/source/features.rst
Normal file
@ -0,0 +1,168 @@
|
||||
features
|
||||
========
|
||||
what does Sol (and other libraries) support?
|
||||
--------------------------------------------
|
||||
|
||||
The goal of Sol is to provide an incredibly clean API that provides high performance (comparable or better than the C it was written on) and extreme ease of use. That is, users should be able to say: "this works pretty much how I expected it to."
|
||||
|
||||
For the hard technical components of Lua and its ecosystem we support, here is the full rundown:
|
||||
|
||||
what Sol supports
|
||||
-----------------
|
||||
|
||||
* Support for Lua 5.1, 5.2, and 5.3. We achieve this through our "doc:`compatibility<compatibility>` header.
|
||||
|
||||
* :doc:`Table<api/table>` support: setting values, getting values of multiple (different) types
|
||||
- :doc:`Lazy evaluation<api/proxy>` for nested/chained queries
|
||||
``table["a"]["b"]["c"] = 24;``
|
||||
- Implicit conversion to the types you want
|
||||
``double b = table["computed_value"];``
|
||||
|
||||
* Support for callables (functions, lambdas, member functions)
|
||||
- Pull out any Lua function with :doc:`sol::function<api/function>`
|
||||
``sol::function fx = table["socket_send"];``
|
||||
- Can also set callables into :doc:`operator[] proxies<api/proxy>`
|
||||
``table["move_dude"] = engine::move_dude;``
|
||||
- Safety: use :doc:`sol::protected_function<api/protected_function>` to catch any kind of error
|
||||
+ ANY kind: C++ exception or Lua erors are trapped and run through the optional ``error_handler`` variable
|
||||
- *Advanced:* Overloading of a single function so you don't need to do boring typechecks
|
||||
|
||||
* User-Defined Type (:doc:`sol::usertype<api/usertype>` in the API) support:
|
||||
- Set member functions to be called
|
||||
- Set member variables
|
||||
- Use free-functions that take the Type as a first argument (pointer or reference)
|
||||
- Support for "Factory" classes that do not expose constructor or destructor
|
||||
- Modifying memory of userdata in C++ directly affects Lua without copying, and
|
||||
- Modifying userdata in Lua directly affects C++ references/pointers
|
||||
``my_class& a = table["a"];``
|
||||
``my_class* a_ptr = table["a"];``
|
||||
- If you want a copy, just use value semantics and get copies:
|
||||
``my_class a = table["a"];``
|
||||
|
||||
* Thread/Coroutine support
|
||||
- Use, resume, and play with :doc:`<coroutines<api/coroutine>` like regular functions
|
||||
- Get and use them even on a separate Lua :doc:`thread<api/thread>`
|
||||
- Monitor status and get check errors
|
||||
|
||||
* *Advanced:* Customizable and extensible to your own types if you override :doc:`getter/pusher/checker<api/stack>` template struct definitions.
|
||||
|
||||
|
||||
The Feature Matrix™
|
||||
-------------------
|
||||
|
||||
The below feature table checks for the presence of something. It, however, does not actually account for any kind of laborious syntax.
|
||||
|
||||
✔ full support
|
||||
- partial support / wonky support
|
||||
✗ no support
|
||||
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| | plain C | luawrapper | lua-intf | luabind | Selene | Sol | oolua | lua-api-pp | kaguya |
|
||||
| | | | | | | | | | |
|
||||
+===========================+=============+============+==========+=========+==========+===========+===========+================+==========+
|
||||
| tables | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| table chaining | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| arbitrary keys | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| user-defined types (udts) | - | ✔ | ✔ | ✔ | ✔ | ✔ | - | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| udts: member functions | - | ✔ | ✔ | ✔ | ✔ | ✔ | - | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| udts: variables | - | - | - | - | - | ✔ | - | - | - |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| stack abstractions | - | ✔ | - | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| function binding | - | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| protected function | ✔ | ✗ | - | - | - | ✔ | - | ✔ | - |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| multi-return | - | ✗ | ✗ | ✔ | ✔ | ✔ | - | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| inheritance | - | ✗ | ✗ | ✔ | ✔ | ✔ | - | - | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| overloading | - | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ | ✗ | ✗ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| thread | ✔ | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| coroutines | ✔ | ✗ | ✗ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| no-rtti support | ✔ | ✗ | - | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| no-exception support | ✔ | ✗ | - | - | ✗ | ✔ | ✗ | ✗ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| Lua 5.1 | ✔ | ✔ | - | ✔ | ✗ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| Lua 5.2 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| Lua 5.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| luajit | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
| distribution | compile | header | both | compile | header | header | compile | compile | header |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+
|
||||
|
||||
notes on implementations
|
||||
------------------------
|
||||
|
||||
Plain C -
|
||||
|
||||
* Obviously you can do anything you want with Plain C, but the effort involved is astronomical in comparison to what frameworks offer
|
||||
* Does not scale very well (in terms of developer ease of use)
|
||||
* Compilation (or package manager use) is obviously required for your platform and required to use ANY of these libraries whatsoever
|
||||
|
||||
luawrapper -
|
||||
|
||||
* Takes the approach of writing and reading tables using ``readVariable`` and ``writeVariable`` functions
|
||||
* C++11
|
||||
* No macros
|
||||
* The interface can be clunky (no table-like data structures: most things go though ``readVariable`` / ``writeVariable``)
|
||||
|
||||
|
||||
lua-intf -
|
||||
|
||||
* Can be both header-only or compiled
|
||||
* C++11
|
||||
* Macro-based registration (strange pseudo-language)
|
||||
* Fairly fast in most regards
|
||||
* Registering classes/"modules" in using C++ code is extremely verbose
|
||||
|
||||
luabind -
|
||||
|
||||
* One of the older frameworks, but has many people updating it and providing "deboostified" versions
|
||||
* Strange in-lua keywords and parsing to allow for classes to be written in lua
|
||||
- not sure if good feature; vendor lock-in to that library to depend on this specific class syntax?
|
||||
|
||||
Selene -
|
||||
|
||||
* member variables are automatically turned into ``obj:set_x( value )`` to set and ``obj:x()`` to get
|
||||
* Registering classes/"modules" in using C++ code is extremely verbose
|
||||
|
||||
Sol -
|
||||
|
||||
* Overloading support can get messy with inheritance, see :doc:`here<api/overload>`
|
||||
* Only (?) library that supports table-like use of variables as shown in the :doc:`sneak peek<index>`
|
||||
* C++14/"C++1y" (-std=c++14, -std=c++1y, =std=c++1z) flags are used (available since GCC 4.9 and Clang 3.5)
|
||||
|
||||
oolua -
|
||||
|
||||
* The syntax for this library is thicker than a brick. No, seriously. `Go read the docs.`_
|
||||
|
||||
.. _ fn1:
|
||||
|
||||
lua-api-pp -
|
||||
|
||||
* Compiled, but the recommendation is to add the source files directly to your project
|
||||
* Userdata registration with nice, thick macros: LUAPP_USERDATA( ... ) plus a bunch of free functions that take a ``T& self`` argument
|
||||
* C++11-ish in some regards
|
||||
|
||||
kaguya -
|
||||
|
||||
* Probably the closest in implementation details and interface to Sol itself
|
||||
* Inspired coroutine support for Sol
|
||||
* Library author (satoren) is a nice guy!
|
||||
* C++11/14, or boostified (which makes it C++03 compatible)
|
||||
|
||||
|
||||
.. _Go read the docs.: https://oolua.org/docs/index.html
|
103
docs/source/index.rst
Normal file
103
docs/source/index.rst
Normal file
@ -0,0 +1,103 @@
|
||||
.. Sol documentation master file, created by
|
||||
sphinx-quickstart on Mon Feb 29 21:49:51 2016.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Sol 2.0.0
|
||||
=========
|
||||
a fast, simple C++ and Lua Binding
|
||||
----------------------------------
|
||||
|
||||
Contents:
|
||||
---------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:name: mastertoc
|
||||
:caption: Contents
|
||||
|
||||
features
|
||||
benchmarks
|
||||
exceptions
|
||||
rtti
|
||||
api/top
|
||||
licenses
|
||||
|
||||
"I need feature X, maybe you have it?"
|
||||
--------------------------------------
|
||||
Take a look at the :doc:`Features<features>` page: it links to much of the API. Don't see a feature you want? Send inquiries for support for a particular abstraction to the `issues`_ tracker.
|
||||
|
||||
|
||||
The Basics:
|
||||
-----------
|
||||
|
||||
.. note::
|
||||
More examples can be found in the `examples directory`_
|
||||
|
||||
.. code-block:: c++
|
||||
:caption: functions
|
||||
:linenos:
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <cassert>
|
||||
|
||||
int main() {
|
||||
sol::state lua;
|
||||
int x = 0;
|
||||
lua.set_function("beep", [&x]{ ++x; });
|
||||
lua.script("beep()");
|
||||
assert(x == 1);
|
||||
|
||||
sol::function beep = lua["beep"];
|
||||
beep();
|
||||
assert(x == 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. code-block:: c++
|
||||
:caption: linking C++ structures to Lua
|
||||
:linenos:
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <cassert>
|
||||
|
||||
struct vars {
|
||||
int boop = 0;
|
||||
|
||||
int bop () const {
|
||||
return boop + 1;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
sol::state lua;
|
||||
lua.new_usertype<vars>("vars",
|
||||
"boop", &vars::boop
|
||||
"bop", &vars::bop);
|
||||
lua.script("beep = vars.new()\n"
|
||||
"beep.boop = 1\n"
|
||||
"bopvalue = beep.bop()");
|
||||
|
||||
vars& beep = lua["beep"];
|
||||
int bopvalue = lua["bopvalue"];
|
||||
|
||||
assert(beep.boop == 1);
|
||||
assert(lua.get<vars>("beep").boop == 1);
|
||||
assert(beep.bop() == 2);
|
||||
assert(bopvalue == 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
.. _issues: http://github.com/ThePhD/sol2/issues
|
||||
.. _examples directory: https://github.com/ThePhD/sol2/tree/develop/examples
|
47
docs/source/licenses.rst
Normal file
47
docs/source/licenses.rst
Normal file
@ -0,0 +1,47 @@
|
||||
licenses
|
||||
========
|
||||
|
||||
The following licenses cover all of the code in Sol. Spoiler: they're all `MIT`_ and it's safe to use in commercial code: feel free to copy/paste the below right into your own attributions / licenses file.
|
||||
|
||||
Sol - ThePhD/sol2:
|
||||
------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2016 Rapptz, ThePhD, and contributors
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Lua-compat-5.3 - keplerproject/Lua-compat-5.3:
|
||||
----------------------------------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Kepler Project.
|
||||
|
||||
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.
|
||||
|
||||
Lua - Lua.org:
|
||||
--------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 1994–2015 Lua.org, PUC-Rio.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
.. _MIT: http://opensource.org/licenses/MIT
|
10
docs/source/rtti.rst
Normal file
10
docs/source/rtti.rst
Normal file
@ -0,0 +1,10 @@
|
||||
run-time type information (rtti)
|
||||
================================
|
||||
because somebody's going to want to shut this off, too...
|
||||
---------------------------------------------------------
|
||||
|
||||
Not compiling with C++'s run-time type information? Do a ``#define SOL_NO_RTII`` before you include ``sol.hpp`` or define ``SOL_NO_RTTI`` on your command line. Be sure to understand the :doc:`implications<api/usertype>` of doing so if you also turn off exceptions.
|
||||
|
||||
If you come across bugs or can't compile because there's a stray `typeid` or `typeinfo` that wasn't hidden behind a ``#ifndef SOL_NO_RTTI``, please file `an issue`_ or even make a pull request so it can be fixed for everyone.
|
||||
|
||||
.. _an issue: https://github.com/ThePhD/sol2/issues
|
@ -25,6 +25,7 @@
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#include <cxxabi.h>
|
||||
@ -64,6 +65,12 @@ inline std::string get_type_name() {
|
||||
if (start < name.size() - 1)
|
||||
start += 1;
|
||||
name = name.substr(start, end - start);
|
||||
if (name.find("struct", 0) == 0)
|
||||
name.replace(0, 6, "", 0);
|
||||
if (name.find("class", 0) == 0)
|
||||
name.replace(0, 5, "", 0);
|
||||
while (name.size() > 0 && std::isblank(name.front())) name.erase(name.begin(), ++name.begin());
|
||||
while (name.size() > 0 && std::isblank(name.back())) name.erase(--name.end(), name.end());
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -40,18 +40,6 @@ struct implicit_wrapper {
|
||||
}
|
||||
};
|
||||
|
||||
inline bool check_types(types<>, std::index_sequence<>, lua_State*, int) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Arg, typename... Args, std::size_t I, std::size_t... In>
|
||||
inline bool check_types(types<Arg, Args...>, std::index_sequence<I, In...>, lua_State* L, int start = 1) {
|
||||
if (!stack::check<Arg>(L, start + I, no_panic))
|
||||
return false;
|
||||
|
||||
return check_types(types<Args...>(), std::index_sequence<In...>(), L, start);
|
||||
}
|
||||
|
||||
template<typename T, typename Func, typename = void>
|
||||
struct functor {
|
||||
typedef meta::callable_traits<Func> traits_type;
|
||||
|
@ -57,7 +57,7 @@ inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>
|
||||
if (traits::arity != fxarity) {
|
||||
return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<traits::arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
if (!function_detail::check_types(args_type(), args_indices(), L, start)) {
|
||||
if (!stack::stack_detail::check_types<true>().check(args_type(), args_indices(), L, start, no_panic)) {
|
||||
return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
return matchfx(types<Fx>(), Index<I>(), return_types(), args_type(), L, fxarity, start, std::forward<Args>(args)...);
|
||||
|
@ -430,13 +430,13 @@ struct checker<T*, type::userdata, C> {
|
||||
if (indextype == type::nil) {
|
||||
return true;
|
||||
}
|
||||
return checker<T, type::userdata, C>{}.check(L, indextype, index, handler);
|
||||
return checker<T, type::userdata, C>{}.check<T*>(L, indextype, index, handler);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename C>
|
||||
struct checker<T, type::userdata, C> {
|
||||
template <typename Handler>
|
||||
template <typename U = T, typename Handler>
|
||||
static bool check (lua_State* L, type indextype, int index, const Handler& handler) {
|
||||
if (indextype != type::userdata) {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
@ -448,46 +448,46 @@ struct checker<T, type::userdata, C> {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
return false;
|
||||
}
|
||||
luaL_getmetatable(L, &usertype_traits<T>::metatable[0]);
|
||||
luaL_getmetatable(L, &usertype_traits<U>::metatable[0]);
|
||||
const type expectedmetatabletype = get<type>(L);
|
||||
if (expectedmetatabletype == type::nil) {
|
||||
if (expectedmetatabletype != type::nil) {
|
||||
if (lua_rawequal(L, -1, -2) == 1) {
|
||||
lua_pop(L, 2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
lua_getfield(L, -1, &detail::base_class_check_key[0]);
|
||||
void* basecastdata = stack::get<light_userdata_value>(L);
|
||||
detail::throw_cast basecast = (detail::throw_cast)basecastdata;
|
||||
bool success = detail::catch_check<T>(basecast);
|
||||
#elif !defined(SOL_NO_RTTI)
|
||||
lua_getfield(L, -1, &detail::base_class_check_key[0]);
|
||||
if (stack::get<type>(L) == type::nil) {
|
||||
lua_pop(L, 2);
|
||||
return false;
|
||||
}
|
||||
void* basecastdata = stack::get<light_userdata_value>(L);
|
||||
detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata;
|
||||
bool success = ic(typeid(T));
|
||||
#else
|
||||
// Topkek
|
||||
lua_getfield(L, -1, &detail::base_class_check_key[0]);
|
||||
if (stack::get<type>(L) == type::nil) {
|
||||
lua_pop(L, 2);
|
||||
return false;
|
||||
}
|
||||
void* basecastdata = stack::get<light_userdata_value>(L);
|
||||
detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata;
|
||||
bool success = ic(detail::id_for<T>::value);
|
||||
#endif // No Runtime Type Information || Exceptions
|
||||
lua_pop(L, 2);
|
||||
if (!success) {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
return false;
|
||||
}
|
||||
bool success = lua_rawequal(L, -1, -2) == 1;
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
if (!success) {
|
||||
lua_getfield(L, -2, &detail::base_class_check_key[0]);
|
||||
void* basecastdata = stack::get<light_userdata_value>(L);
|
||||
detail::throw_cast basecast = (detail::throw_cast)basecastdata;
|
||||
success |= detail::catch_check<T>(basecast);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
#elif !defined(SOL_NO_RTTI)
|
||||
if (!success) {
|
||||
lua_getfield(L, -2, &detail::base_class_check_key[0]);
|
||||
if (stack::get<type>(L) != type::nil) {
|
||||
void* basecastdata = stack::get<light_userdata_value>(L);
|
||||
detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata;
|
||||
success |= ic(typeid(T));
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
#else
|
||||
// Topkek
|
||||
if (!success) {
|
||||
lua_getfield(L, -2, &detail::base_class_check_key[0]);
|
||||
if (stack::get<type>(L) != type::nil) {
|
||||
void* basecastdata = stack::get<light_userdata_value>(L);
|
||||
detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata;
|
||||
success |= ic(detail::id_for<T>::value);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
#endif // No Runtime Type Information || Exceptions
|
||||
lua_pop(L, 2);
|
||||
return success;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
@ -819,36 +819,37 @@ inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 1) {
|
||||
}
|
||||
|
||||
template <bool b>
|
||||
struct check_arguments {
|
||||
template <std::size_t I0, std::size_t... I, typename Arg0, typename... Args>
|
||||
static bool check(types<Arg0, Args...>, std::index_sequence<I0, I...>, lua_State* L, int firstargument) {
|
||||
if (!stack::check<Arg0>(L, firstargument + I0))
|
||||
struct check_types {
|
||||
template <std::size_t I0, std::size_t... I, typename Arg0, typename... Args, typename Handler>
|
||||
static bool check(types<Arg0, Args...>, std::index_sequence<I0, I...>, lua_State* L, int firstargument, Handler&& handler) {
|
||||
if (!stack::check<Arg0>(L, firstargument + I0, handler))
|
||||
return false;
|
||||
return check(types<Args...>(), std::index_sequence<I...>(), L, firstargument);
|
||||
return check(types<Args...>(), std::index_sequence<I...>(), L, firstargument, std::forward<Handler>(handler));
|
||||
}
|
||||
|
||||
static bool check(types<>, std::index_sequence<>, lua_State*, int) {
|
||||
template <typename Handler>
|
||||
static bool check(types<>, std::index_sequence<>, lua_State*, int, Handler&&) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct check_arguments<false> {
|
||||
template <std::size_t... I, typename... Args>
|
||||
static bool check(types<Args...>, std::index_sequence<I...>, lua_State*, int) {
|
||||
struct check_types<false> {
|
||||
template <std::size_t... I, typename... Args, typename Handler>
|
||||
static bool check(types<Args...>, std::index_sequence<I...>, lua_State*, int, Handler&&) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <bool checkargs = default_check_arguments, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
|
||||
inline R call(types<R>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
|
||||
check_arguments<checkargs>{}.check(ta, tai, L, start);
|
||||
check_types<checkargs>{}.check(ta, tai, L, start, type_panic);
|
||||
return fx(std::forward<FxArgs>(args)..., stack::get<Args>(L, start + I)...);
|
||||
}
|
||||
|
||||
template <bool checkargs = default_check_arguments, std::size_t... I, typename... Args, typename Fx, typename... FxArgs>
|
||||
inline void call(types<void>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
|
||||
check_arguments<checkargs>{}.check(ta, tai, L, start);
|
||||
check_types<checkargs>{}.check(ta, tai, L, start, type_panic);
|
||||
fx(std::forward<FxArgs>(args)..., stack::get<Args>(L, start + I)...);
|
||||
}
|
||||
} // stack_detail
|
||||
|
@ -119,7 +119,6 @@ inline void push_metatable(lua_State* L, bool needsindexfunction, Funcs&& funcs,
|
||||
static const auto& gcname = meta_function_names[static_cast<int>(meta_function::garbage_collect)];
|
||||
luaL_newmetatable(L, &usertype_traits<T>::metatable[0]);
|
||||
int metatableindex = lua_gettop(L);
|
||||
#if !defined(SOL_NO_EXCEPTIONS) || !defined(SOL_NO_RTTI)
|
||||
if (baseclasscheck != nullptr) {
|
||||
stack::push(L, light_userdata_value(baseclasscheck));
|
||||
lua_setfield(L, metatableindex, &detail::base_class_check_key[0]);
|
||||
@ -128,7 +127,6 @@ inline void push_metatable(lua_State* L, bool needsindexfunction, Funcs&& funcs,
|
||||
stack::push(L, light_userdata_value(baseclasscast));
|
||||
lua_setfield(L, metatableindex, &detail::base_class_cast_key[0]);
|
||||
}
|
||||
#endif // No Exceptions || RTTI
|
||||
if (funcs.size() < 1 && metafunctable.size() < 2) {
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user