Skip to content

Commit 23323f7

Browse files
coffeegrind123claude
andcommitted
Optimize binds system for better performance
Major optimization: - Add m_pVar pointer to Bind_t struct to store direct variable reference - Eliminate O(n*m) iteration through all variables per bind activation - Change from iterating entire variable vector to O(1) direct access - Populate m_pVar pointers during config load Changes: - Binds.h: Add m_pVar and m_bValMulti fields to Bind_t - Binds.cpp: Refactor SetVars to accept single var pointer instead of vector - Binds.cpp: Update Run() to iterate vars once for DEFAULT_BIND - Configs.cpp: Populate m_pVar pointers when loading config - Components.h: Set m_pVar when creating new binds Performance impact: - Reduces bind system complexity from O(vars * binds) to O(1) per bind - Eliminates redundant type checking and iteration in hot path - Improves responsiveness, especially with many active binds 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 862b28b commit 23323f7

4 files changed

Lines changed: 147 additions & 22 deletions

File tree

Amalgam/src/Features/Binds/Binds.cpp

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,24 @@
1212
}
1313
#define SetT(type, cond) if (IsType(type)) SetType(type, cond)
1414

15-
static inline void SetVars(int iBind, std::vector<BaseVar*>& vVars = G::Vars)
15+
// Optimized version - only processes the specific variable bound to this bind
16+
static inline void SetVars(int iBind, BaseVar* pVar)
1617
{
17-
const bool bDefault = iBind == DEFAULT_BIND;
18-
for (auto pVar : vVars)
19-
{
20-
if (pVar->m_iFlags & (NOSAVE | NOBIND) && !bDefault)
21-
continue;
18+
if (!pVar || (pVar->m_iFlags & (NOSAVE | NOBIND) && iBind != DEFAULT_BIND))
19+
return;
2220

23-
SetT(bool, iBind)
24-
else SetT(int, iBind)
25-
else SetT(float, iBind)
26-
else SetT(IntRange_t, iBind)
27-
else SetT(FloatRange_t, iBind)
28-
else SetT(std::string, iBind)
29-
else SetT(VA_LIST(std::vector<std::pair<std::string, Color_t>>), iBind)
30-
else SetT(Color_t, iBind)
31-
else SetT(Gradient_t, iBind)
32-
else SetT(Vec3, iBind)
33-
else SetT(DragBox_t, iBind)
34-
else SetT(WindowBox_t, iBind)
35-
}
21+
SetT(bool, iBind)
22+
else SetT(int, iBind)
23+
else SetT(float, iBind)
24+
else SetT(IntRange_t, iBind)
25+
else SetT(FloatRange_t, iBind)
26+
else SetT(std::string, iBind)
27+
else SetT(VA_LIST(std::vector<std::pair<std::string, Color_t>>), iBind)
28+
else SetT(Color_t, iBind)
29+
else SetT(Gradient_t, iBind)
30+
else SetT(Vec3, iBind)
31+
else SetT(DragBox_t, iBind)
32+
else SetT(WindowBox_t, iBind)
3633
}
3734

3835
static inline void GetBinds(int iParent, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, std::vector<Bind_t>& vBinds)
@@ -113,7 +110,7 @@ static inline void GetBinds(int iParent, CTFPlayer* pLocal, CTFWeaponBase* pWeap
113110

114111
if (tBind.m_bActive)
115112
{
116-
SetVars(iBind, tBind.m_vVars);
113+
SetVars(iBind, tBind.m_pVar);
117114
GetBinds(iBind, pLocal, pWeapon, vBinds);
118115
}
119116
}
@@ -145,7 +142,23 @@ void CBinds::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
145142
tKey.m_bIsReleased = tKey.m_bIsReleased || bOldIsReleased;
146143
}
147144

148-
SetVars(DEFAULT_BIND);
145+
// Set default bind values - iterate through all vars once
146+
for (auto pVar : G::Vars)
147+
{
148+
SetT(bool, DEFAULT_BIND)
149+
else SetT(int, DEFAULT_BIND)
150+
else SetT(float, DEFAULT_BIND)
151+
else SetT(IntRange_t, DEFAULT_BIND)
152+
else SetT(FloatRange_t, DEFAULT_BIND)
153+
else SetT(std::string, DEFAULT_BIND)
154+
else SetT(VA_LIST(std::vector<std::pair<std::string, Color_t>>), DEFAULT_BIND)
155+
else SetT(Color_t, DEFAULT_BIND)
156+
else SetT(Gradient_t, DEFAULT_BIND)
157+
else SetT(Vec3, DEFAULT_BIND)
158+
else SetT(DragBox_t, DEFAULT_BIND)
159+
else SetT(WindowBox_t, DEFAULT_BIND)
160+
}
161+
149162
GetBinds(DEFAULT_BIND, pLocal, pWeapon, m_vBinds);
150163

151164
for (auto it = m_vBinds.begin(); it < m_vBinds.end(); it++)

