aboutsummaryrefslogtreecommitdiff
path: root/src/linda.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/linda.cpp176
1 files changed, 89 insertions, 87 deletions
diff --git a/src/linda.cpp b/src/linda.cpp
index ad40eef..a7cf011 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -39,6 +39,72 @@ THE SOFTWARE.
39#include <functional> 39#include <functional>
40 40
41// ################################################################################################# 41// #################################################################################################
42
43static void check_key_types(lua_State* L_, int start_, int end_)
44{
45 for (int _i{ start_ }; _i <= end_; ++_i) {
46 LuaType const t{ lua_type_as_enum(L_, _i) };
47 switch (t) {
48 case LuaType::BOOLEAN:
49 case LuaType::NUMBER:
50 case LuaType::STRING:
51 continue;
52
53 case LuaType::LIGHTUSERDATA:
54 static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel };
55 for (UniqueKey const& key : kKeysToCheck) {
56 if (key.equals(L_, _i)) {
57 raise_luaL_error(L_, "argument #%d: can't use %s as a key", _i, key.debugName);
58 break;
59 }
60 }
61 break;
62 }
63 raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", _i);
64 }
65}
66
67// #################################################################################################
68
69/*
70 * string = linda:__tostring( linda_ud)
71 *
72 * Return the stringification of a linda
73 *
74 * Useful for concatenation or debugging purposes
75 */
76
77template <bool OPT>
78[[nodiscard]] static int LindaToString(lua_State* L_, int idx_)
79{
80 Linda* const _linda{ ToLinda<OPT>(L_, idx_) };
81 if (_linda != nullptr) {
82 char _text[128];
83 int _len;
84 if (_linda->getName())
85 _len = sprintf(_text, "Linda: %.*s", (int) sizeof(_text) - 8, _linda->getName());
86 else
87 _len = sprintf(_text, "Linda: %p", _linda);
88 lua_pushlstring(L_, _text, _len);
89 return 1;
90 }
91 return 0;
92}
93
94// #################################################################################################
95
96template <bool OPT>
97[[nodiscard]] static inline Linda* ToLinda(lua_State* L_, int idx_)
98{
99 Linda* const _linda{ static_cast<Linda*>(LindaFactory::Instance.toDeep(L_, idx_)) };
100 if constexpr (!OPT) {
101 luaL_argcheck(L_, _linda != nullptr, idx_, "expecting a linda object"); // doesn't return if linda is nullptr
102 LUA_ASSERT(L_, _linda->U == universe_get(L_));
103 }
104 return _linda;
105}
106
107// #################################################################################################
42// ################################################################################################# 108// #################################################################################################
43 109
44// Any hashing will do that maps pointers to [0..Universe::nb_keepers[ consistently. 110// Any hashing will do that maps pointers to [0..Universe::nb_keepers[ consistently.
@@ -66,27 +132,6 @@ Linda::~Linda()
66 132
67// ################################################################################################# 133// #################################################################################################
68 134
69void Linda::setName(char const* name_, size_t len_)
70{
71 // keep default
72 if (!name_ || len_ == 0) {
73 return;
74 }
75 ++len_; // don't forget terminating 0
76 if (len_ < kEmbeddedNameLength) {
77 nameVariant.emplace<EmbeddedName>();
78 char* const _name{ std::get<EmbeddedName>(nameVariant).data() };
79 memcpy(_name, name_, len_);
80 } else {
81 AllocatedName& _name = std::get<AllocatedName>(nameVariant);
82 _name.name = static_cast<char*>(U->internalAllocator.alloc(len_));
83 _name.len = len_;
84 memcpy(_name.name, name_, len_);
85 }
86}
87
88// #################################################################################################
89
90char const* Linda::getName() const 135char const* Linda::getName() const
91{ 136{
92 if (std::holds_alternative<AllocatedName>(nameVariant)) { 137 if (std::holds_alternative<AllocatedName>(nameVariant)) {
@@ -102,45 +147,6 @@ char const* Linda::getName() const
102 147
103// ################################################################################################# 148// #################################################################################################
104 149
105template <bool OPT>
106[[nodiscard]] static inline Linda* ToLinda(lua_State* L_, int idx_)
107{
108 Linda* const _linda{ static_cast<Linda*>(LindaFactory::Instance.toDeep(L_, idx_)) };
109 if constexpr (!OPT) {
110 luaL_argcheck(L_, _linda != nullptr, idx_, "expecting a linda object"); // doesn't return if linda is nullptr
111 LUA_ASSERT(L_, _linda->U == universe_get(L_));
112 }
113 return _linda;
114}
115
116// #################################################################################################
117
118static void check_key_types(lua_State* L_, int start_, int end_)
119{
120 for (int _i{ start_ }; _i <= end_; ++_i) {
121 LuaType const t{ lua_type_as_enum(L_, _i) };
122 switch (t) {
123 case LuaType::BOOLEAN:
124 case LuaType::NUMBER:
125 case LuaType::STRING:
126 continue;
127
128 case LuaType::LIGHTUSERDATA:
129 static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel };
130 for (UniqueKey const& key : kKeysToCheck) {
131 if (key.equals(L_, _i)) {
132 raise_luaL_error(L_, "argument #%d: can't use %s as a key", _i, key.debugName);
133 break;
134 }
135 }
136 break;
137 }
138 raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", _i);
139 }
140}
141
142// #################################################################################################
143
144// used to perform all linda operations that access keepers 150// used to perform all linda operations that access keepers
145int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_) 151int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_)
146{ 152{
@@ -175,6 +181,29 @@ int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_)
175 181
176// ################################################################################################# 182// #################################################################################################
177 183
184void Linda::setName(char const* name_, size_t len_)
185{
186 // keep default
187 if (!name_ || len_ == 0) {
188 return;
189 }
190 ++len_; // don't forget terminating 0
191 if (len_ < kEmbeddedNameLength) {
192 nameVariant.emplace<EmbeddedName>();
193 char* const _name{ std::get<EmbeddedName>(nameVariant).data() };
194 memcpy(_name, name_, len_);
195 } else {
196 AllocatedName& _name = std::get<AllocatedName>(nameVariant);
197 _name.name = static_cast<char*>(U->internalAllocator.alloc(len_));
198 _name.len = len_;
199 memcpy(_name.name, name_, len_);
200 }
201}
202
203// #################################################################################################
204// ########################################## Lua API ##############################################
205// #################################################################################################
206
178/* 207/*
179 * bool= linda:linda_send([timeout_secs=nil,] key_num|str|bool|lightuserdata, ...) 208 * bool= linda:linda_send([timeout_secs=nil,] key_num|str|bool|lightuserdata, ...)
180 * 209 *
@@ -649,33 +678,6 @@ LUAG_FUNC(linda_deep)
649 678
650// ################################################################################################# 679// #################################################################################################
651 680
652/*
653 * string = linda:__tostring( linda_ud)
654 *
655 * Return the stringification of a linda
656 *
657 * Useful for concatenation or debugging purposes
658 */
659
660template <bool OPT>
661[[nodiscard]] static int LindaToString(lua_State* L_, int idx_)
662{
663 Linda* const _linda{ ToLinda<OPT>(L_, idx_) };
664 if (_linda != nullptr) {
665 char _text[128];
666 int _len;
667 if (_linda->getName())
668 _len = sprintf(_text, "Linda: %.*s", (int) sizeof(_text) - 8, _linda->getName());
669 else
670 _len = sprintf(_text, "Linda: %p", _linda);
671 lua_pushlstring(L_, _text, _len);
672 return 1;
673 }
674 return 0;
675}
676
677// #################################################################################################
678
679LUAG_FUNC(linda_tostring) 681LUAG_FUNC(linda_tostring)
680{ 682{
681 return LindaToString<false>(L_, 1); 683 return LindaToString<false>(L_, 1);