aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-05-20 17:52:04 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-05-20 17:52:04 +0200
commite17ab4ffe5b675b0163368cd893d2e703c874675 (patch)
treed147a9d6139b18e8ae75ed4741fbff42b124c7fc /src
parenteb090da027012292e8856dc01856cde8880d3467 (diff)
downloadlanes-e17ab4ffe5b675b0163368cd893d2e703c874675.tar.gz
lanes-e17ab4ffe5b675b0163368cd893d2e703c874675.tar.bz2
lanes-e17ab4ffe5b675b0163368cd893d2e703c874675.zip
Use string_view for Linda names
Diffstat (limited to 'src')
-rw-r--r--src/linda.cpp55
-rw-r--r--src/linda.h14
-rw-r--r--src/lindafactory.cpp2
3 files changed, 37 insertions, 34 deletions
diff --git a/src/linda.cpp b/src/linda.cpp
index 48da1cf..1916629 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -79,10 +79,11 @@ template <bool OPT>
79{ 79{
80 Linda* const _linda{ ToLinda<OPT>(L_, idx_) }; 80 Linda* const _linda{ ToLinda<OPT>(L_, idx_) };
81 if (_linda != nullptr) { 81 if (_linda != nullptr) {
82 std::string_view const _lindaName{ _linda->getName() };
82 char _text[128]; 83 char _text[128];
83 int _len; 84 int _len;
84 if (_linda->getName()) 85 if (!_lindaName.empty())
85 _len = sprintf(_text, "Linda: %.*s", (int) sizeof(_text) - 8, _linda->getName()); 86 _len = sprintf(_text, "Linda: %.*s", (int) sizeof(_text) - 8, _lindaName.data());
86 else 87 else
87 _len = sprintf(_text, "Linda: %p", _linda); 88 _len = sprintf(_text, "Linda: %p", _linda);
88 lua_pushlstring(L_, _text, _len); 89 lua_pushlstring(L_, _text, _len);
@@ -113,37 +114,37 @@ template <bool OPT>
113// have to cast to unsigned long to avoid compilation warnings about loss of data when converting pointer-to-integer 114// have to cast to unsigned long to avoid compilation warnings about loss of data when converting pointer-to-integer
114static constexpr uintptr_t kPointerMagicShift{ 3 }; 115static constexpr uintptr_t kPointerMagicShift{ 3 };
115 116
116Linda::Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_) 117Linda::Linda(Universe* U_, LindaGroup group_, std::string_view const& name_)
117: DeepPrelude{ LindaFactory::Instance } 118: DeepPrelude{ LindaFactory::Instance }
118, U{ U_ } 119, U{ U_ }
119, keeperIndex{ (group_ ? group_ : static_cast<int>(std::bit_cast<uintptr_t>(this) >> kPointerMagicShift)) % U_->keepers->nb_keepers } 120, keeperIndex{ (group_ ? group_ : static_cast<int>(std::bit_cast<uintptr_t>(this) >> kPointerMagicShift)) % U_->keepers->nb_keepers }
120{ 121{
121 setName(name_, len_); 122 setName(name_);
122} 123}
123 124
124// ################################################################################################# 125// #################################################################################################
125 126
126Linda::~Linda() 127Linda::~Linda()
127{ 128{
128 if (std::holds_alternative<AllocatedName>(nameVariant)) { 129 if (std::holds_alternative<std::string_view>(nameVariant)) {
129 AllocatedName& _name = std::get<AllocatedName>(nameVariant); 130 std::string_view& _name = std::get<std::string_view>(nameVariant);
130 U->internalAllocator.free(_name.name, _name.len); 131 U->internalAllocator.free(const_cast<char*>(_name.data()), _name.size());
131 } 132 }
132} 133}
133 134
134// ################################################################################################# 135// #################################################################################################
135 136
136char const* Linda::getName() const 137std::string_view Linda::getName() const
137{ 138{
138 if (std::holds_alternative<AllocatedName>(nameVariant)) { 139 if (std::holds_alternative<std::string_view>(nameVariant)) {
139 AllocatedName const& _name = std::get<AllocatedName>(nameVariant); 140 std::string_view const& _name = std::get<std::string_view>(nameVariant);
140 return _name.name; 141 return _name;
141 } 142 }
142 if (std::holds_alternative<EmbeddedName>(nameVariant)) { 143 if (std::holds_alternative<EmbeddedName>(nameVariant)) {
143 char const* const _name{ std::get<EmbeddedName>(nameVariant).data() }; 144 char const* const _name{ std::get<EmbeddedName>(nameVariant).data() };
144 return _name; 145 return std::string_view{ _name, strlen(_name) };
145 } 146 }
146 return nullptr; 147 return std::string_view{};
147} 148}
148 149
149// ################################################################################################# 150// #################################################################################################
@@ -182,22 +183,28 @@ int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_)
182 183
183// ################################################################################################# 184// #################################################################################################
184 185
185void Linda::setName(char const* name_, size_t len_) 186void Linda::setName(std::string_view const& name_)
186{ 187{
187 // keep default 188 // keep default
188 if (!name_ || len_ == 0) { 189 if (name_.empty()) {
189 return; 190 return;
190 } 191 }
191 ++len_; // don't forget terminating 0 192 size_t const _lenWithTZ{ name_.size() + 1 }; // don't forget terminating 0
192 if (len_ < kEmbeddedNameLength) { 193 if (_lenWithTZ < kEmbeddedNameLength) {
193 nameVariant.emplace<EmbeddedName>(); 194 // grab our internal buffer
194 char* const _name{ std::get<EmbeddedName>(nameVariant).data() }; 195 EmbeddedName& _name = nameVariant.emplace<EmbeddedName>();
195 memcpy(_name, name_, len_); 196 // copy the string in it
197 memcpy(_name.data(), name_.data(), name_.size());
198 // don't forget terminating 0
199 _name[_lenWithTZ] = 0;
196 } else { 200 } else {
197 AllocatedName& _name = std::get<AllocatedName>(nameVariant); 201 // allocate an external buffer
198 _name.name = static_cast<char*>(U->internalAllocator.alloc(len_)); 202 char* const _nameBuffer{ static_cast<char*>(U->internalAllocator.alloc(_lenWithTZ)) };
199 _name.len = len_; 203 // copy the string in it
200 memcpy(_name.name, name_, len_); 204 memcpy(_nameBuffer, name_.data(), name_.size());
205 // don't forget terminating 0
206 _nameBuffer[_lenWithTZ] = 0;
207 nameVariant.emplace<std::string_view>(_nameBuffer, name_.size());
201 } 208 }
202} 209}
203 210
diff --git a/src/linda.h b/src/linda.h
index 4943197..611008e 100644
--- a/src/linda.h
+++ b/src/linda.h
@@ -7,6 +7,7 @@
7 7
8#include <array> 8#include <array>
9#include <condition_variable> 9#include <condition_variable>
10#include <string_view>
10#include <variant> 11#include <variant>
11 12
12struct Keeper; 13struct Keeper;
@@ -26,13 +27,8 @@ class Linda
26 private: 27 private:
27 static constexpr size_t kEmbeddedNameLength = 24; 28 static constexpr size_t kEmbeddedNameLength = 24;
28 using EmbeddedName = std::array<char, kEmbeddedNameLength>; 29 using EmbeddedName = std::array<char, kEmbeddedNameLength>;
29 struct AllocatedName
30 {
31 size_t len{ 0 };
32 char* name{ nullptr };
33 };
34 // depending on the name length, it is either embedded inside the Linda, or allocated separately 30 // depending on the name length, it is either embedded inside the Linda, or allocated separately
35 std::variant<AllocatedName, EmbeddedName> nameVariant; 31 std::variant<std::string_view, EmbeddedName> nameVariant;
36 32
37 public: 33 public:
38 std::condition_variable readHappened; 34 std::condition_variable readHappened;
@@ -51,7 +47,7 @@ class Linda
51 static void operator delete(void* p_) { static_cast<Linda*>(p_)->U->internalAllocator.free(p_, sizeof(Linda)); } 47 static void operator delete(void* p_) { static_cast<Linda*>(p_)->U->internalAllocator.free(p_, sizeof(Linda)); }
52 48
53 ~Linda(); 49 ~Linda();
54 Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_); 50 Linda(Universe* U_, LindaGroup group_, std::string_view const& name_);
55 Linda() = delete; 51 Linda() = delete;
56 // non-copyable, non-movable 52 // non-copyable, non-movable
57 Linda(Linda const&) = delete; 53 Linda(Linda const&) = delete;
@@ -60,11 +56,11 @@ class Linda
60 Linda& operator=(Linda const&&) = delete; 56 Linda& operator=(Linda const&&) = delete;
61 57
62 private: 58 private:
63 void setName(char const* name_, size_t len_); 59 void setName(std::string_view const& name_);
64 60
65 public: 61 public:
66 [[nodiscard]] Keeper* acquireKeeper() const; 62 [[nodiscard]] Keeper* acquireKeeper() const;
67 [[nodiscard]] char const* getName() const; 63 [[nodiscard]] std::string_view getName() const;
68 void releaseKeeper(Keeper* keeper_) const; 64 void releaseKeeper(Keeper* keeper_) const;
69 [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_); 65 [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_);
70 [[nodiscard]] Keeper* whichKeeper() const { return U->keepers->nb_keepers ? &U->keepers->keeper_array[keeperIndex] : nullptr; } 66 [[nodiscard]] Keeper* whichKeeper() const { return U->keepers->nb_keepers ? &U->keepers->keeper_array[keeperIndex] : nullptr; }
diff --git a/src/lindafactory.cpp b/src/lindafactory.cpp
index 015baf4..890cc96 100644
--- a/src/lindafactory.cpp
+++ b/src/lindafactory.cpp
@@ -127,6 +127,6 @@ DeepPrelude* LindaFactory::newDeepObjectInternal(lua_State* L_) const
127 // The deep data is allocated separately of Lua stack; we might no longer be around when last reference to it is being released. 127 // The deep data is allocated separately of Lua stack; we might no longer be around when last reference to it is being released.
128 // One can use any memory allocation scheme. Just don't use L's allocF because we don't know which state will get the honor of GCing the linda 128 // One can use any memory allocation scheme. Just don't use L's allocF because we don't know which state will get the honor of GCing the linda
129 Universe* const _U{ universe_get(L_) }; 129 Universe* const _U{ universe_get(L_) };
130 Linda* const _linda{ new (_U) Linda{ _U, _linda_group, _linda_name.data(), _linda_name.size() } }; 130 Linda* const _linda{ new (_U) Linda{ _U, _linda_group, _linda_name } };
131 return _linda; 131 return _linda;
132} 132}