diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-04 15:00:06 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-04 15:00:06 +0200 |
| commit | 4695cbe96514e6b174fb5050bb2e9a41514091f3 (patch) | |
| tree | eda954fa4e7b7c6636dfddc21cea1bfdf2de8a67 /src | |
| parent | 046f07e1a79f0d39b1db5f69f6132dbe70cda2a4 (diff) | |
| download | lanes-4695cbe96514e6b174fb5050bb2e9a41514091f3.tar.gz lanes-4695cbe96514e6b174fb5050bb2e9a41514091f3.tar.bz2 lanes-4695cbe96514e6b174fb5050bb2e9a41514091f3.zip | |
Refactored keeper implementation of linda:limit()
Diffstat (limited to 'src')
| -rw-r--r-- | src/keeper.cpp | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index 1779ab3..a546868 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
| @@ -77,17 +77,31 @@ class KeyUD | |||
| 77 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | 77 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception |
| 78 | static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] KeeperState L_) { LUA_ASSERT(L_, !"should never be called"); } | 78 | static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] KeeperState L_) { LUA_ASSERT(L_, !"should never be called"); } |
| 79 | 79 | ||
| 80 | [[nodiscard]] static KeyUD* GetPtr(KeeperState K_, int idx_); | 80 | [[nodiscard]] bool changeLimit(int limit_); |
| 81 | [[nodiscard]] static KeyUD* Create(KeeperState K_); | 81 | [[nodiscard]] static KeyUD* Create(KeeperState K_); |
| 82 | void prepareAccess(KeeperState K_); | 82 | [[nodiscard]] static KeyUD* GetPtr(KeeperState K_, int idx_); |
| 83 | void peek(KeeperState K_, int count_); | 83 | void peek(KeeperState K_, int count_); |
| 84 | void pop(KeeperState K_, int count_); | 84 | void pop(KeeperState K_, int count_); |
| 85 | void prepareAccess(KeeperState K_); | ||
| 85 | void push(KeeperState K_, int count_); | 86 | void push(KeeperState K_, int count_); |
| 86 | [[nodiscard]] bool reset(KeeperState K_); | 87 | [[nodiscard]] bool reset(KeeperState K_); |
| 87 | }; | 88 | }; |
| 88 | 89 | ||
| 89 | // ################################################################################################# | 90 | // ################################################################################################# |
| 90 | 91 | ||
| 92 | bool KeyUD::changeLimit(int const limit_) | ||
| 93 | { | ||
| 94 | bool const _newSlackAvailable{ | ||
| 95 | ((limit >= 0) && (count >= limit)) // then: the key was full if limited and count exceeded the previous limit | ||
| 96 | && ((limit_ < 0) || (count < limit_)) // now: the key is not full if unlimited or count is lower than the new limit | ||
| 97 | }; | ||
| 98 | // set the new limit | ||
| 99 | limit = limit_; | ||
| 100 | return _newSlackAvailable; | ||
| 101 | } | ||
| 102 | |||
| 103 | // ################################################################################################# | ||
| 104 | |||
| 91 | // in: nothing | 105 | // in: nothing |
| 92 | // out: { first = 1, count = 0, limit = -1} | 106 | // out: { first = 1, count = 0, limit = -1} |
| 93 | KeyUD* KeyUD::Create(KeeperState const K_) | 107 | KeyUD* KeyUD::Create(KeeperState const K_) |
| @@ -111,18 +125,6 @@ KeyUD* KeyUD::GetPtr(KeeperState const K_, int idx_) | |||
| 111 | 125 | ||
| 112 | // ################################################################################################# | 126 | // ################################################################################################# |
| 113 | 127 | ||
| 114 | // expects 'this' on top of the stack | ||
| 115 | // replaces it by its uservalue on the stack | ||
| 116 | void KeyUD::prepareAccess(KeeperState const K_) | ||
| 117 | { | ||
| 118 | LUA_ASSERT(K_, KeyUD::GetPtr(K_, -1) == this); | ||
| 119 | // we can replace the key userdata in the stack without fear of it being GCed, there are other references around | ||
| 120 | lua_getiuservalue(K_, -1, kContentsTableIndex); | ||
| 121 | lua_replace(K_, -2); | ||
| 122 | } | ||
| 123 | |||
| 124 | // ################################################################################################# | ||
| 125 | |||
| 126 | // in: fifo | 128 | // in: fifo |
| 127 | // out: ...|nothing | 129 | // out: ...|nothing |
| 128 | // pops the fifo, push as much data as is available (up to the specified count) without consuming it | 130 | // pops the fifo, push as much data as is available (up to the specified count) without consuming it |
| @@ -182,6 +184,18 @@ void KeyUD::pop(KeeperState const K_, int const count_) | |||
| 182 | 184 | ||
| 183 | // ################################################################################################# | 185 | // ################################################################################################# |
| 184 | 186 | ||
| 187 | // expects 'this' on top of the stack | ||
| 188 | // replaces it by its uservalue on the stack | ||
| 189 | void KeyUD::prepareAccess(KeeperState const K_) | ||
| 190 | { | ||
| 191 | LUA_ASSERT(K_, KeyUD::GetPtr(K_, -1) == this); | ||
| 192 | // we can replace the key userdata in the stack without fear of it being GCed, there are other references around | ||
| 193 | lua_getiuservalue(K_, -1, kContentsTableIndex); | ||
| 194 | lua_replace(K_, -2); | ||
| 195 | } | ||
| 196 | |||
| 197 | // ################################################################################################# | ||
| 198 | |||
| 185 | // in: expect fifo args... on top of the stack | 199 | // in: expect fifo args... on top of the stack |
| 186 | // out: nothing, removes all pushed values from the stack | 200 | // out: nothing, removes all pushed values from the stack |
| 187 | void KeyUD::push(KeeperState const K_, int const count_) | 201 | void KeyUD::push(KeeperState const K_, int const count_) |
| @@ -432,17 +446,11 @@ int keepercall_limit(lua_State* const L_) | |||
| 432 | } | 446 | } |
| 433 | // remove any clutter on the stack | 447 | // remove any clutter on the stack |
| 434 | lua_settop(_K, 0); // _K: | 448 | lua_settop(_K, 0); // _K: |
| 435 | // return true if we decide that blocked threads waiting to write on that key should be awakened | 449 | if (_key->changeLimit(_limit)) { |
| 436 | // this is the case if we detect the key was full but it is no longer the case | 450 | // return true if we decide that blocked threads waiting to write on that key should be awakened |
| 437 | // TODO: make this KeyUD::changeLimit() -> was full (bool) | 451 | // this is the case if we detect the key was full but it is no longer the case |
| 438 | if ( | ||
| 439 | ((_key->limit >= 0) && (_key->count >= _key->limit)) // the key was full if limited and count exceeded the previous limit | ||
| 440 | && ((_limit < 0) || (_key->count < _limit)) // the key is not full if unlimited or count is lower than the new limit | ||
| 441 | ) { | ||
| 442 | lua_pushboolean(_K, 1); // _K: true | 452 | lua_pushboolean(_K, 1); // _K: true |
| 443 | } | 453 | } |
| 444 | // set the new limit | ||
| 445 | _key->limit = _limit; | ||
| 446 | // return 0 or 1 value | 454 | // return 0 or 1 value |
| 447 | return lua_gettop(_K); | 455 | return lua_gettop(_K); |
| 448 | } | 456 | } |
