| 21856 | |
| 21857 | template <typename T> |
| 21858 | inline int register_usertype(lua_State* L, automagic_enrollments enrollments = {}) { |
| 21859 | using u_traits = usertype_traits<T>; |
| 21860 | using u_const_traits = usertype_traits<const T>; |
| 21861 | using u_unique_traits = usertype_traits<detail::unique_usertype<T>>; |
| 21862 | using u_ref_traits = usertype_traits<T*>; |
| 21863 | using u_const_ref_traits = usertype_traits<T const*>; |
| 21864 | using uts = usertype_storage<T>; |
| 21865 | |
| 21866 | // always have __new_index point to usertype_storage method |
| 21867 | // have __index always point to regular fast-lookup |
| 21868 | // meta_method table |
| 21869 | // if __new_index is invoked, runtime-swap |
| 21870 | // to slow __index if necessary |
| 21871 | // (no speed penalty because function calls |
| 21872 | // are all read-only -- only depend on __index |
| 21873 | // to retrieve function and then call happens VIA Lua) |
| 21874 | |
| 21875 | // __type entry: |
| 21876 | // table contains key -> value lookup, |
| 21877 | // where key is entry in metatable |
| 21878 | // and value is type information as a string as |
| 21879 | // best as we can give it |
| 21880 | |
| 21881 | // name entry: |
| 21882 | // string that contains raw class name, |
| 21883 | // as defined from C++ |
| 21884 | |
| 21885 | // is entry: |
| 21886 | // checks if argument supplied is of type T |
| 21887 | |
| 21888 | // __storage entry: |
| 21889 | // a light userdata pointing to the storage |
| 21890 | // mostly to enable this new abstraction |
| 21891 | // to not require the type name `T` |
| 21892 | // to get at the C++ usertype storage within |
| 21893 | |
| 21894 | // we then let typical definitions potentially override these intrinsics |
| 21895 | // it's the user's fault if they override things or screw them up: |
| 21896 | // these names have been reserved and documented since sol3 |
| 21897 | |
| 21898 | // STEP 0: tell the old usertype (if it exists) |
| 21899 | // to fuck off |
| 21900 | delete_usertype_storage<T>(L); |
| 21901 | |
| 21902 | // STEP 1: Create backing store for usertype storage |
| 21903 | // Pretty much the most important step. |
| 21904 | // STEP 2: Create Lua tables used for fast method indexing. |
| 21905 | // This is done inside of the storage table's constructor |
| 21906 | usertype_storage<T>& storage = create_usertype_storage<T>(L); |
| 21907 | usertype_storage_base& base_storage = storage; |
| 21908 | void* light_storage = static_cast<void*>(&storage); |
| 21909 | void* light_base_storage = static_cast<void*>(&base_storage); |
| 21910 | |
| 21911 | // STEP 3: set up GC escape hatch table entirely |
| 21912 | storage.gc_names_table.push(); |
| 21913 | stack_reference gnt(L, -1); |
| 21914 | stack::set_field(L, submetatable_type::named, &u_traits::gc_table()[0], gnt.stack_index()); |
| 21915 | stack::set_field(L, submetatable_type::const_value, &u_const_traits::metatable()[0], gnt.stack_index()); |
nothing calls this directly
no test coverage detected