diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-04 10:45:48 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-04 10:45:48 +0200 |
commit | fc2fde434b73e9189dfa6b0c160e5fe72a7aee15 (patch) | |
tree | 76d02f3a1c4abe0fe1c00489945430cf97325344 /src | |
parent | 901ed6e98987a9e02bca8330973f19a34e55bd50 (diff) | |
download | lanes-fc2fde434b73e9189dfa6b0c160e5fe72a7aee15.tar.gz lanes-fc2fde434b73e9189dfa6b0c160e5fe72a7aee15.tar.bz2 lanes-fc2fde434b73e9189dfa6b0c160e5fe72a7aee15.zip |
Keeper code internal improvements
Diffstat (limited to 'src')
-rw-r--r-- | src/keeper.cpp | 75 |
1 files changed, 42 insertions, 33 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index 7a8a855..915d6b6 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
@@ -63,6 +63,9 @@ | |||
63 | // the full userdata associated to a given Linda key to store its contents | 63 | // the full userdata associated to a given Linda key to store its contents |
64 | class KeyUD | 64 | class KeyUD |
65 | { | 65 | { |
66 | private: | ||
67 | static constexpr int kContentsTableIndex{ 1 }; | ||
68 | |||
66 | public: | 69 | public: |
67 | int first{ 1 }; | 70 | int first{ 1 }; |
68 | int count{ 0 }; | 71 | int count{ 0 }; |
@@ -80,10 +83,9 @@ class KeyUD | |||
80 | void peek(KeeperState K_, int count_); | 83 | void peek(KeeperState K_, int count_); |
81 | void pop(KeeperState K_, int count_); | 84 | void pop(KeeperState K_, int count_); |
82 | void push(KeeperState K_, int count_); | 85 | void push(KeeperState K_, int count_); |
86 | [[nodiscard]] bool reset(KeeperState K_); | ||
83 | }; | 87 | }; |
84 | 88 | ||
85 | static constexpr int kContentsTableIndex{ 1 }; | ||
86 | |||
87 | // ################################################################################################# | 89 | // ################################################################################################# |
88 | 90 | ||
89 | // in: nothing | 91 | // in: nothing |
@@ -107,10 +109,10 @@ KeyUD* KeyUD::GetPtr(KeeperState const K_, int idx_) | |||
107 | return lua_tofulluserdata<KeyUD>(K_, idx_); | 109 | return lua_tofulluserdata<KeyUD>(K_, idx_); |
108 | } | 110 | } |
109 | 111 | ||
110 | |||
111 | // ################################################################################################# | 112 | // ################################################################################################# |
112 | 113 | ||
113 | // replaces the fifo ud by its uservalue on the stack | 114 | // replaces the KeyUD by its uservalue on the stack |
115 | // TODO: make it a non-static member to be called after KeyUD::GetPtr() | ||
114 | KeyUD* KeyUD::PrepareAccess(KeeperState const K_, int const idx_) | 116 | KeyUD* KeyUD::PrepareAccess(KeeperState const K_, int const idx_) |
115 | { | 117 | { |
116 | KeyUD* const _key{ KeyUD::GetPtr(K_, idx_) }; | 118 | KeyUD* const _key{ KeyUD::GetPtr(K_, idx_) }; |
@@ -129,10 +131,10 @@ KeyUD* KeyUD::PrepareAccess(KeeperState const K_, int const idx_) | |||
129 | // in: fifo | 131 | // in: fifo |
130 | // out: ...|nothing | 132 | // out: ...|nothing |
131 | // expects exactly 1 value on the stack! | 133 | // expects exactly 1 value on the stack! |
132 | // currently only called with a count of 1, but this may change in the future | ||
133 | // function assumes that there is enough data in the fifo to satisfy the request | 134 | // function assumes that there is enough data in the fifo to satisfy the request |
134 | void KeyUD::peek(KeeperState const K_, int const count_) | 135 | void KeyUD::peek(KeeperState const K_, int const count_) |
135 | { | 136 | { |
137 | //LUA_ASSERT(K_, KeyUD::GetPtr(K_, 1) == this); | ||
136 | STACK_GROW(K_, count_); | 138 | STACK_GROW(K_, count_); |
137 | for (int const _i : std::ranges::iota_view{ 0, count_ }) { | 139 | for (int const _i : std::ranges::iota_view{ 0, count_ }) { |
138 | lua_rawgeti(K_, 1, first + _i); | 140 | lua_rawgeti(K_, 1, first + _i); |
@@ -142,28 +144,28 @@ void KeyUD::peek(KeeperState const K_, int const count_) | |||
142 | // ################################################################################################# | 144 | // ################################################################################################# |
143 | 145 | ||
144 | // in: fifo | 146 | // in: fifo |
145 | // out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number) | 147 | // out: remove the fifo table from the stack, push as many items as required on the stack (function assumes they exist in sufficient number) |
146 | void KeyUD::pop(KeeperState const K_, int const count_) | 148 | void KeyUD::pop(KeeperState const K_, int const count_) |
147 | { | 149 | { |
148 | LUA_ASSERT(K_, lua_istable(K_, -1)); | 150 | LUA_ASSERT(K_, lua_istable(K_, -1)); |
149 | int const _fifo_idx{ lua_gettop(K_) }; // K_: ... fifotbl | 151 | int const _fifo_idx{ lua_gettop(K_) }; // K_: ... fifo |
150 | // each iteration pushes a value on the stack! | 152 | // each iteration pushes a value on the stack! |
151 | STACK_GROW(K_, count_ + 2); | 153 | STACK_GROW(K_, count_ + 2); |
152 | // skip first item, we will push it last | 154 | // skip first item, we will push it last |
153 | for (int const _i : std::ranges::iota_view{ 1, count_ }) { | 155 | for (int const _i : std::ranges::iota_view{ 1, count_ }) { |
154 | int const _at{ first + _i }; | 156 | int const _at{ first + _i }; |
155 | // push item on the stack | 157 | // push item on the stack |
156 | lua_rawgeti(K_, _fifo_idx, _at); // K_: ... fifotbl val | 158 | lua_rawgeti(K_, _fifo_idx, _at); // K_: ... fifo val |
157 | // remove item from the fifo | 159 | // remove item from the fifo |
158 | lua_pushnil(K_); // K_: ... fifotbl val nil | 160 | lua_pushnil(K_); // K_: ... fifo val nil |
159 | lua_rawseti(K_, _fifo_idx, _at); // K_: ... fifotbl val | 161 | lua_rawseti(K_, _fifo_idx, _at); // K_: ... fifo val |
160 | } | 162 | } |
161 | // now process first item | 163 | // now process first item |
162 | { | 164 | { |
163 | int const _at{ first }; | 165 | int const _at{ first }; |
164 | lua_rawgeti(K_, _fifo_idx, _at); // K_: ... fifotbl vals val | 166 | lua_rawgeti(K_, _fifo_idx, _at); // K_: ... fifo vals val |
165 | lua_pushnil(K_); // K_: ... fifotbl vals val nil | 167 | lua_pushnil(K_); // K_: ... fifo vals val nil |
166 | lua_rawseti(K_, _fifo_idx, _at); // K_: ... fifotbl vals val | 168 | lua_rawseti(K_, _fifo_idx, _at); // K_: ... fifo vals val |
167 | lua_replace(K_, _fifo_idx); // K_: ... vals | 169 | lua_replace(K_, _fifo_idx); // K_: ... vals |
168 | } | 170 | } |
169 | 171 | ||
@@ -192,6 +194,23 @@ void KeyUD::push(KeeperState const K_, int const count_) | |||
192 | } | 194 | } |
193 | 195 | ||
194 | // ################################################################################################# | 196 | // ################################################################################################# |
197 | |||
198 | // expects 'this' on top of the stack | ||
199 | bool KeyUD::reset(KeeperState const K_) | ||
200 | { | ||
201 | LUA_ASSERT(K_, KeyUD::GetPtr(K_, -1) == this); | ||
202 | STACK_CHECK_START_REL(K_, 0); | ||
203 | bool const _wasFull{ (limit > 0) && (count >= limit) }; | ||
204 | // empty the KeyUD: replace uservalue with a virgin table, reset counters, but leave limit unchanged! | ||
205 | lua_newtable(K_); // K_: KeysDB key val... KeyUD {} | ||
206 | lua_setiuservalue(K_, -2, kContentsTableIndex); // K_: KeysDB key val... KeyUD | ||
207 | first = 1; | ||
208 | count = 0; | ||
209 | STACK_CHECK(K_, 0); | ||
210 | return _wasFull; | ||
211 | } | ||
212 | |||
213 | // ################################################################################################# | ||
195 | // ################################################################################################# | 214 | // ################################################################################################# |
196 | 215 | ||
197 | // in: linda_ud expected at stack slot idx | 216 | // in: linda_ud expected at stack slot idx |
@@ -247,22 +266,22 @@ int keeper_push_linda_storage(Linda& linda_, DestState L_) | |||
247 | InterCopyContext _c{ linda_.U, L_, SourceState{ _K }, {}, {}, {}, LookupMode::FromKeeper, {} }; | 266 | InterCopyContext _c{ linda_.U, L_, SourceState{ _K }, {}, {}, {}, LookupMode::FromKeeper, {} }; |
248 | lua_pushnil(_K); // _K: KeysDB nil L_: out | 267 | lua_pushnil(_K); // _K: KeysDB nil L_: out |
249 | while (lua_next(_K, -2)) { // _K: KeysDB key KeyUD L_: out | 268 | while (lua_next(_K, -2)) { // _K: KeysDB key KeyUD L_: out |
250 | KeyUD* const _keyUD{ KeyUD::PrepareAccess(_K, -1) }; // _K: KeysDB key fifo L_: out | 269 | KeyUD* const _key{ KeyUD::PrepareAccess(_K, -1) }; // _K: KeysDB key fifo L_: out |
251 | lua_pushvalue(_K, -2); // _K: KeysDB key fifo key L_: out | 270 | lua_pushvalue(_K, -2); // _K: KeysDB key fifo key L_: out |
252 | std::ignore = _c.inter_move(1); // _K: KeysDB key fifo L_: out key | 271 | std::ignore = _c.inter_move(1); // _K: KeysDB key fifo L_: out key |
253 | STACK_CHECK(L_, 2); | 272 | STACK_CHECK(L_, 2); |
254 | lua_newtable(L_); // _K: KeysDB key fifo L_: out key keyout | 273 | lua_newtable(L_); // _K: KeysDB key fifo L_: out key keyout |
255 | std::ignore = _c.inter_move(1); // _K: KeysDB key L_: out key keyout fifo | 274 | std::ignore = _c.inter_move(1); // _K: KeysDB key L_: out key keyout fifo |
256 | // keyout.first | 275 | // keyout.first |
257 | lua_pushinteger(L_, _keyUD->first); // _K: KeysDB key L_: out key keyout fifo first | 276 | lua_pushinteger(L_, _key->first); // _K: KeysDB key L_: out key keyout fifo first |
258 | STACK_CHECK(L_, 5); | 277 | STACK_CHECK(L_, 5); |
259 | lua_setfield(L_, -3, "first"); // _K: KeysDB key L_: out key keyout fifo | 278 | lua_setfield(L_, -3, "first"); // _K: KeysDB key L_: out key keyout fifo |
260 | // keyout.count | 279 | // keyout.count |
261 | lua_pushinteger(L_, _keyUD->count); // _K: KeysDB key L_: out key keyout fifo count | 280 | lua_pushinteger(L_, _key->count); // _K: KeysDB key L_: out key keyout fifo count |
262 | STACK_CHECK(L_, 5); | 281 | STACK_CHECK(L_, 5); |
263 | lua_setfield(L_, -3, "count"); // _K: KeysDB key L_: out key keyout fifo | 282 | lua_setfield(L_, -3, "count"); // _K: KeysDB key L_: out key keyout fifo |
264 | // keyout.limit | 283 | // keyout.limit |
265 | lua_pushinteger(L_, _keyUD->limit); // _K: KeysDB key L_: out key keyout fifo limit | 284 | lua_pushinteger(L_, _key->limit); // _K: KeysDB key L_: out key keyout fifo limit |
266 | STACK_CHECK(L_, 5); | 285 | STACK_CHECK(L_, 5); |
267 | lua_setfield(L_, -3, "limit"); // _K: KeysDB key L_: out key keyout fifo | 286 | lua_setfield(L_, -3, "limit"); // _K: KeysDB key L_: out key keyout fifo |
268 | // keyout.fifo | 287 | // keyout.fifo |
@@ -461,13 +480,9 @@ int keepercall_set(lua_State* const L_) | |||
461 | lua_pushnil(_K); // _K: KeysDB key nil | 480 | lua_pushnil(_K); // _K: KeysDB key nil |
462 | lua_rawset(_K, -3); // _K: KeysDB | 481 | lua_rawset(_K, -3); // _K: KeysDB |
463 | } else { | 482 | } else { |
464 | // we create room if the KeyUD was full but it is no longer the case | ||
465 | _should_wake_writers = (_key->limit > 0) && (_key->count >= _key->limit); | ||
466 | lua_remove(_K, -2); // _K: KeysDB KeyUD | 483 | lua_remove(_K, -2); // _K: KeysDB KeyUD |
467 | lua_newtable(_K); // _K: KeysDB KeyUD {} | 484 | // we create room if the KeyUD was full but it is no longer the case |
468 | lua_setiuservalue(_K, -2, kContentsTableIndex); // _K: KeysDB KeyUD | 485 | _should_wake_writers = _key->reset(_K); |
469 | _key->first = 1; | ||
470 | _key->count = 0; | ||
471 | } | 486 | } |
472 | } | 487 | } |
473 | } else { // set/replace contents stored at the specified key? | 488 | } else { // set/replace contents stored at the specified key? |
@@ -478,22 +493,16 @@ int keepercall_set(lua_State* const L_) | |||
478 | if (_key == nullptr) { // can be nullptr if we store a value at a new key // KeysDB key val... nil | 493 | if (_key == nullptr) { // can be nullptr if we store a value at a new key // KeysDB key val... nil |
479 | // no need to wake writers in that case, because a writer can't wait on an inexistent key | 494 | // no need to wake writers in that case, because a writer can't wait on an inexistent key |
480 | lua_pop(_K, 1); // _K: KeysDB key val... | 495 | lua_pop(_K, 1); // _K: KeysDB key val... |
481 | std::ignore = KeyUD::Create(KeeperState{ _K }); // _K: KeysDB key val... KeyUD | 496 | _key = KeyUD::Create(KeeperState{ _K }); // _K: KeysDB key val... KeyUD |
482 | lua_pushvalue(_K, 2); // _K: KeysDB key val... KeyUD key | 497 | lua_pushvalue(_K, 2); // _K: KeysDB key val... KeyUD key |
483 | lua_pushvalue(_K, -2); // _K: KeysDB key val... KeyUD key KeyUD | 498 | lua_pushvalue(_K, -2); // _K: KeysDB key val... KeyUD key KeyUD |
484 | lua_rawset(_K, 1); // _K: KeysDB key val... KeyUD | 499 | lua_rawset(_K, 1); // _K: KeysDB key val... KeyUD |
485 | } else { // _K: KeysDB key val... KeyUD | 500 | } else { // _K: KeysDB key val... KeyUD |
486 | // the KeyUD exists, we just want to update its contents | 501 | // the KeyUD exists, we just want to update its contents |
487 | // we create room if the KeyUD was full but it is no longer the case | 502 | // we create room if the KeyUD was full but we didn't refill it to the brim with new data |
488 | _should_wake_writers = (_key->limit > 0) && (_key->count >= _key->limit) && (_count < _key->limit); | 503 | _should_wake_writers = _key->reset(_K) && (_count < _key->limit); |
489 | // TODO: turn this into a KeyUD::reset() method | ||
490 | // empty the KeyUD for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! | ||
491 | lua_newtable(_K); // _K: KeysDB key val... KeyUD {} | ||
492 | lua_setiuservalue(_K, -2, kContentsTableIndex); // _K: KeysDB key val... KeyUD | ||
493 | _key->first = 1; | ||
494 | _key->count = 0; | ||
495 | } | 504 | } |
496 | _key = KeyUD::PrepareAccess(_K, -1); // _K: KeysDB key val... fifo | 505 | std::ignore = KeyUD::PrepareAccess(_K, -1); // _K: KeysDB key val... fifo |
497 | // move the fifo below the values we want to store | 506 | // move the fifo below the values we want to store |
498 | lua_insert(_K, 3); // _K: KeysDB key fifo val... | 507 | lua_insert(_K, 3); // _K: KeysDB key fifo val... |
499 | _key->push(_K, _count); // _K: KeysDB key fifo | 508 | _key->push(_K, _count); // _K: KeysDB key fifo |