sol2 icon indicating copy to clipboard operation
sol2 copied to clipboard

Improve Usertype Interop Documentation

Open dhkatz opened this issue 3 years ago • 0 comments

Read these guidelines. They are relatively simple and will allow me to help you better!

For Error Reports:

  1. Produce a simple, short, compilable test case that reproduces your problem.
  2. Make a descriptive title that summarises the bug as a whole.
  3. Explain the bug in as much detail as you can in the body of the issue.
  4. Include Compiler/IDE (Visual Studio, XCode...), Build and Deployment System, Language (C++, Objective-C++), and any special defines you have set.

If you want to request a feature:

  1. Produce any relevant imaginary code that illustrates what you would like or desired behavior.
  2. Include a description and title of what you would like.
  3. Annotate and describe the behavior through comments, asserts or just a small write up.

Thanks for helping sol2 grow!

I've been using RTTR in a project, and I figured I could leverage it when it came time to integrate sol2 as well. RTTR provides a handy visitor pattern that you can use to integrate other libraries that might need type information.

The documentation was a little unclear about how you could go about accessing usertypes later on without a reference to them anymore.

I thought I could just do this:

    template <typename T>
    void visit_property(const property_info<T>& info) {
        auto name = info.property_item.get_name().to_string(); // property's name
        auto table = info.property_item.get_declaring_type().get_name().to_string(); // type name

        // Register the property on the usertype!
        lua[table][name] = info.property_accessor;
    }

However, it seems like accessing the usertype through direct indexing doesn't quite work. Indexing in this way uses table proxies and such to let you do fancy chained indexing, lazy evaluation, etc.

For example if I have some class Vector:


class Vector {
  float x;
  float y;
  float z;
}

and I run this lua code:

        local p = Vector.new()
        print(p.x)
        print(p.y)
        print(p.z)

I end up with this output:

function: 0000022F5217A5D0
function: 0000022F5217A850
function: 0000022F5217AC50

Instead, you have to explicitly retrieve the table as a sol::usertype<T>:

  template <typename T>
  void visit_property(const property_info<T>& info) {
      // We can grab the underlying class type here (in this example it's vector3)
      using Class = typename property_info<T>::declaring_type;

      auto name = info.property_item.get_name().to_string();
      auto table = info.property_item.get_declaring_type().get_name().to_string();

      // Explicitly get a sol::usertype<T> from the global table.
      auto usertype = lua.get<sol::usertype<Class>>(table);

      usertype[name] = info.property_accessor;
  }

Then I get the proper output:

0.0
0.0
0.0

dhkatz avatar Mar 11 '22 02:03 dhkatz