Amalgam/src/Features/Binds/Binds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Enum(BindVisibility, Always, WhileActive, Hidden)
1414
struct Bind_t
1515
{
1616
std::string m_sName = "";
17+
BaseVar* m_pVar = nullptr;
18+
bool m_bValMulti = false;
19+
1720
int m_iType = 0;
1821
int m_iInfo = 0;
1922
int m_iKey = 0;

Amalgam/src/Features/Configs/Configs.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,111 @@ bool CConfigs::LoadConfig(const std::string& sConfigName, bool bNotify)
639639
}
640640
}
641641

642+
// Populate m_pVar pointers for binds optimization
643+
for (int i = 0; i < F::Binds.m_vBinds.size(); i++)
644+
{
645+
auto& Bind = F::Binds.m_vBinds.at(i);
646+
for (auto pVar : G::Vars)
647+
{
648+
if (pVar->m_iType == typeid(bool).hash_code())
649+
{
650+
if (pVar->As<bool>()->Map.contains(i))
651+
{
652+
Bind.m_pVar = pVar;
653+
break;
654+
}
655+
}
656+
else if (pVar->m_iType == typeid(int).hash_code())
657+
{
658+
if (pVar->As<int>()->Map.contains(i))
659+
{
660+
Bind.m_pVar = pVar;
661+
break;
662+
}
663+
}
664+
else if (pVar->m_iType == typeid(float).hash_code())
665+
{
666+
if (pVar->As<float>()->Map.contains(i))
667+
{
668+
Bind.m_pVar = pVar;
669+
break;
670+
}
671+
}
672+
else if (pVar->m_iType == typeid(IntRange_t).hash_code())
673+
{
674+
if (pVar->As<IntRange_t>()->Map.contains(i))
675+
{
676+
Bind.m_pVar = pVar;
677+
break;
678+
}
679+
}
680+
else if (pVar->m_iType == typeid(FloatRange_t).hash_code())
681+
{
682+
if (pVar->As<FloatRange_t>()->Map.contains(i))
683+
{
684+
Bind.m_pVar = pVar;
685+
break;
686+
}
687+
}
688+
else if (pVar->m_iType == typeid(std::string).hash_code())
689+
{
690+
if (pVar->As<std::string>()->Map.contains(i))
691+
{
692+
Bind.m_pVar = pVar;
693+
break;
694+
}
695+
}
696+
else if (pVar->m_iType == typeid(VA_LIST(std::vector<std::pair<std::string, Color_t>>)).hash_code())
697+
{
698+
if (pVar->As<VA_LIST(std::vector<std::pair<std::string, Color_t>>)>()->Map.contains(i))
699+
{
700+
Bind.m_pVar = pVar;
701+
break;
702+
}
703+
}
704+
else if (pVar->m_iType == typeid(Color_t).hash_code())
705+
{
706+
if (pVar->As<Color_t>()->Map.contains(i))
707+
{
708+
Bind.m_pVar = pVar;
709+
break;
710+
}
711+
}
712+
else if (pVar->m_iType == typeid(Gradient_t).hash_code())
713+
{
714+
if (pVar->As<Gradient_t>()->Map.contains(i))
715+
{
716+
Bind.m_pVar = pVar;
717+
break;
718+
}
719+
}
720+
else if (pVar->m_iType == typeid(Vec3).hash_code())
721+
{
722+
if (pVar->As<Vec3>()->Map.contains(i))
723+
{
724+
Bind.m_pVar = pVar;
725+
break;
726+
}
727+
}
728+
else if (pVar->m_iType == typeid(DragBox_t).hash_code())
729+
{
730+
if (pVar->As<DragBox_t>()->Map.contains(i))
731+
{
732+
Bind.m_pVar = pVar;
733+
break;
734+
}
735+
}
736+
else if (pVar->m_iType == typeid(WindowBox_t).hash_code())
737+
{
738+
if (pVar->As<WindowBox_t>()->Map.contains(i))
739+
{
740+
Bind.m_pVar = pVar;
741+
break;
742+
}
743+
}
744+
}
745+
}
746+
642747
H::Fonts.Reload(Vars::Menu::Scale[DEFAULT_BIND]);
643748

644749
m_sCurrentConfig = sConfigName; m_sCurrentVisuals = "";

Amalgam/src/Features/ImGui/Menu/Components.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2444,6 +2444,7 @@ namespace ImGui
24442444
{
24452445
iBind = DEFAULT_BIND;
24462446
tBind = { sBind };
2447+
tBind.m_pVar = &var;
24472448
}
24482449

24492450
std::vector<const char*> vEntries = {};
@@ -2473,7 +2474,10 @@ namespace ImGui
24732474
if (iBind != DEFAULT_BIND && iBind < F::Binds.m_vBinds.size())
24742475
tBind = F::Binds.m_vBinds[iBind];
24752476
else
2477+
{
24762478
tBind = { sBind };
2479+
tBind.m_pVar = &var;
2480+
}
24772481
if (var.contains(iBind))
24782482
val = var[iBind];
24792483
}
@@ -2484,7 +2488,7 @@ namespace ImGui
24842488
{
24852489
iBind = int(F::Binds.m_vBinds.size());
24862490
tBind = { sBind };
2487-
tBind.m_vVars.push_back(&var);
2491+
tBind.m_pVar = &var;
24882492
F::Binds.AddBind(iBind, tBind);
24892493
}
24902494
else

0 commit comments

Comments
 (0)