objects_binding.rst 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. ============================
  2. Objects binding and lifetime
  3. ============================
  4. Crown has a native runtime written in C++. To guarantee good performance and
  5. ease of use, we employ a number of different techniques when binding C-side
  6. objects to the Lua environment, depending on their type and lifetime.
  7. Light userdata binding
  8. ----------------------
  9. Most objects are exposed to Lua via Light userdata. Light userdata objects are
  10. owned by the C side and do not require garbage collection.
  11. One disadvantage is that individual Light userdata objects cannot have a
  12. metatable, so the regular object notation is not available when calling them:
  13. .. code:: lua
  14. world:spawn_unit("units/grass")
  15. Instead you must explicitly look up the function in the World table and pass
  16. `world` as a parameter:
  17. .. code:: lua
  18. World.spawn_unit(world, "units/grass")
  19. Full userdata binding
  20. ---------------------
  21. Full userdata objects are owned by the Lua side, they are heap-allocated and
  22. subject to gargbage collection. They support metatables and thus offer object
  23. notation and operator overloading.
  24. We make sporadic use of full userdata, due to their runtime overhead. One such
  25. example are the "boxed" versions of regular math objects (Vector3Box,
  26. Matrix4x4Box etc).
  27. Singleton objects
  28. -----------------
  29. Objects which only have a single instance of them in the runtime are called
  30. singletons. Singletons are typically created at program start and live until the
  31. runtime exits.
  32. Since they always refer to the same instance, you don't need to specify it when
  33. calling their functions:
  34. .. code:: lua
  35. Device.version()
  36. Temporary objects
  37. -----------------
  38. Sometimes you want an object to be owned by the Lua side, but without the
  39. performance implications of a garbage-collected Full userdata object. Vectors
  40. and matrices are a perfect example of that.
  41. Crown uses a fixed-size memory pool to allocate temporary objects from. The pool
  42. is reset at each frame so temporaries are only valid in the frame they are
  43. created.
  44. To store a temporary Vector3 for use in later frames, you need to copy its value
  45. into something else with a longer lifespan, for example, you could "box" it in a
  46. Vector3Box:
  47. .. code:: lua
  48. local pos = Vector3Box()
  49. function update(dt)
  50. local p = SceneGraph.local_position(...)
  51. pos:store(p)
  52. end
  53. And later retrieve its value with:
  54. .. code:: lua
  55. local p = pos:unbox()
  56. Crown will report an error when it detects a stale temporary object that is used
  57. across-frames.
  58. If you have particularly long computations, you may run out of temporary
  59. objects. This could happen when doing math inside loops for example. You can use
  60. ``Device.temp_count()`` and ``Device.set_temp_count()`` to save and restore the
  61. number of temporary objects used before and after computations:
  62. .. code:: lua
  63. for i, v in pairs(objects) do
  64. local nv, nq, nm = Device.temp_count()
  65. ...
  66. Device.set_temp_count(nv, nq, nm)
  67. end