diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-10-07 09:29:49 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-10-07 09:29:49 +0200 |
commit | e939e5e6a894a042d3301e47faa05264445f27f6 (patch) | |
tree | e913615e3fd0ed9e94d9494d6e266420dd7a771b /src/linda.cpp | |
parent | b064bedccebe511b96c9d99d689d6634f5873ec2 (diff) | |
download | lanes-e939e5e6a894a042d3301e47faa05264445f27f6.tar.gz lanes-e939e5e6a894a042d3301e47faa05264445f27f6.tar.bz2 lanes-e939e5e6a894a042d3301e47faa05264445f27f6.zip |
Internal improvements: new strong types StackIndex and KeeperIndex
Diffstat (limited to 'src/linda.cpp')
-rw-r--r-- | src/linda.cpp | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/src/linda.cpp b/src/linda.cpp index eb39c0f..3f5fd33 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
@@ -44,10 +44,10 @@ namespace { | |||
44 | // ############################################################################################# | 44 | // ############################################################################################# |
45 | 45 | ||
46 | 46 | ||
47 | static void CheckKeyTypes(lua_State* const L_, int const start_, int const end_) | 47 | static void CheckKeyTypes(lua_State* const L_, StackIndex const start_, StackIndex const end_) |
48 | { | 48 | { |
49 | STACK_CHECK_START_REL(L_, 0); | 49 | STACK_CHECK_START_REL(L_, 0); |
50 | for (int const _i : std::ranges::iota_view{ start_, end_ + 1 }) { | 50 | for (StackIndex const _i : std::ranges::iota_view{ start_, StackIndex{ end_ + 1 } }) { |
51 | LuaType const _t{ luaG_type(L_, _i) }; | 51 | LuaType const _t{ luaG_type(L_, _i) }; |
52 | switch (_t) { | 52 | switch (_t) { |
53 | case LuaType::BOOLEAN: | 53 | case LuaType::BOOLEAN: |
@@ -83,7 +83,7 @@ namespace { | |||
83 | // ############################################################################################# | 83 | // ############################################################################################# |
84 | 84 | ||
85 | template <bool OPT> | 85 | template <bool OPT> |
86 | [[nodiscard]] static inline Linda* ToLinda(lua_State* const L_, int const idx_) | 86 | [[nodiscard]] static inline Linda* ToLinda(lua_State* const L_, StackIndex const idx_) |
87 | { | 87 | { |
88 | Linda* const _linda{ static_cast<Linda*>(LindaFactory::Instance.toDeep(L_, idx_)) }; | 88 | Linda* const _linda{ static_cast<Linda*>(LindaFactory::Instance.toDeep(L_, idx_)) }; |
89 | if constexpr (!OPT) { | 89 | if constexpr (!OPT) { |
@@ -104,7 +104,7 @@ namespace { | |||
104 | */ | 104 | */ |
105 | 105 | ||
106 | template <bool OPT> | 106 | template <bool OPT> |
107 | [[nodiscard]] static int LindaToString(lua_State* const L_, int const idx_) | 107 | [[nodiscard]] static int LindaToString(lua_State* const L_, StackIndex const idx_) |
108 | { | 108 | { |
109 | Linda* const _linda{ ToLinda<OPT>(L_, idx_) }; | 109 | Linda* const _linda{ ToLinda<OPT>(L_, idx_) }; |
110 | if (_linda != nullptr) { | 110 | if (_linda != nullptr) { |
@@ -192,7 +192,7 @@ std::string_view Linda::getName() const | |||
192 | // used to perform all linda operations that access keepers | 192 | // used to perform all linda operations that access keepers |
193 | int Linda::ProtectedCall(lua_State* const L_, lua_CFunction const f_) | 193 | int Linda::ProtectedCall(lua_State* const L_, lua_CFunction const f_) |
194 | { | 194 | { |
195 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 195 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
196 | 196 | ||
197 | // acquire the keeper | 197 | // acquire the keeper |
198 | Keeper* const _keeper{ _linda->acquireKeeper() }; | 198 | Keeper* const _keeper{ _linda->acquireKeeper() }; |
@@ -279,7 +279,7 @@ void Linda::setName(std::string_view const& name_) | |||
279 | */ | 279 | */ |
280 | LUAG_FUNC(linda_cancel) | 280 | LUAG_FUNC(linda_cancel) |
281 | { | 281 | { |
282 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 282 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
283 | std::string_view const _who{ luaG_optstring(L_, 2, "both") }; | 283 | std::string_view const _who{ luaG_optstring(L_, 2, "both") }; |
284 | // make sure we got 2 arguments: the linda and the cancellation mode | 284 | // make sure we got 2 arguments: the linda and the cancellation mode |
285 | luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); | 285 | luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); |
@@ -306,7 +306,7 @@ LUAG_FUNC(linda_cancel) | |||
306 | // linda:__close(err|nil) | 306 | // linda:__close(err|nil) |
307 | static LUAG_FUNC(linda_close) | 307 | static LUAG_FUNC(linda_close) |
308 | { | 308 | { |
309 | [[maybe_unused]] Linda* const _linda{ ToLinda<false>(L_, 1) }; // L_: linda err|nil | 309 | [[maybe_unused]] Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; // L_: linda err|nil |
310 | 310 | ||
311 | // do we have a uservalue? it contains a callback | 311 | // do we have a uservalue? it contains a callback |
312 | switch (lua_getiuservalue(L_, 1, 1)) { | 312 | switch (lua_getiuservalue(L_, 1, 1)) { |
@@ -340,11 +340,11 @@ LUAG_FUNC(linda_concat) | |||
340 | { // L_: linda1? linda2? | 340 | { // L_: linda1? linda2? |
341 | bool _atLeastOneLinda{ false }; | 341 | bool _atLeastOneLinda{ false }; |
342 | // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. | 342 | // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. |
343 | if (LindaToString<true>(L_, 1)) { | 343 | if (LindaToString<true>(L_, StackIndex{ 1 })) { |
344 | _atLeastOneLinda = true; | 344 | _atLeastOneLinda = true; |
345 | lua_replace(L_, 1); | 345 | lua_replace(L_, 1); |
346 | } | 346 | } |
347 | if (LindaToString<true>(L_, 2)) { | 347 | if (LindaToString<true>(L_, StackIndex{ 2 })) { |
348 | _atLeastOneLinda = true; | 348 | _atLeastOneLinda = true; |
349 | lua_replace(L_, 2); | 349 | lua_replace(L_, 2); |
350 | } | 350 | } |
@@ -366,9 +366,9 @@ LUAG_FUNC(linda_count) | |||
366 | { | 366 | { |
367 | static constexpr lua_CFunction _count{ | 367 | static constexpr lua_CFunction _count{ |
368 | +[](lua_State* const L_) { | 368 | +[](lua_State* const L_) { |
369 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 369 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
370 | // make sure the keys are of a valid type | 370 | // make sure the keys are of a valid type |
371 | CheckKeyTypes(L_, 2, lua_gettop(L_)); | 371 | CheckKeyTypes(L_, StackIndex{ 2 }, StackIndex{ lua_gettop(L_) }); |
372 | 372 | ||
373 | Keeper* const _keeper{ _linda->whichKeeper() }; | 373 | Keeper* const _keeper{ _linda->whichKeeper() }; |
374 | KeeperCallResult const _pushed{ keeper_call(_keeper->K, KEEPER_API(count), L_, _linda, 2) }; | 374 | KeeperCallResult const _pushed{ keeper_call(_keeper->K, KEEPER_API(count), L_, _linda, 2) }; |
@@ -392,7 +392,7 @@ LUAG_FUNC(linda_count) | |||
392 | */ | 392 | */ |
393 | LUAG_FUNC(linda_deep) | 393 | LUAG_FUNC(linda_deep) |
394 | { | 394 | { |
395 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 395 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
396 | lua_pushlightuserdata(L_, _linda->obfuscated<void*>()); // just the address | 396 | lua_pushlightuserdata(L_, _linda->obfuscated<void*>()); // just the address |
397 | return 1; | 397 | return 1; |
398 | } | 398 | } |
@@ -407,7 +407,7 @@ LUAG_FUNC(linda_dump) | |||
407 | { | 407 | { |
408 | static constexpr lua_CFunction _dump{ | 408 | static constexpr lua_CFunction _dump{ |
409 | +[](lua_State* const L_) { | 409 | +[](lua_State* const L_) { |
410 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 410 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
411 | return Keeper::PushLindaStorage(*_linda, DestState{ L_ }); | 411 | return Keeper::PushLindaStorage(*_linda, DestState{ L_ }); |
412 | } | 412 | } |
413 | }; | 413 | }; |
@@ -425,12 +425,12 @@ LUAG_FUNC(linda_get) | |||
425 | { | 425 | { |
426 | static constexpr lua_CFunction _get{ | 426 | static constexpr lua_CFunction _get{ |
427 | +[](lua_State* const L_) { | 427 | +[](lua_State* const L_) { |
428 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 428 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
429 | lua_Integer const _count{ luaL_optinteger(L_, 3, 1) }; | 429 | lua_Integer const _count{ luaL_optinteger(L_, 3, 1) }; |
430 | luaL_argcheck(L_, _count >= 1, 3, "count should be >= 1"); | 430 | luaL_argcheck(L_, _count >= 1, 3, "count should be >= 1"); |
431 | luaL_argcheck(L_, lua_gettop(L_) <= 3, 4, "too many arguments"); | 431 | luaL_argcheck(L_, lua_gettop(L_) <= 3, 4, "too many arguments"); |
432 | // make sure the key is of a valid type (throws an error if not the case) | 432 | // make sure the key is of a valid type (throws an error if not the case) |
433 | CheckKeyTypes(L_, 2, 2); | 433 | CheckKeyTypes(L_, StackIndex{ 2 }, StackIndex{ 2 }); |
434 | 434 | ||
435 | KeeperCallResult _pushed; | 435 | KeeperCallResult _pushed; |
436 | if (_linda->cancelRequest == CancelRequest::None) { | 436 | if (_linda->cancelRequest == CancelRequest::None) { |
@@ -463,7 +463,7 @@ LUAG_FUNC(linda_limit) | |||
463 | { | 463 | { |
464 | static constexpr lua_CFunction _limit{ | 464 | static constexpr lua_CFunction _limit{ |
465 | +[](lua_State* const L_) { | 465 | +[](lua_State* const L_) { |
466 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 466 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
467 | // make sure we got 2 or 3 arguments: the linda, a key and optionally a limit | 467 | // make sure we got 2 or 3 arguments: the linda, a key and optionally a limit |
468 | int const _nargs{ lua_gettop(L_) }; | 468 | int const _nargs{ lua_gettop(L_) }; |
469 | luaL_argcheck(L_, _nargs == 2 || _nargs == 3, 2, "wrong number of arguments"); | 469 | luaL_argcheck(L_, _nargs == 2 || _nargs == 3, 2, "wrong number of arguments"); |
@@ -474,7 +474,7 @@ LUAG_FUNC(linda_limit) | |||
474 | raise_luaL_argerror(L_, 3, "limit must be >= 0"); | 474 | raise_luaL_argerror(L_, 3, "limit must be >= 0"); |
475 | } | 475 | } |
476 | // make sure the key is of a valid type | 476 | // make sure the key is of a valid type |
477 | CheckKeyTypes(L_, 2, 2); | 477 | CheckKeyTypes(L_, StackIndex{ 2 }, StackIndex{ 2 }); |
478 | 478 | ||
479 | KeeperCallResult _pushed; | 479 | KeeperCallResult _pushed; |
480 | if (_linda->cancelRequest == CancelRequest::None) { | 480 | if (_linda->cancelRequest == CancelRequest::None) { |
@@ -526,8 +526,8 @@ LUAG_FUNC(linda_receive) | |||
526 | { | 526 | { |
527 | static constexpr lua_CFunction _receive{ | 527 | static constexpr lua_CFunction _receive{ |
528 | +[](lua_State* const L_) { | 528 | +[](lua_State* const L_) { |
529 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 529 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
530 | int _key_i{ 2 }; // index of first key, if timeout not there | 530 | StackIndex _key_i{ 2 }; // index of first key, if timeout not there |
531 | 531 | ||
532 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; | 532 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; |
533 | if (luaG_type(L_, 2) == LuaType::NUMBER) { // we don't want to use lua_isnumber() because of autocoercion | 533 | if (luaG_type(L_, 2) == LuaType::NUMBER) { // we don't want to use lua_isnumber() because of autocoercion |
@@ -566,7 +566,7 @@ LUAG_FUNC(linda_receive) | |||
566 | } | 566 | } |
567 | } else { | 567 | } else { |
568 | // make sure the keys are of a valid type | 568 | // make sure the keys are of a valid type |
569 | CheckKeyTypes(L_, _key_i, lua_gettop(L_)); | 569 | CheckKeyTypes(L_, _key_i, StackIndex{ lua_gettop(L_) }); |
570 | // receive a single value, checking multiple slots | 570 | // receive a single value, checking multiple slots |
571 | _selected_keeper_receive = KEEPER_API(receive); | 571 | _selected_keeper_receive = KEEPER_API(receive); |
572 | // we expect a single (value, key) pair of returned values | 572 | // we expect a single (value, key) pair of returned values |
@@ -682,8 +682,8 @@ LUAG_FUNC(linda_send) | |||
682 | { | 682 | { |
683 | static constexpr lua_CFunction _send{ | 683 | static constexpr lua_CFunction _send{ |
684 | +[](lua_State* const L_) { | 684 | +[](lua_State* const L_) { |
685 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 685 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
686 | int _key_i{ 2 }; // index of first key, if timeout not there | 686 | StackIndex _key_i{ 2 }; // index of first key, if timeout not there |
687 | 687 | ||
688 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; | 688 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; |
689 | if (luaG_type(L_, 2) == LuaType::NUMBER) { // we don't want to use lua_isnumber() because of autocoercion | 689 | if (luaG_type(L_, 2) == LuaType::NUMBER) { // we don't want to use lua_isnumber() because of autocoercion |
@@ -820,10 +820,10 @@ LUAG_FUNC(linda_set) | |||
820 | { | 820 | { |
821 | static constexpr lua_CFunction _set{ | 821 | static constexpr lua_CFunction _set{ |
822 | +[](lua_State* const L_) { | 822 | +[](lua_State* const L_) { |
823 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 823 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
824 | bool const _has_data{ lua_gettop(L_) > 2 }; | 824 | bool const _has_data{ lua_gettop(L_) > 2 }; |
825 | // make sure the key is of a valid type (throws an error if not the case) | 825 | // make sure the key is of a valid type (throws an error if not the case) |
826 | CheckKeyTypes(L_, 2, 2); | 826 | CheckKeyTypes(L_, StackIndex{ 2 }, StackIndex{ 2 }); |
827 | 827 | ||
828 | KeeperCallResult _pushed; | 828 | KeeperCallResult _pushed; |
829 | if (_linda->cancelRequest == CancelRequest::None) { | 829 | if (_linda->cancelRequest == CancelRequest::None) { |
@@ -859,7 +859,7 @@ LUAG_FUNC(linda_set) | |||
859 | 859 | ||
860 | LUAG_FUNC(linda_tostring) | 860 | LUAG_FUNC(linda_tostring) |
861 | { | 861 | { |
862 | return LindaToString<false>(L_, 1); | 862 | return LindaToString<false>(L_, StackIndex{ 1 }); |
863 | } | 863 | } |
864 | 864 | ||
865 | // ################################################################################################# | 865 | // ################################################################################################# |
@@ -871,11 +871,11 @@ LUAG_FUNC(linda_tostring) | |||
871 | */ | 871 | */ |
872 | LUAG_FUNC(linda_towatch) | 872 | LUAG_FUNC(linda_towatch) |
873 | { | 873 | { |
874 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 874 | Linda* const _linda{ ToLinda<false>(L_, StackIndex{ 1 }) }; |
875 | int _pushed{ Keeper::PushLindaStorage(*_linda, DestState{ L_ }) }; | 875 | int _pushed{ Keeper::PushLindaStorage(*_linda, DestState{ L_ }) }; |
876 | if (_pushed == 0) { | 876 | if (_pushed == 0) { |
877 | // if the linda is empty, don't return nil | 877 | // if the linda is empty, don't return nil |
878 | _pushed = LindaToString<false>(L_, 1); | 878 | _pushed = LindaToString<false>(L_, StackIndex{ 1 }); |
879 | } | 879 | } |
880 | return _pushed; | 880 | return _pushed; |
881 | } | 881 | } |
@@ -989,7 +989,7 @@ LUAG_FUNC(linda) | |||
989 | } | 989 | } |
990 | // depending on whether we have a handler or not, the stack is not in the same state at this point | 990 | // depending on whether we have a handler or not, the stack is not in the same state at this point |
991 | // just make sure we have our Linda at the top | 991 | // just make sure we have our Linda at the top |
992 | LUA_ASSERT(L_, ToLinda<true>(L_, -1)); | 992 | LUA_ASSERT(L_, ToLinda<true>(L_, StackIndex{ -1 })); |
993 | return 1; | 993 | return 1; |
994 | } else { // no to-be-closed support | 994 | } else { // no to-be-closed support |
995 | // ensure we have name, group in that order on the stack | 995 | // ensure we have name, group in that order on the stack |