From 7168c3177bc9754fca1685bb3bd1b430027a0003 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Wed, 31 May 2017 18:58:24 -0400 Subject: [PATCH] Add some additional documentation to aid in understanding --- docs/source/api/usertype_memory.rst | 7 ++++++- docs/source/usertypes.rst | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/source/api/usertype_memory.rst b/docs/source/api/usertype_memory.rst index c714638b..4043cb27 100644 --- a/docs/source/api/usertype_memory.rst +++ b/docs/source/api/usertype_memory.rst @@ -7,7 +7,12 @@ usertype memory The userdata generated by Sol has a specific layout, depending on how Sol recognizes userdata passed into it. All of the referred to metatable names are generated from the name of the class itself. Note that we use 1 metatable per the 3 styles listed below, plus 1 additional metatable that is used for the actual table that you bind with the name when calling ``table::new/set_(simple_)usertype``. -In general, we always insert a T* in the first `sizeof(T*)` bytes, so the any framework that pulls out those first bytes expecting a pointer will work. The rest of the data has some different alignments and contents based on what it's used for and how it's used. +In general, we always insert a ``T*`` in the first ``sizeof(T*)`` bytes, so the any framework that pulls out those first bytes expecting a pointer will work. The rest of the data has some different alignments and contents based on what it's used for and how it's used. + +To retrieve a ``T`` +------------------- + +If you want to retrieve a ``T*`` pointer to the data managed by a sol2 userdata and are not using sol2's abstractions to do it (e.g., messing with the plain Lua C API), simply use ``lua_touserdata`` to get the ``void*`` pointer. Then, execute a ``T* object_pointer = *static_cast(the_void_pointer);``. Every type pushed into C++ that is classified as a userdata (e.g., all user-defined objects that are not covered by the stack abstraction's basic types) can be retrieved in this format, whether they are values or pointers or ``unique_ptr``. The reasons for why this works is below. For ``T`` --------- diff --git a/docs/source/usertypes.rst b/docs/source/usertypes.rst index c3deafda..19142b39 100644 --- a/docs/source/usertypes.rst +++ b/docs/source/usertypes.rst @@ -28,9 +28,13 @@ The examples folder also has a number of really great examples for you to see. T - This means retrieval of class types (not primitive types like strings or integers) by ``T&`` or ``T*`` allow you to modify the data in Lua directly. - Retrieve a plain ``T`` to get a copy - Return types and passing arguments to ``sol::function``-types use perfect forwarding and reference semantics, which means no copies happen unless you specify a value explicitly. See :ref:`this note for details`. +* You can set ``index`` and ``new_index`` freely on any usertype you like to override the default "if a key is missing, find it / set it here" functionality of a specific object of a usertype. + - new_index and index will not be called if you try to manipulate the named usertype table directly. sol2's will be called to add that function to the usertype's function/variable lookup table. + - new_index and index will be called if you attempt to call a key that does not exist on an actual userdata object (the C++ object) itself. + - If you made a usertype named ``test``, this means ``t = test()``, with ``t.hi = 54`` will call your function, but ``test.hi = function () print ("hi");`` will instead the key ``hi`` to to that function for all ``test`` types * The first ``sizeof( void* )`` bytes is always a pointer to the typed C++ memory. What comes after is based on what you've pushed into the system according to :doc:`the memory specification for usertypes`. This is compatible with a number of systems other than just sol2, making it easy to interop with select other Lua systems. * Member methods, properties, variables and functions taking ``self&`` arguments modify data directly - - Work on a copy by taking or returning a copy by value. + - Work on a copy by taking arguments or returning by value. Do not use r-value references: they do not mean anything in Lua code. * The actual metatable associated with the usertype has a long name and is defined to be opaque by the Sol implementation. * The actual metatable inner workings is opaque and defined by the Sol implementation, and there are no internal docs because optimizations on the operations are applied based on heuristics we discover from performance testing the system. * Containers get pushed as special usertypes, but can be disabled if problems arise as detailed :doc:`here`.