-
Notifications
You must be signed in to change notification settings - Fork 224
Use StringView and Span in Player #2293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 18 commits
797b8c2
d8f4c1d
28a1682
7459617
cacd559
c9f8ab5
713233f
7c807d4
b015bcc
82b8330
b4561af
5322ac0
2dd4993
0144971
7624fa5
0c74513
a22859e
e635250
4097688
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| #include <benchmark/benchmark.h> | ||
| #include <font.h> | ||
| #include <rect.h> | ||
| #include <bitmap.h> | ||
| #include <text.h> | ||
| #include <pixel_format.h> | ||
| #include <cache.h> | ||
|
|
||
| static void BM_ReplacePlaceholders(benchmark::State& state) { | ||
| for (auto _: state) { | ||
| Utils::ReplacePlaceholders("One night is %V %U", | ||
| Utils::MakeArray('V', 'U'), | ||
| Utils::MakeSvArray("Rest", "Do not Rest")); | ||
| } | ||
| } | ||
|
|
||
| BENCHMARK(BM_ReplacePlaceholders); | ||
|
|
||
| BENCHMARK_MAIN(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,29 +39,29 @@ | |
| using namespace std::chrono_literals; | ||
|
|
||
| namespace { | ||
| std::string MakeHashKey(const std::string& folder_name, const std::string& filename, bool transparent) { | ||
| return folder_name + ":" + filename + ":" + (transparent ? "T" : " "); | ||
| std::string MakeHashKey(StringView folder_name, StringView filename, bool transparent) { | ||
| return std::string(folder_name) + ":" + std::string(filename) + ":" + (transparent ? "T" : " "); | ||
|
||
| } | ||
|
|
||
| std::string MakeTileHashKey(const std::string& chipset_name, int id) { | ||
| std::string MakeTileHashKey(StringView chipset_name, int id) { | ||
| std::string key; | ||
| key.reserve(chipset_name.size() + sizeof(int) + 2); | ||
| key.append(reinterpret_cast<char*>(&id), sizeof(id)); | ||
| key.append(1, ':'); | ||
| key.append(chipset_name); | ||
| key.append(chipset_name.begin(), chipset_name.end()); | ||
|
|
||
| return key; | ||
| } | ||
|
|
||
| int IdFromTileHash(const std::string& key) { | ||
| int IdFromTileHash(StringView key) { | ||
| int id = 0; | ||
| if (key.size() > sizeof(id)) { | ||
| std::memcpy(&id, key.data(), sizeof(id)); | ||
| } | ||
| return id; | ||
| } | ||
|
|
||
| const char* NameFromTileHash(const std::string& key) { | ||
| const char* NameFromTileHash(StringView key) { | ||
| int offset = sizeof(int) + 1; | ||
| if (static_cast<int>(key.size()) < offset) { | ||
| return ""; | ||
|
|
@@ -132,14 +132,15 @@ namespace { | |
| return (cache[key] = {bmp, Game_Clock::GetFrameTime()}).bitmap; | ||
| } | ||
|
|
||
| BitmapRef LoadBitmap(const std::string& folder_name, const std::string& filename, | ||
| BitmapRef LoadBitmap(StringView folder_name, StringView filename, | ||
| bool transparent, const uint32_t flags) { | ||
| const auto key = MakeHashKey(folder_name, filename, transparent); | ||
|
|
||
| auto it = cache.find(key); | ||
|
|
||
| if (it == cache.end()) { | ||
| const std::string path = FileFinder::FindImage(folder_name, filename); | ||
| // FIXME: STRING_VIEW string copies here | ||
| const std::string path = FileFinder::FindImage(std::string(folder_name), std::string(filename)); | ||
|
|
||
| BitmapRef bmp = BitmapRef(); | ||
|
|
||
|
|
@@ -249,7 +250,7 @@ namespace { | |
| } | ||
|
|
||
| template<Material::Type T> | ||
| BitmapRef LoadDummyBitmap(const std::string& folder_name, const std::string& filename, bool transparent) { | ||
| BitmapRef LoadDummyBitmap(StringView folder_name, StringView filename, bool transparent) { | ||
| static_assert(Material::REND < T && T < Material::END, "Invalid material."); | ||
|
|
||
| const Spec& s = spec[T]; | ||
|
|
@@ -271,7 +272,7 @@ namespace { | |
| } | ||
|
|
||
| template<Material::Type T> | ||
| BitmapRef LoadBitmap(const std::string& f, bool transparent) { | ||
| BitmapRef LoadBitmap(StringView f, bool transparent) { | ||
| static_assert(Material::REND < T && T < Material::END, "Invalid material."); | ||
|
|
||
| const Spec& s = spec[T]; | ||
|
|
@@ -320,7 +321,7 @@ namespace { | |
| } | ||
|
|
||
| template<Material::Type T> | ||
| BitmapRef LoadBitmap(const std::string& f) { | ||
| BitmapRef LoadBitmap(StringView f) { | ||
| static_assert(Material::REND < T && T < Material::END, "Invalid material."); | ||
|
|
||
| const Spec& s = spec[T]; | ||
|
|
@@ -331,67 +332,67 @@ namespace { | |
|
|
||
| std::vector<uint8_t> Cache::exfont_custom; | ||
|
|
||
| BitmapRef Cache::Backdrop(const std::string& file) { | ||
| BitmapRef Cache::Backdrop(StringView file) { | ||
| return LoadBitmap<Material::Backdrop>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Battle(const std::string& file) { | ||
| BitmapRef Cache::Battle(StringView file) { | ||
| return LoadBitmap<Material::Battle>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Battle2(const std::string& file) { | ||
| BitmapRef Cache::Battle2(StringView file) { | ||
| return LoadBitmap<Material::Battle2>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Battlecharset(const std::string& file) { | ||
| BitmapRef Cache::Battlecharset(StringView file) { | ||
| return LoadBitmap<Material::Battlecharset>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Battleweapon(const std::string& file) { | ||
| BitmapRef Cache::Battleweapon(StringView file) { | ||
| return LoadBitmap<Material::Battleweapon>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Charset(const std::string& file) { | ||
| BitmapRef Cache::Charset(StringView file) { | ||
| return LoadBitmap<Material::Charset>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Chipset(const std::string& file) { | ||
| BitmapRef Cache::Chipset(StringView file) { | ||
| return LoadBitmap<Material::Chipset>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Faceset(const std::string& file) { | ||
| BitmapRef Cache::Faceset(StringView file) { | ||
| return LoadBitmap<Material::Faceset>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Frame(const std::string& file, bool transparent) { | ||
| BitmapRef Cache::Frame(StringView file, bool transparent) { | ||
| return LoadBitmap<Material::Frame>(file, transparent); | ||
| } | ||
|
|
||
| BitmapRef Cache::Gameover(const std::string& file) { | ||
| BitmapRef Cache::Gameover(StringView file) { | ||
| return LoadBitmap<Material::Gameover>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Monster(const std::string& file) { | ||
| BitmapRef Cache::Monster(StringView file) { | ||
| return LoadBitmap<Material::Monster>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Panorama(const std::string& file) { | ||
| BitmapRef Cache::Panorama(StringView file) { | ||
| return LoadBitmap<Material::Panorama>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Picture(const std::string& file, bool transparent) { | ||
| BitmapRef Cache::Picture(StringView file, bool transparent) { | ||
| return LoadBitmap<Material::Picture>(file, transparent); | ||
| } | ||
|
|
||
| BitmapRef Cache::System2(const std::string& file) { | ||
| BitmapRef Cache::System2(StringView file) { | ||
| return LoadBitmap<Material::System2>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::Title(const std::string& file) { | ||
| BitmapRef Cache::Title(StringView file) { | ||
| return LoadBitmap<Material::Title>(file); | ||
| } | ||
|
|
||
| BitmapRef Cache::System(const std::string& file) { | ||
| BitmapRef Cache::System(StringView file) { | ||
| return LoadBitmap<Material::System>(file); | ||
| } | ||
|
|
||
|
|
@@ -419,7 +420,7 @@ BitmapRef Cache::Exfont() { | |
| } | ||
| } | ||
|
|
||
| BitmapRef Cache::Tile(const std::string& filename, int tile_id) { | ||
| BitmapRef Cache::Tile(StringView filename, int tile_id) { | ||
| const auto key = MakeTileHashKey(filename, tile_id); | ||
| auto it = cache_tiles.find(key); | ||
|
|
||
|
|
@@ -519,12 +520,12 @@ void Cache::Clear() { | |
| cache_tiles.clear(); | ||
| } | ||
|
|
||
| void Cache::SetSystemName(std::string const& filename) { | ||
| system_name = filename; | ||
| void Cache::SetSystemName(std::string filename) { | ||
| system_name = std::move(filename); | ||
| } | ||
|
|
||
| void Cache::SetSystem2Name(std::string const& filename) { | ||
| system2_name = filename; | ||
| void Cache::SetSystem2Name(std::string filename) { | ||
| system2_name = std::move(filename); | ||
| } | ||
|
|
||
| BitmapRef Cache::System() { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: So, a string view is always used when the target function does not take ownership on the string?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish I could tell you yes, replace all
const std::string&withStringView. Unfortunately this is C++ so there is always one big caveat.StringViewis not null terminated, so if at the end of your call stack you end up calling a C library which requires null terminatedconst char*, you'll end up having to make a copy so you can get a new string with a null byte at the end.Aside from that caveat, yes use
StringViewwhere-ever you need a non-owning reference. Not only is it a generic adapter but the calling convention used is faster (see below).Spandoes not have this caveat, fortunately so you can use it anywhere you'd pass a vector by reference.Performance Note
const string&if you think about it in C terms, is essentially a double pointerconst char**. The reference is a pointer to the string object, which contains another pointer to the bytes.When you pass a
StringViewyou're passing aconst char*, removing one level of indirection. In some cases this can help the optimizer with it's aliasing analysis to produce faster code.The same rule applies to
vectorandSpan.