Skip to content

Commit 73b4daa

Browse files
authored
Moved two hashmaps from run-time to compile-time, replaced a vector with a constexpr array (#121)
1 parent bbe0d31 commit 73b4daa

File tree

2 files changed

+46
-44
lines changed

2 files changed

+46
-44
lines changed

Source/NimbleCommander/NimbleCommander/Core/ActionsShortcutsManager.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2014-2023 Michael Kazakov. Subject to GNU General Public License version 3.
1+
// Copyright (C) 2014-2024 Michael Kazakov. Subject to GNU General Public License version 3.
22
#pragma once
33

44
// ⇧ - NSShiftKeyMask
@@ -33,7 +33,7 @@ class ActionsShortcutsManager : nc::base::ObservableBase
3333
/**
3434
* return "" on if action corresponing _tag wasn't found.
3535
*/
36-
std::string ActionFromTag(int _tag) const;
36+
std::string_view ActionFromTag(int _tag) const noexcept;
3737

3838
/**
3939
* Return default if can't be found.
@@ -54,7 +54,7 @@ class ActionsShortcutsManager : nc::base::ObservableBase
5454

5555
void RevertToDefaults();
5656

57-
bool SetShortCutOverride(const std::string &_action, const ShortCut &_sc);
57+
bool SetShortCutOverride(std::string_view _action, const ShortCut &_sc);
5858

5959
void SetMenuShortCuts(NSMenu *_menu) const;
6060

@@ -70,12 +70,6 @@ class ActionsShortcutsManager : nc::base::ObservableBase
7070
void ReadOverrideFromConfig();
7171
void WriteOverridesToConfig() const;
7272

73-
robin_hood::unordered_flat_map<int, const char *> m_TagToAction;
74-
robin_hood::unordered_flat_map<std::string,
75-
int,
76-
nc::RHTransparentStringHashEqual,
77-
nc::RHTransparentStringHashEqual>
78-
m_ActionToTag;
7973
robin_hood::unordered_flat_map<int, ShortCut> m_ShortCutsDefaults;
8074
robin_hood::unordered_flat_map<int, ShortCut> m_ShortCutsOverrides;
8175
};

Source/NimbleCommander/NimbleCommander/Core/ActionsShortcutsManager.mm

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
#include <Config/RapidJSON.h>
44
#include "ActionsShortcutsManager.h"
55
#include <assert.h>
6+
#include <frozen/unordered_map.h>
7+
#include <frozen/string.h>
68

79
// this key should not exist in config defaults
810
static const auto g_OverridesConfigPath = "hotkeyOverrides_v1";
911

1012
// clang-format off
1113
// the persistance holy grail is below, change ids only in emergency case:
12-
[[clang::no_destroy]] static const std::vector<std::pair<const char*,int>> g_ActionsTags = {
14+
static constexpr std::pair<const char*,int> g_ActionsTags[] = {
1315
{"menu.nimble_commander.about", 10'000},
1416
{"menu.nimble_commander.preferences", 10'010},
1517
{"menu.nimble_commander.hide", 10'020},
@@ -213,19 +215,19 @@
213215
{"viewer.refresh", 101'005}
214216
};
215217

216-
[[clang::no_destroy]] static const std::vector<std::pair<const char*, const char8_t*>> g_DefaultShortcuts = {
218+
static constinit std::pair<const char*, const char8_t*> g_DefaultShortcuts[] = {
217219
{"menu.nimble_commander.about", u8"" },
218220
{"menu.nimble_commander.preferences", u8"⌘," }, // cmd+,
219221
{"menu.nimble_commander.toggle_admin_mode", u8"" },
220222
{"menu.nimble_commander.hide", u8"⌘h" }, // cmd+h
221223
{"menu.nimble_commander.hide_others", u8"⌥⌘h" }, // cmd+alt+h
222224
{"menu.nimble_commander.show_all", u8"" },
223225
{"menu.nimble_commander.quit", u8"⌘q" }, // cmd+q
224-
{"menu.nimble_commander.active_license_file", u8"" },
225-
{"menu.nimble_commander.purchase_license", u8"" },
226-
{"menu.nimble_commander.purchase_pro_features", u8"" },
227-
{"menu.nimble_commander.restore_purchases", u8"" },
228-
{"menu.nimble_commander.registration_info", u8"" },
226+
{"menu.nimble_commander.active_license_file", u8"" }, // no longer used
227+
{"menu.nimble_commander.purchase_license", u8"" }, // no longer used
228+
{"menu.nimble_commander.purchase_pro_features", u8"" }, // no longer used
229+
{"menu.nimble_commander.restore_purchases", u8"" }, // no longer used
230+
{"menu.nimble_commander.registration_info", u8"" }, // no longer used
229231

230232
{"menu.file.newwindow", u8"⌘n" }, // cmd+n
231233
{"menu.file.new_folder", u8"⇧⌘n" }, // cmd+shift+n
@@ -410,6 +412,22 @@
410412
};
411413
// clang-format on
412414

415+
static constinit const auto g_ActionToTag = [] {
416+
std::pair<frozen::string, int> items[std::size(g_ActionsTags)] = {
417+
[0 ... std::size(g_ActionsTags) - 1] = {frozen::string(""), 0}};
418+
for( size_t i = 0; i < std::size(g_ActionsTags); ++i )
419+
items[i] = std::pair<frozen::string, int>(g_ActionsTags[i].first, g_ActionsTags[i].second);
420+
return frozen::make_unordered_map(items);
421+
}();
422+
423+
static constinit const auto g_TagToAction = [] {
424+
std::pair<int, frozen::string> items[std::size(g_ActionsTags)] = {
425+
[0 ... std::size(g_ActionsTags) - 1] = {0, frozen::string("")}};
426+
for( size_t i = 0; i < std::size(g_ActionsTags); ++i )
427+
items[i] = std::pair<int, frozen::string>(g_ActionsTags[i].second, g_ActionsTags[i].first);
428+
return frozen::make_unordered_map(items);
429+
}();
430+
413431
ActionsShortcutsManager::ShortCutsUpdater::ShortCutsUpdater(std::span<const UpdateTarget> _targets)
414432
{
415433
auto &am = ActionsShortcutsManager::Instance();
@@ -430,19 +448,15 @@
430448

431449
ActionsShortcutsManager::ActionsShortcutsManager()
432450
{
433-
for( auto &p : g_ActionsTags ) {
434-
// safety checks against malformed g_ActionsTags
435-
assert(m_TagToAction.count(p.second) == 0);
436-
assert(m_ActionToTag.count(p.first) == 0);
437-
438-
m_TagToAction[p.second] = p.first;
439-
m_ActionToTag[p.first] = p.second;
440-
}
451+
// safety checks against malformed g_ActionsTags, only in Debug builds
452+
assert(
453+
(robin_hood::unordered_map<std::string_view, int>{std::begin(g_ActionsTags), std::end(g_ActionsTags)}).size() ==
454+
std::size(g_ActionsTags));
441455

442456
for( auto &d : g_DefaultShortcuts ) {
443-
auto i = m_ActionToTag.find(d.first);
444-
if( i != end(m_ActionToTag) )
445-
m_ShortCutsDefaults[i->second] = nc::utility::ActionShortcut{d.second};
457+
auto i = g_ActionToTag.find(std::string_view{d.first});
458+
if( i != g_ActionToTag.end() )
459+
m_ShortCutsDefaults[i->second] = nc::utility::ActionShortcut{d.second};
446460
}
447461

448462
ReadOverrideFromConfig();
@@ -456,18 +470,14 @@
456470

457471
int ActionsShortcutsManager::TagFromAction(std::string_view _action) const noexcept
458472
{
459-
auto it = m_ActionToTag.find(_action);
460-
if( it != std::end(m_ActionToTag) )
461-
return it->second;
462-
return -1;
473+
const auto it = g_ActionToTag.find(_action);
474+
return it == g_ActionToTag.end() ? -1 : it->second;
463475
}
464476

465-
std::string ActionsShortcutsManager::ActionFromTag(int _tag) const
477+
std::string_view ActionsShortcutsManager::ActionFromTag(int _tag) const noexcept
466478
{
467-
auto it = m_TagToAction.find(_tag);
468-
if( it != end(m_TagToAction) )
469-
return it->second;
470-
return "";
479+
const auto it = g_TagToAction.find(_tag);
480+
return it == g_TagToAction.end() ? "" : std::string_view{it->second.data(), it->second.size()};
471481
}
472482

473483
void ActionsShortcutsManager::SetMenuShortCuts(NSMenu *_menu) const
@@ -488,7 +498,7 @@
488498
if( sc != m_ShortCutsDefaults.end() ) {
489499
[i nc_setKeyEquivalentWithShortcut:sc->second];
490500
}
491-
else if( m_TagToAction.find(tag) != m_TagToAction.end() ) {
501+
else if( g_TagToAction.find(tag) != g_TagToAction.end() ) {
492502
[i nc_setKeyEquivalentWithShortcut:nc::utility::ActionShortcut{}];
493503
}
494504
}
@@ -507,14 +517,13 @@
507517
m_ShortCutsOverrides.clear();
508518
for( auto i = v.MemberBegin(), e = v.MemberEnd(); i != e; ++i )
509519
if( i->name.GetType() == kStringType && i->value.GetType() == kStringType ) {
510-
auto att = m_ActionToTag.find(i->name.GetString());
511-
if( att != m_ActionToTag.end() )
520+
auto att = g_ActionToTag.find(std::string_view{i->name.GetString()});
521+
if( att != g_ActionToTag.end() )
512522
m_ShortCutsOverrides[att->second] = nc::utility::ActionShortcut{i->value.GetString()};
513523
}
514524
}
515525

516-
ActionsShortcutsManager::ShortCut
517-
ActionsShortcutsManager::ShortCutFromAction(std::string_view _action) const noexcept
526+
ActionsShortcutsManager::ShortCut ActionsShortcutsManager::ShortCutFromAction(std::string_view _action) const noexcept
518527
{
519528
int tag = TagFromAction(_action);
520529
if( tag <= 0 )
@@ -544,7 +553,7 @@
544553
return {};
545554
}
546555

547-
bool ActionsShortcutsManager::SetShortCutOverride(const std::string &_action, const ShortCut &_sc)
556+
bool ActionsShortcutsManager::SetShortCutOverride(const std::string_view _action, const ShortCut &_sc)
548557
{
549558
const auto tag = TagFromAction(_action);
550559
if( tag <= 0 )
@@ -605,8 +614,7 @@
605614
return g_ActionsTags;
606615
}
607616

608-
ActionsShortcutsManager::ObservationTicket
609-
ActionsShortcutsManager::ObserveChanges(std::function<void()> _callback)
617+
ActionsShortcutsManager::ObservationTicket ActionsShortcutsManager::ObserveChanges(std::function<void()> _callback)
610618
{
611619
return ObservableBase::AddObserver(_callback);
612620
}

0 commit comments

Comments
 (0)