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 | |
parent | b064bedccebe511b96c9d99d689d6634f5873ec2 (diff) | |
download | lanes-e939e5e6a894a042d3301e47faa05264445f27f6.tar.gz lanes-e939e5e6a894a042d3301e47faa05264445f27f6.tar.bz2 lanes-e939e5e6a894a042d3301e47faa05264445f27f6.zip |
Internal improvements: new strong types StackIndex and KeeperIndex
-rw-r--r-- | src/debug.h | 20 | ||||
-rw-r--r-- | src/keeper.cpp | 2 | ||||
-rw-r--r-- | src/keeper.h | 3 | ||||
-rw-r--r-- | src/linda.cpp | 56 | ||||
-rw-r--r-- | src/linda.h | 2 | ||||
-rw-r--r-- | src/macros_and_utils.h | 34 | ||||
-rw-r--r-- | src/unique.hpp | 44 | ||||
-rw-r--r-- | src/universe.cpp | 2 |
8 files changed, 84 insertions, 79 deletions
diff --git a/src/debug.h b/src/debug.h index e96632d..0f5c6bc 100644 --- a/src/debug.h +++ b/src/debug.h | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | #include "lanesconf.h" | 3 | #include "lanesconf.h" |
4 | #include "luaerrors.h" | 4 | #include "luaerrors.h" |
5 | #include "unique.hpp" | ||
5 | 6 | ||
6 | // ################################################################################################# | 7 | // ################################################################################################# |
7 | 8 | ||
@@ -18,7 +19,7 @@ inline SourceLocation Where(std::source_location const& where_ = std::source_loc | |||
18 | return std::make_tuple(_fileName, where_.line(), _func); | 19 | return std::make_tuple(_fileName, where_.line(), _func); |
19 | } | 20 | } |
20 | 21 | ||
21 | inline void LUA_ASSERT_IMPL(lua_State* const L_, bool cond_, std::string_view const& txt_, SourceLocation const& where_ = Where()) | 22 | inline void LUA_ASSERT_IMPL(lua_State* const L_, bool const cond_, std::string_view const& txt_, SourceLocation const& where_ = Where()) |
22 | { | 23 | { |
23 | if (!cond_) { | 24 | if (!cond_) { |
24 | raise_luaL_error(L_, "%s:%d: LUA_ASSERT '%s' IN %s", std::get<0>(where_).data(), std::get<1>(where_), txt_.data(), std::get<2>(where_).data()); | 25 | raise_luaL_error(L_, "%s:%d: LUA_ASSERT '%s' IN %s", std::get<0>(where_).data(), std::get<1>(where_), txt_.data(), std::get<2>(where_).data()); |
@@ -35,19 +36,8 @@ class StackChecker | |||
35 | int oldtop; | 36 | int oldtop; |
36 | 37 | ||
37 | public: | 38 | public: |
38 | struct Relative | 39 | using Relative = Unique<int>; |
39 | { | 40 | using Absolute = Unique<int>; |
40 | int const offset; | ||
41 | |||
42 | operator int() const { return offset; } | ||
43 | }; | ||
44 | |||
45 | struct Absolute | ||
46 | { | ||
47 | int const offset; | ||
48 | |||
49 | operator int() const { return offset; } | ||
50 | }; | ||
51 | 41 | ||
52 | StackChecker(lua_State* const L_, Relative const offset_, SourceLocation const& where_ = Where()) | 42 | StackChecker(lua_State* const L_, Relative const offset_, SourceLocation const& where_ = Where()) |
53 | : L{ L_ } | 43 | : L{ L_ } |
@@ -77,7 +67,7 @@ class StackChecker | |||
77 | } | 67 | } |
78 | 68 | ||
79 | // verify if the distance between the current top and the initial one is what we expect | 69 | // verify if the distance between the current top and the initial one is what we expect |
80 | void check(int expected_, SourceLocation const& where_ = Where()) | 70 | void check(int const expected_, SourceLocation const& where_ = Where()) |
81 | { | 71 | { |
82 | if (expected_ != LUA_MULTRET) { | 72 | if (expected_ != LUA_MULTRET) { |
83 | int const _actual{ lua_gettop(L) - oldtop }; | 73 | int const _actual{ lua_gettop(L) - oldtop }; |
diff --git a/src/keeper.cpp b/src/keeper.cpp index e2df380..58796b8 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
@@ -840,7 +840,7 @@ void Keepers::close() | |||
840 | 840 | ||
841 | // ################################################################################################# | 841 | // ################################################################################################# |
842 | 842 | ||
843 | [[nodiscard]] Keeper* Keepers::getKeeper(int idx_) | 843 | [[nodiscard]] Keeper* Keepers::getKeeper(KeeperIndex const idx_) |
844 | { | 844 | { |
845 | if (isClosing.test(std::memory_order_acquire)) { | 845 | if (isClosing.test(std::memory_order_acquire)) { |
846 | return nullptr; | 846 | return nullptr; |
diff --git a/src/keeper.h b/src/keeper.h index 05e3547..04bf834 100644 --- a/src/keeper.h +++ b/src/keeper.h | |||
@@ -9,6 +9,7 @@ class Universe; | |||
9 | 9 | ||
10 | using KeeperState = Unique<lua_State*>; | 10 | using KeeperState = Unique<lua_State*>; |
11 | using LindaLimit = Unique<int>; | 11 | using LindaLimit = Unique<int>; |
12 | using KeeperIndex = Unique<int>; | ||
12 | 13 | ||
13 | // ################################################################################################# | 14 | // ################################################################################################# |
14 | 15 | ||
@@ -62,7 +63,7 @@ struct Keepers | |||
62 | 63 | ||
63 | Keepers() = default; | 64 | Keepers() = default; |
64 | void close(); | 65 | void close(); |
65 | [[nodiscard]] Keeper* getKeeper(int idx_); | 66 | [[nodiscard]] Keeper* getKeeper(KeeperIndex idx_); |
66 | [[nodiscard]] int getNbKeepers() const; | 67 | [[nodiscard]] int getNbKeepers() const; |
67 | void initialize(Universe& U_, lua_State* L_, int nbKeepers_, int gc_threshold_); | 68 | void initialize(Universe& U_, lua_State* L_, int nbKeepers_, int gc_threshold_); |
68 | }; | 69 | }; |
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 |
diff --git a/src/linda.h b/src/linda.h index 6901a86..4551443 100644 --- a/src/linda.h +++ b/src/linda.h | |||
@@ -52,7 +52,7 @@ class Linda | |||
52 | std::condition_variable readHappened{}; | 52 | std::condition_variable readHappened{}; |
53 | std::condition_variable writeHappened{}; | 53 | std::condition_variable writeHappened{}; |
54 | Universe* const U{ nullptr }; // the universe this linda belongs to | 54 | Universe* const U{ nullptr }; // the universe this linda belongs to |
55 | int const keeperIndex{ -1 }; // the keeper associated to this linda | 55 | KeeperIndex const keeperIndex{ -1 }; // the keeper associated to this linda |
56 | CancelRequest cancelRequest{ CancelRequest::None }; | 56 | CancelRequest cancelRequest{ CancelRequest::None }; |
57 | 57 | ||
58 | public: | 58 | public: |
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index 1b1ced6..e73abef 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | #include "debug.h" | 3 | #include "debug.h" |
4 | #include "luaerrors.h" | 4 | #include "luaerrors.h" |
5 | #include "unique.hpp" | ||
5 | 6 | ||
6 | using namespace std::chrono_literals; | 7 | using namespace std::chrono_literals; |
7 | 8 | ||
@@ -24,40 +25,9 @@ using lua_Duration = std::chrono::template duration<lua_Number>; | |||
24 | 25 | ||
25 | // ################################################################################################# | 26 | // ################################################################################################# |
26 | 27 | ||
27 | // A unique type generator | ||
28 | template <typename T, auto = [] {}, typename specialization = void> | ||
29 | class Unique | ||
30 | { | ||
31 | private: | ||
32 | T val; | ||
33 | |||
34 | public: | ||
35 | using type = T; | ||
36 | Unique() = default; | ||
37 | operator T() const { return val; } | ||
38 | explicit Unique(T b_) | ||
39 | : val{ b_ } | ||
40 | { | ||
41 | } | ||
42 | }; | ||
43 | |||
44 | template <typename T, auto lambda> | ||
45 | class Unique<T, lambda, std::enable_if_t<!std::is_scalar_v<T>>> | ||
46 | : public T | ||
47 | { | ||
48 | public: | ||
49 | using type = T; | ||
50 | using T::T; | ||
51 | explicit Unique(T const& b_) | ||
52 | : T{ b_ } | ||
53 | { | ||
54 | } | ||
55 | }; | ||
56 | |||
57 | // ################################################################################################# | ||
58 | |||
59 | using SourceState = Unique<lua_State*>; | 28 | using SourceState = Unique<lua_State*>; |
60 | using DestState = Unique<lua_State*>; | 29 | using DestState = Unique<lua_State*>; |
30 | using StackIndex = Unique<int>; | ||
61 | 31 | ||
62 | // ################################################################################################# | 32 | // ################################################################################################# |
63 | 33 | ||
diff --git a/src/unique.hpp b/src/unique.hpp new file mode 100644 index 0000000..aeb7a67 --- /dev/null +++ b/src/unique.hpp | |||
@@ -0,0 +1,44 @@ | |||
1 | #pragma once | ||
2 | |||
3 | // ################################################################################################# | ||
4 | |||
5 | // A unique type generator | ||
6 | template <typename T, auto = [] {}, typename specialization = void> | ||
7 | class Unique | ||
8 | { | ||
9 | private: | ||
10 | T val; | ||
11 | |||
12 | public: | ||
13 | using type = T; | ||
14 | Unique() = default; | ||
15 | operator T() const { return val; } | ||
16 | explicit Unique(T b_) | ||
17 | : val{ b_ } | ||
18 | { | ||
19 | } | ||
20 | // pre-imcrement | ||
21 | auto& operator++() | ||
22 | { | ||
23 | ++val; | ||
24 | return *this; | ||
25 | } | ||
26 | // post-increment | ||
27 | auto operator++(int) | ||
28 | { | ||
29 | return Unique<T>{ std::exchange(val, val + 1) }; | ||
30 | } | ||
31 | }; | ||
32 | |||
33 | template <typename T, auto lambda> | ||
34 | class Unique<T, lambda, std::enable_if_t<!std::is_scalar_v<T>>> | ||
35 | : public T | ||
36 | { | ||
37 | public: | ||
38 | using type = T; | ||
39 | using T::T; | ||
40 | explicit Unique(T const& b_) | ||
41 | : T{ b_ } | ||
42 | { | ||
43 | } | ||
44 | }; | ||
diff --git a/src/universe.cpp b/src/universe.cpp index 04db10f..3800dbb 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
@@ -85,7 +85,7 @@ void Universe::callOnStateCreate(lua_State* const L_, lua_State* const from_, Lo | |||
85 | } | 85 | } |
86 | 86 | ||
87 | STACK_CHECK_START_REL(L_, 0); | 87 | STACK_CHECK_START_REL(L_, 0); |
88 | DEBUGSPEW_CODE(DebugSpew(U_) << "calling on_state_create()" << std::endl); | 88 | DEBUGSPEW_CODE(DebugSpew(this) << "calling on_state_create()" << std::endl); |
89 | if (std::holds_alternative<lua_CFunction>(onStateCreateFunc)) { | 89 | if (std::holds_alternative<lua_CFunction>(onStateCreateFunc)) { |
90 | 90 | ||
91 | // C function: recreate a closure in the new state, bypassing the lookup scheme | 91 | // C function: recreate a closure in the new state, bypassing the lookup scheme |