diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-26 17:46:00 +0100 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-26 17:46:00 +0100 |
commit | f214d35df5f09e7026dafd8553e83cc6ea21cbde (patch) | |
tree | 2bd19bfddf4949183fe0e84ca58940fd6a6aa918 /src | |
parent | 2eeb245b98bd702379aa92d888f7b7d21d1193b8 (diff) | |
download | lanes-f214d35df5f09e7026dafd8553e83cc6ea21cbde.tar.gz lanes-f214d35df5f09e7026dafd8553e83cc6ea21cbde.tar.bz2 lanes-f214d35df5f09e7026dafd8553e83cc6ea21cbde.zip |
C++ migration: templated lua_touserdata
Diffstat (limited to 'src')
-rw-r--r-- | src/deep.cpp | 14 | ||||
-rw-r--r-- | src/keeper.cpp | 32 | ||||
-rw-r--r-- | src/lanes.cpp | 6 | ||||
-rw-r--r-- | src/lanes_private.h | 2 | ||||
-rw-r--r-- | src/linda.cpp | 2 | ||||
-rw-r--r-- | src/macros_and_utils.h | 7 | ||||
-rw-r--r-- | src/state.cpp | 2 | ||||
-rw-r--r-- | src/universe.cpp | 2 | ||||
-rw-r--r-- | src/universe.h | 2 |
9 files changed, 41 insertions, 28 deletions
diff --git a/src/deep.cpp b/src/deep.cpp index dd682e4..f091d4d 100644 --- a/src/deep.cpp +++ b/src/deep.cpp | |||
@@ -113,7 +113,7 @@ static inline luaG_IdFunction* get_idfunc( lua_State* L, int index, LookupMode m | |||
113 | // when looking inside a keeper, we are 100% sure the object is a deep userdata | 113 | // when looking inside a keeper, we are 100% sure the object is a deep userdata |
114 | if( mode_ == eLM_FromKeeper) | 114 | if( mode_ == eLM_FromKeeper) |
115 | { | 115 | { |
116 | DeepPrelude** proxy = (DeepPrelude**) lua_touserdata( L, index); | 116 | DeepPrelude** const proxy{ lua_touserdata<DeepPrelude*>(L, index) }; |
117 | // we can (and must) cast and fetch the internally stored idfunc | 117 | // we can (and must) cast and fetch the internally stored idfunc |
118 | return (*proxy)->idfunc; | 118 | return (*proxy)->idfunc; |
119 | } | 119 | } |
@@ -133,7 +133,7 @@ static inline luaG_IdFunction* get_idfunc( lua_State* L, int index, LookupMode m | |||
133 | // replace metatable with the idfunc pointer, if it is actually a deep userdata | 133 | // replace metatable with the idfunc pointer, if it is actually a deep userdata |
134 | get_deep_lookup( L); // deep ... idfunc|nil | 134 | get_deep_lookup( L); // deep ... idfunc|nil |
135 | 135 | ||
136 | luaG_IdFunction* const ret{ static_cast<luaG_IdFunction*>(lua_touserdata(L, -1)) }; // nullptr if not a userdata | 136 | luaG_IdFunction* const ret{ lua_touserdata<luaG_IdFunction>(L, -1) }; // nullptr if not a userdata |
137 | lua_pop( L, 1); | 137 | lua_pop( L, 1); |
138 | STACK_CHECK( L, 0); | 138 | STACK_CHECK( L, 0); |
139 | return ret; | 139 | return ret; |
@@ -161,7 +161,7 @@ void free_deep_prelude( lua_State* L, DeepPrelude* prelude_) | |||
161 | */ | 161 | */ |
162 | static int deep_userdata_gc( lua_State* L) | 162 | static int deep_userdata_gc( lua_State* L) |
163 | { | 163 | { |
164 | DeepPrelude** proxy = (DeepPrelude**) lua_touserdata( L, 1); | 164 | DeepPrelude** const proxy{ lua_touserdata<DeepPrelude*>(L, 1) }; |
165 | DeepPrelude* p = *proxy; | 165 | DeepPrelude* p = *proxy; |
166 | 166 | ||
167 | // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded | 167 | // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded |
@@ -418,17 +418,15 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction* idfunc, int nuv_) | |||
418 | */ | 418 | */ |
419 | void* luaG_todeep( lua_State* L, luaG_IdFunction* idfunc, int index) | 419 | void* luaG_todeep( lua_State* L, luaG_IdFunction* idfunc, int index) |
420 | { | 420 | { |
421 | DeepPrelude** proxy; | ||
422 | |||
423 | STACK_CHECK_START_REL(L, 0); | 421 | STACK_CHECK_START_REL(L, 0); |
424 | // ensure it is actually a deep userdata | 422 | // ensure it is actually a deep userdata |
425 | if( get_idfunc( L, index, eLM_LaneBody) != idfunc) | 423 | if( get_idfunc( L, index, eLM_LaneBody) != idfunc) |
426 | { | 424 | { |
427 | return nullptr; // no metatable, or wrong kind | 425 | return nullptr; // no metatable, or wrong kind |
428 | } | 426 | } |
427 | STACK_CHECK(L, 0); | ||
429 | 428 | ||
430 | proxy = (DeepPrelude**) lua_touserdata( L, index); | 429 | DeepPrelude** const proxy{ lua_touserdata<DeepPrelude*>(L, index) }; |
431 | STACK_CHECK( L, 0); | ||
432 | 430 | ||
433 | return *proxy; | 431 | return *proxy; |
434 | } | 432 | } |
@@ -464,7 +462,7 @@ bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, L | |||
464 | lua_pop( L, 1); // ... u [uv]* | 462 | lua_pop( L, 1); // ... u [uv]* |
465 | STACK_CHECK( L, nuv); | 463 | STACK_CHECK( L, nuv); |
466 | 464 | ||
467 | errmsg = push_deep_proxy(L2, *(DeepPrelude**) lua_touserdata( L, i), nuv, mode_); // u | 465 | errmsg = push_deep_proxy(L2, *lua_touserdata<DeepPrelude*>(L, i), nuv, mode_); // u |
468 | 466 | ||
469 | // transfer all uservalues of the source in the destination | 467 | // transfer all uservalues of the source in the destination |
470 | { | 468 | { |
diff --git a/src/keeper.cpp b/src/keeper.cpp index 88bd4ff..35b5ea8 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
@@ -52,11 +52,18 @@ | |||
52 | // Keeper implementation | 52 | // Keeper implementation |
53 | // ################################################################################### | 53 | // ################################################################################### |
54 | 54 | ||
55 | struct keeper_fifo | 55 | class keeper_fifo |
56 | { | 56 | { |
57 | public: | ||
58 | |||
57 | int first{ 1 }; | 59 | int first{ 1 }; |
58 | int count{ 0 }; | 60 | int count{ 0 }; |
59 | int limit{ -1 }; | 61 | int limit{ -1 }; |
62 | |||
63 | static void* operator new(size_t size_, lua_State* L) noexcept { return lua_newuserdatauv(L, size_, 1); } | ||
64 | // always embedded somewhere else or "in-place constructed" as a full userdata | ||
65 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | ||
66 | static void operator delete(void* p_, lua_State* L){ ASSERT_L(!"should never be called") }; | ||
60 | }; | 67 | }; |
61 | 68 | ||
62 | static constexpr int CONTENTS_TABLE{ 1 }; | 69 | static constexpr int CONTENTS_TABLE{ 1 }; |
@@ -66,7 +73,7 @@ static constexpr int CONTENTS_TABLE{ 1 }; | |||
66 | // replaces the fifo ud by its uservalue on the stack | 73 | // replaces the fifo ud by its uservalue on the stack |
67 | static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) | 74 | static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) |
68 | { | 75 | { |
69 | keeper_fifo* const fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, idx_)) }; | 76 | keeper_fifo* const fifo{ lua_touserdata<keeper_fifo>(L, idx_) }; |
70 | if (fifo != nullptr) | 77 | if (fifo != nullptr) |
71 | { | 78 | { |
72 | idx_ = lua_absindex(L, idx_); | 79 | idx_ = lua_absindex(L, idx_); |
@@ -84,13 +91,14 @@ static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) | |||
84 | // out: { first = 1, count = 0, limit = -1} | 91 | // out: { first = 1, count = 0, limit = -1} |
85 | static void fifo_new(lua_State* L) | 92 | static void fifo_new(lua_State* L) |
86 | { | 93 | { |
87 | keeper_fifo* fifo; | ||
88 | STACK_GROW(L, 2); | 94 | STACK_GROW(L, 2); |
95 | STACK_CHECK_START_REL(L, 0); | ||
89 | // a fifo full userdata has one uservalue, the table that holds the actual fifo contents | 96 | // a fifo full userdata has one uservalue, the table that holds the actual fifo contents |
90 | fifo = (keeper_fifo*) lua_newuserdatauv(L, sizeof(keeper_fifo), 1); | 97 | [[maybe_unused]] keeper_fifo* const fifo{ new (L) keeper_fifo{} }; |
91 | fifo->keeper_fifo::keeper_fifo(); | 98 | STACK_CHECK(L, 1); |
92 | lua_newtable(L); | 99 | lua_newtable(L); |
93 | lua_setiuservalue(L, -2, CONTENTS_TABLE); | 100 | lua_setiuservalue(L, -2, CONTENTS_TABLE); |
101 | STACK_CHECK(L, 1); | ||
94 | } | 102 | } |
95 | 103 | ||
96 | // ################################################################################################## | 104 | // ################################################################################################## |
@@ -163,13 +171,13 @@ static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_) | |||
163 | 171 | ||
164 | // ################################################################################################## | 172 | // ################################################################################################## |
165 | 173 | ||
166 | // in: linda_ud expected at *absolute* stack slot idx | 174 | // in: linda_ud expected at stack slot idx |
167 | // out: fifos[ud] | 175 | // out: fifos[ud] |
168 | // crc64/we of string "FIFOS_KEY" generated at http://www.nitrxgen.net/hashgen/ | 176 | // crc64/we of string "FIFOS_KEY" generated at http://www.nitrxgen.net/hashgen/ |
169 | static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull }; | 177 | static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull }; |
170 | static void push_table(lua_State* L, int idx_) | 178 | static void push_table(lua_State* L, int idx_) |
171 | { | 179 | { |
172 | STACK_GROW(L, 4); | 180 | STACK_GROW(L, 5); |
173 | STACK_CHECK_START_REL(L, 0); | 181 | STACK_CHECK_START_REL(L, 0); |
174 | idx_ = lua_absindex(L, idx_); | 182 | idx_ = lua_absindex(L, idx_); |
175 | FIFOS_KEY.query_registry(L); // ud fifos | 183 | FIFOS_KEY.query_registry(L); // ud fifos |
@@ -276,7 +284,7 @@ int keepercall_send(lua_State* L) | |||
276 | lua_rawset(L, -4); // ud key ... fifos fifo | 284 | lua_rawset(L, -4); // ud key ... fifos fifo |
277 | } | 285 | } |
278 | lua_remove(L, -2); // ud key ... fifo | 286 | lua_remove(L, -2); // ud key ... fifo |
279 | keeper_fifo* fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, -1)) }; | 287 | keeper_fifo* fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
280 | if( fifo->limit >= 0 && fifo->count + n > fifo->limit) | 288 | if( fifo->limit >= 0 && fifo->count + n > fifo->limit) |
281 | { | 289 | { |
282 | lua_settop(L, 0); // | 290 | lua_settop(L, 0); // |
@@ -374,12 +382,12 @@ int keepercall_limit(lua_State* L) | |||
374 | lua_pop(L, 1); // fifos key | 382 | lua_pop(L, 1); // fifos key |
375 | lua_pushvalue(L, -1); // fifos key key | 383 | lua_pushvalue(L, -1); // fifos key key |
376 | lua_rawget(L, -3); // fifos key fifo|nil | 384 | lua_rawget(L, -3); // fifos key fifo|nil |
377 | keeper_fifo* fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, -1)) }; | 385 | keeper_fifo* fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
378 | if (fifo == nullptr) | 386 | if (fifo == nullptr) |
379 | { // fifos key nil | 387 | { // fifos key nil |
380 | lua_pop(L, 1); // fifos key | 388 | lua_pop(L, 1); // fifos key |
381 | fifo_new(L); // fifos key fifo | 389 | fifo_new(L); // fifos key fifo |
382 | fifo = static_cast<keeper_fifo*>(lua_touserdata(L, -1)); | 390 | fifo = lua_touserdata<keeper_fifo>(L, -1); |
383 | lua_rawset(L, -3); // fifos | 391 | lua_rawset(L, -3); // fifos |
384 | } | 392 | } |
385 | // remove any clutter on the stack | 393 | // remove any clutter on the stack |
@@ -418,7 +426,7 @@ int keepercall_set(lua_State* L) | |||
418 | lua_pushvalue(L, -1); // fifos key key | 426 | lua_pushvalue(L, -1); // fifos key key |
419 | lua_rawget(L, 1); // fifos key fifo|nil | 427 | lua_rawget(L, 1); // fifos key fifo|nil |
420 | // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! | 428 | // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! |
421 | keeper_fifo* const fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, -1)) }; | 429 | keeper_fifo* const fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
422 | if (fifo != nullptr) // might be nullptr if we set a nonexistent key to nil | 430 | if (fifo != nullptr) // might be nullptr if we set a nonexistent key to nil |
423 | { // fifos key fifo | 431 | { // fifos key fifo |
424 | if (fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it | 432 | if (fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it |
@@ -444,7 +452,7 @@ int keepercall_set(lua_State* L) | |||
444 | int const count{ lua_gettop(L) - 2 }; // number of items we want to store | 452 | int const count{ lua_gettop(L) - 2 }; // number of items we want to store |
445 | lua_pushvalue(L, 2); // fifos key [val [, ...]] key | 453 | lua_pushvalue(L, 2); // fifos key [val [, ...]] key |
446 | lua_rawget(L, 1); // fifos key [val [, ...]] fifo|nil | 454 | lua_rawget(L, 1); // fifos key [val [, ...]] fifo|nil |
447 | keeper_fifo* fifo = static_cast<keeper_fifo*>(lua_touserdata( L, -1)); | 455 | keeper_fifo* fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
448 | if( fifo == nullptr) // can be nullptr if we store a value at a new key | 456 | if( fifo == nullptr) // can be nullptr if we store a value at a new key |
449 | { // fifos key [val [, ...]] nil | 457 | { // fifos key [val [, ...]] nil |
450 | // no need to wake writers in that case, because a writer can't wait on an inexistent key | 458 | // no need to wake writers in that case, because a writer can't wait on an inexistent key |
diff --git a/src/lanes.cpp b/src/lanes.cpp index 5945a1a..6b3542b 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
@@ -442,7 +442,7 @@ static bool selfdestruct_remove( Lane* s) | |||
442 | */ | 442 | */ |
443 | static int selfdestruct_gc( lua_State* L) | 443 | static int selfdestruct_gc( lua_State* L) |
444 | { | 444 | { |
445 | Universe* U = (Universe*) lua_touserdata( L, 1); | 445 | Universe* const U{ lua_touserdata<Universe>(L, 1) }; |
446 | 446 | ||
447 | while( U->selfdestruct_first != SELFDESTRUCT_END) // true at most once! | 447 | while( U->selfdestruct_first != SELFDESTRUCT_END) // true at most once! |
448 | { | 448 | { |
@@ -781,7 +781,7 @@ LUAG_FUNC( set_debug_threadname) | |||
781 | // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator | 781 | // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator |
782 | constexpr UniqueKey hidden_regkey{ 0x79C0669AAAE04440ull }; | 782 | constexpr UniqueKey hidden_regkey{ 0x79C0669AAAE04440ull }; |
783 | // C s_lane structure is a light userdata upvalue | 783 | // C s_lane structure is a light userdata upvalue |
784 | Lane* s = (Lane*) lua_touserdata( L, lua_upvalueindex( 1)); | 784 | Lane* const s{ lua_touserdata<Lane>(L, lua_upvalueindex(1)) }; |
785 | luaL_checktype( L, -1, LUA_TSTRING); // "name" | 785 | luaL_checktype( L, -1, LUA_TSTRING); // "name" |
786 | lua_settop( L, 1); | 786 | lua_settop( L, 1); |
787 | STACK_CHECK_START_ABS( L, 1); | 787 | STACK_CHECK_START_ABS( L, 1); |
@@ -1887,7 +1887,7 @@ LUAG_FUNC( configure) | |||
1887 | STACK_CHECK( L, 2); | 1887 | STACK_CHECK( L, 2); |
1888 | 1888 | ||
1889 | // Proxy userdata contents is only a 'DeepPrelude*' pointer | 1889 | // Proxy userdata contents is only a 'DeepPrelude*' pointer |
1890 | U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1); | 1890 | U->timer_deep = *lua_touserdata<DeepPrelude*>(L, -1); |
1891 | // increment refcount so that this linda remains alive as long as the universe exists. | 1891 | // increment refcount so that this linda remains alive as long as the universe exists. |
1892 | U->timer_deep->m_refcount.fetch_add(1, std::memory_order_relaxed); | 1892 | U->timer_deep->m_refcount.fetch_add(1, std::memory_order_relaxed); |
1893 | lua_pop( L, 1); // settings | 1893 | lua_pop( L, 1); // settings |
diff --git a/src/lanes_private.h b/src/lanes_private.h index b8d26d3..839a51f 100644 --- a/src/lanes_private.h +++ b/src/lanes_private.h | |||
@@ -83,7 +83,7 @@ static inline Lane* get_lane_from_registry( lua_State* L) | |||
83 | STACK_GROW( L, 1); | 83 | STACK_GROW( L, 1); |
84 | STACK_CHECK_START_REL(L, 0); | 84 | STACK_CHECK_START_REL(L, 0); |
85 | CANCEL_TEST_KEY.query_registry(L); | 85 | CANCEL_TEST_KEY.query_registry(L); |
86 | Lane* const s = static_cast<Lane*>(lua_touserdata(L, -1)); // lightuserdata (true 's_lane' pointer) / nil | 86 | Lane* const s{ lua_touserdata<Lane>(L, -1) }; // lightuserdata (true 's_lane' pointer) / nil |
87 | lua_pop( L, 1); | 87 | lua_pop( L, 1); |
88 | STACK_CHECK( L, 0); | 88 | STACK_CHECK( L, 0); |
89 | return s; | 89 | return s; |
diff --git a/src/linda.cpp b/src/linda.cpp index eb2349e..7e346d8 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
@@ -808,7 +808,7 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
808 | 808 | ||
809 | case eDO_delete: | 809 | case eDO_delete: |
810 | { | 810 | { |
811 | struct s_Linda* linda = (struct s_Linda*) lua_touserdata( L, 1); | 811 | struct s_Linda* const linda{ lua_touserdata<struct s_Linda>(L, 1) }; |
812 | ASSERT_L( linda); | 812 | ASSERT_L( linda); |
813 | 813 | ||
814 | // Clean associated structures in the keeper state. | 814 | // Clean associated structures in the keeper state. |
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index c549d72..370cbed 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h | |||
@@ -124,3 +124,10 @@ inline void STACK_GROW(lua_State* L, int n_) | |||
124 | } | 124 | } |
125 | 125 | ||
126 | #define LUAG_FUNC( func_name) int LG_##func_name( lua_State* L) | 126 | #define LUAG_FUNC( func_name) int LG_##func_name( lua_State* L) |
127 | |||
128 | // a small helper to extract a userdata pointer from the stack | ||
129 | template<typename T> | ||
130 | T* lua_touserdata(lua_State* L, int index_) | ||
131 | { | ||
132 | return static_cast<T*>(lua_touserdata(L, index_)); | ||
133 | } | ||
diff --git a/src/state.cpp b/src/state.cpp index 7bdaec9..b46a145 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
@@ -259,7 +259,7 @@ lua_State* create_state( Universe* U, lua_State* from_) | |||
259 | lua_pushcclosure( from_, U->provide_allocator, 0); | 259 | lua_pushcclosure( from_, U->provide_allocator, 0); |
260 | lua_call( from_, 0, 1); | 260 | lua_call( from_, 0, 1); |
261 | { | 261 | { |
262 | AllocatorDefinition* const def = (AllocatorDefinition*) lua_touserdata( from_, -1); | 262 | AllocatorDefinition* const def{ lua_touserdata<AllocatorDefinition>(from_, -1) }; |
263 | L = lua_newstate( def->m_allocF, def->m_allocUD); | 263 | L = lua_newstate( def->m_allocF, def->m_allocUD); |
264 | } | 264 | } |
265 | lua_pop( from_, 1); | 265 | lua_pop( from_, 1); |
diff --git a/src/universe.cpp b/src/universe.cpp index 4dd956d..095f000 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
@@ -67,7 +67,7 @@ Universe* universe_get(lua_State* L) | |||
67 | STACK_GROW(L, 2); | 67 | STACK_GROW(L, 2); |
68 | STACK_CHECK_START_REL(L, 0); | 68 | STACK_CHECK_START_REL(L, 0); |
69 | UNIVERSE_REGKEY.query_registry(L); | 69 | UNIVERSE_REGKEY.query_registry(L); |
70 | Universe* const universe = static_cast<Universe*>(lua_touserdata(L, -1)); // nullptr if nil | 70 | Universe* const universe{ lua_touserdata<Universe>(L, -1) }; // nullptr if nil |
71 | lua_pop(L, 1); | 71 | lua_pop(L, 1); |
72 | STACK_CHECK(L, 0); | 72 | STACK_CHECK(L, 0); |
73 | return universe; | 73 | return universe; |
diff --git a/src/universe.h b/src/universe.h index bb3ebdd..04c92ca 100644 --- a/src/universe.h +++ b/src/universe.h | |||
@@ -142,7 +142,7 @@ struct Universe | |||
142 | 142 | ||
143 | // Initialized by 'init_once_LOCKED()': the deep userdata Linda object | 143 | // Initialized by 'init_once_LOCKED()': the deep userdata Linda object |
144 | // used for timers (each lane will get a proxy to this) | 144 | // used for timers (each lane will get a proxy to this) |
145 | volatile DeepPrelude* timer_deep{ nullptr }; // = nullptr | 145 | DeepPrelude* timer_deep{ nullptr }; |
146 | 146 | ||
147 | #if HAVE_LANE_TRACKING() | 147 | #if HAVE_LANE_TRACKING() |
148 | std::mutex tracking_cs; | 148 | std::mutex tracking_cs; |