diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-15 14:39:05 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-15 14:39:05 +0200 |
commit | f4b0527c7d11b3a95d44b880cbdd4aae2d58ca8d (patch) | |
tree | 431f4753f41f61a4adbbaed22553a01aa6625583 /src/deep.h | |
parent | e55e2a5ab1b1c411efd4d0d2f64626671a9079b4 (diff) | |
download | lanes-f4b0527c7d11b3a95d44b880cbdd4aae2d58ca8d.tar.gz lanes-f4b0527c7d11b3a95d44b880cbdd4aae2d58ca8d.tar.bz2 lanes-f4b0527c7d11b3a95d44b880cbdd4aae2d58ca8d.zip |
C++ migration: deep userdata API rework. bye bye idfunc, hello DeepFactory
Diffstat (limited to 'src/deep.h')
-rw-r--r-- | src/deep.h | 62 |
1 files changed, 44 insertions, 18 deletions
@@ -28,34 +28,60 @@ enum class LookupMode | |||
28 | FromKeeper // send a function from a keeper state to a lane | 28 | FromKeeper // send a function from a keeper state to a lane |
29 | }; | 29 | }; |
30 | 30 | ||
31 | enum class DeepOp | ||
32 | { | ||
33 | New, | ||
34 | Delete, | ||
35 | Metatable, | ||
36 | Module, | ||
37 | }; | ||
38 | |||
39 | using luaG_IdFunction = void*(*)(lua_State* L, DeepOp op_); | ||
40 | |||
41 | // ################################################################################################ | 31 | // ################################################################################################ |
42 | 32 | ||
43 | // xxh64 of string "DEEP_VERSION_3" generated at https://www.pelock.com/products/hash-calculator | 33 | // xxh64 of string "DEEP_VERSION_3" generated at https://www.pelock.com/products/hash-calculator |
44 | static constexpr UniqueKey DEEP_VERSION{ 0xB2CC0FD9C0AE9674ull }; | 34 | static constexpr UniqueKey DEEP_VERSION{ 0xB2CC0FD9C0AE9674ull, "DEEP_VERSION_3" }; |
45 | 35 | ||
46 | // should be used as header for deep userdata | 36 | // should be used as header for deep userdata |
47 | // a deep userdata is a full userdata that stores a single pointer to the actual DeepPrelude-derived object | 37 | // a deep userdata is a full userdata that stores a single pointer to the actual DeepPrelude-derived object |
48 | struct DeepPrelude | 38 | struct DeepPrelude |
49 | { | 39 | { |
50 | UniqueKey const magic{ DEEP_VERSION }; | 40 | UniqueKey const m_magic{ DEEP_VERSION }; |
51 | // when stored in a keeper state, the full userdata doesn't have a metatable, so we need direct access to the idfunc | 41 | // when stored in a keeper state, the full userdata doesn't have a metatable, so we need direct access to the factory |
52 | luaG_IdFunction idfunc { nullptr }; | 42 | class DeepFactory& m_factory; |
53 | // data is destroyed when refcount is 0 | 43 | // data is destroyed when refcount is 0 |
54 | std::atomic<int> m_refcount{ 0 }; | 44 | std::atomic<int> m_refcount{ 0 }; |
45 | |||
46 | DeepPrelude(DeepFactory& factory_) | ||
47 | : m_factory{ factory_ } | ||
48 | { | ||
49 | } | ||
55 | }; | 50 | }; |
56 | 51 | ||
57 | [[nodiscard]] char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode mode_); | 52 | // external C modules should create a single object implementing that interface for each Deep userdata class they want to expose |
58 | void free_deep_prelude(lua_State* L, DeepPrelude* prelude_); | 53 | class DeepFactory |
54 | { | ||
55 | protected: | ||
56 | |||
57 | // protected non-virtual destructor: Lanes won't manage the Factory's lifetime | ||
58 | DeepFactory() = default; | ||
59 | ~DeepFactory() = default; | ||
60 | |||
61 | public: | ||
62 | |||
63 | // non-copyable, non-movable | ||
64 | DeepFactory(DeepFactory const&) = delete; | ||
65 | DeepFactory(DeepFactory const&&) = delete; | ||
66 | DeepFactory& operator=(DeepFactory const&) = delete; | ||
67 | DeepFactory& operator=(DeepFactory const&&) = delete; | ||
68 | |||
69 | private: | ||
70 | |||
71 | // NVI: private overrides | ||
72 | virtual DeepPrelude* newDeepObjectInternal(lua_State* L) const = 0; | ||
73 | virtual void deleteDeepObjectInternal(lua_State* L, DeepPrelude* o_) const = 0; | ||
74 | virtual void createMetatable(lua_State* L) const = 0; | ||
75 | virtual char const* moduleName() const = 0; | ||
76 | |||
77 | public: | ||
78 | |||
79 | // NVI: public interface | ||
80 | int pushDeepUserdata(Dest L, int nuv_) const; | ||
81 | DeepPrelude* toDeep(lua_State* L, int index) const; | ||
82 | static void DeleteDeepObject(lua_State* L, DeepPrelude* o_); | ||
83 | static char const* PushDeepProxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode mode_); | ||
84 | }; | ||
59 | 85 | ||
60 | LANES_API [[nodiscard]] int luaG_newdeepuserdata(Dest L, luaG_IdFunction idfunc, int nuv_); | 86 | //LANES_API [[nodiscard]] int luaG_newdeepuserdata(Dest L, DeepFactory& factory_, int nuv_); |
61 | LANES_API [[nodiscard]] DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index); | 87 | //LANES_API [[nodiscard]] DeepPrelude* luaG_todeep(lua_State* L, DeepFactory &factory_, int index); |