diff options
| -rw-r--r-- | src/keeper.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index ca2a80d..7619eb4 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
| @@ -191,23 +191,33 @@ int KeyUD::pop(KeeperState const K_, int const minCount_, int const maxCount_) | |||
| 191 | int const _popCount{ std::min(count, maxCount_) }; | 191 | int const _popCount{ std::min(count, maxCount_) }; |
| 192 | LUA_ASSERT(K_, KeyUD::GetPtr(K_, kIdxTop) == this); // K_: ... this | 192 | LUA_ASSERT(K_, KeyUD::GetPtr(K_, kIdxTop) == this); // K_: ... this |
| 193 | prepareAccess(K_, kIdxTop); // K_: ... fifo | 193 | prepareAccess(K_, kIdxTop); // K_: ... fifo |
| 194 | |||
| 195 | STACK_CHECK_START_REL(K_, 0); | ||
| 194 | StackIndex const _fifo_idx{ lua_gettop(K_) }; | 196 | StackIndex const _fifo_idx{ lua_gettop(K_) }; |
| 195 | // each iteration pushes a value on the stack! | 197 | // each iteration pushes a value on the stack! |
| 196 | STACK_GROW(K_, _popCount + 2); | 198 | STACK_GROW(K_, _popCount + 2); |
| 197 | // skip first item, we will push it last | 199 | |
| 198 | for (int const _i : std::ranges::iota_view{ 1, _popCount }) { | 200 | // remove an element from fifo sequence and push it on the stack |
| 201 | auto _extractFifoItem = [K = K_, first = first, fifo_idx = lua_gettop(K_)](int const _i) | ||
| 202 | { | ||
| 203 | STACK_CHECK_START_REL(K, 0); | ||
| 199 | int const _at{ first + _i }; | 204 | int const _at{ first + _i }; |
| 200 | // push item on the stack | 205 | // push item on the stack |
| 201 | lua_rawgeti(K_, _fifo_idx, _at); // K_: ... fifo val | 206 | lua_rawgeti(K, fifo_idx, _at); // K_: ... fifo val |
| 202 | // remove item from the fifo | 207 | // remove item from the fifo |
| 203 | lua_pushnil(K_); // K_: ... fifo val nil | 208 | lua_pushnil(K); // K_: ... fifo val nil |
| 204 | lua_rawseti(K_, _fifo_idx, _at); // K_: ... fifo val | 209 | lua_rawseti(K, fifo_idx, _at); // K_: ... fifo val |
| 210 | STACK_CHECK(K, 1); | ||
| 211 | }; | ||
| 212 | |||
| 213 | // skip first item, we will push it last to avoid shifting the whole stack when removing 'fifo' | ||
| 214 | for (int const _i : std::ranges::iota_view{ 1, _popCount }) { | ||
| 215 | _extractFifoItem(_i); // K_: ... fifo val1...valN | ||
| 205 | } | 216 | } |
| 206 | // now process first item | 217 | // now process first item |
| 207 | lua_rawgeti(K_, _fifo_idx, first); // K_: ... fifo vals val | 218 | _extractFifoItem(0); // K_: ... fifo val1...valN val0 |
| 208 | lua_pushnil(K_); // K_: ... fifo vals val nil | 219 | STACK_CHECK(K_, _popCount); |
| 209 | lua_rawseti(K_, _fifo_idx, first); // K_: ... fifo vals val | 220 | lua_replace(K_, _fifo_idx); // K_: ... val0...valN |
| 210 | lua_replace(K_, _fifo_idx); // K_: ... vals | ||
| 211 | 221 | ||
| 212 | // avoid ever-growing indexes by resetting each time we detect the fifo is empty | 222 | // avoid ever-growing indexes by resetting each time we detect the fifo is empty |
| 213 | int const _new_count{ count - _popCount }; | 223 | int const _new_count{ count - _popCount }; |
