1+ /* * Double-include prevention */
2+ #if defined _utl_dict_included
3+ #endinput
4+ #endif
5+ #define _utl_dict_included
6+
7+ #include <sdktools>
8+ #include <address_base>
9+ #include <stringt>
10+ #include "tier1/utl_map.inc"
11+
12+ #pragma newdecls required
13+ #pragma semicolon 1
14+
15+ #define UTL_DICT_TAG " [UtlDict]"
16+ #define UTL_DICT_VERSION " 1.0.0"
17+
18+ /* *
19+ * Author: blueblur
20+ * Date: 2025-11-14
21+ * url: https://github.com/blueblur0730/modified-plugins
22+ * Version: 1.0.0
23+ */
24+
25+ enum EDictCompareType
26+ {
27+ k_eDictCompareTypeCaseSensitive =0 ,
28+ k_eDictCompareTypeCaseInsensitive =1 ,
29+ k_eDictCompareTypeFilenames // Slashes and backslashes count as the same character..
30+ };
31+
32+ /*
33+ //-----------------------------------------------------------------------------
34+ // A dictionary mapping from symbol to structure
35+ //-----------------------------------------------------------------------------
36+ template <class T, class I = int >
37+
38+ // Nested typedefs, for code that might need
39+ // to fish out the index type from a given dict
40+ typedef I IndexType_t;
41+
42+ typedef CUtlMap<const char *, T, I> DictElementMap_t;
43+ DictElementMap_t m_Elements;
44+ */
45+
46+ methodmap UtlDict < AddressBase {
47+ public UtlDict (Address addr ) {
48+ UtlDict p = view_as <UtlDict >(addr );
49+
50+ if (p .IsNull ()) {
51+ ThrowError (" Invalid UtlDict address" );
52+ }
53+
54+ return p ;
55+ }
56+
57+ property UtlMap m_Elements {
58+ public get () {
59+ return LoadFromAddress (this .addr , NumberType_Int32 );
60+ }
61+
62+ public set (UtlMap value ) {
63+ StoreToAddress (this .addr , value , NumberType_Int32 );
64+ }
65+ }
66+
67+ public any Element (int i , int size = 4 , NumberType type = NumberType_Int32 ) {
68+ return this .m_Elements .Element (i , size , type );
69+ }
70+
71+ public Stringt GetElementName (int i , int size = 4 , NumberType type = NumberType_Int32 ) {
72+ return this .m_Elements .Key (i , size , type );
73+ }
74+
75+ // SetElementName seems to be incomplete, and has not yet been used anywhere in the code.
76+ /*
77+ template <class T, class I>
78+ inline void CUtlDict<T, I>::SetElementName( I i, char const *pName )
79+ {
80+ MEM_ALLOC_CREDIT_CLASS();
81+ // TODO: This makes a copy of the old element
82+ // TODO: This relies on the rb tree putting the most recently
83+ // removed element at the head of the insert list
84+ free( (void *)m_Elements.Key( i ) );
85+ m_Elements.Reinsert( strdup( pName ), i );
86+ }
87+ */
88+
89+ public int Count () {
90+ return this .m_Elements .Count ();
91+ }
92+
93+ public int MaxElement () {
94+ return this .m_Elements .MaxElement ();
95+ }
96+
97+ public bool IsValidIndex (int i ) {
98+ return this .m_Elements .IsValidIndex (i );
99+ }
100+
101+ public static int InvalidIndex () {
102+ return UtlRBTree .InvalidIndex ();
103+ }
104+
105+ public int FindSafe (any obj , int size = 4 , NumberType numberType = NumberType_Int32 ) {
106+ if (obj ) {
107+ return this .m_Elements .FindSafe (obj , size , numberType );
108+ } else {
109+ return UtlRBTree .InvalidIndex ();
110+ }
111+ }
112+
113+ public bool HasElementSafe (any obj , int size = 4 , NumberType numberType = NumberType_Int32 ) {
114+ if (obj ) {
115+ return this .IsValidIndex (this .m_Elements .FindSafe (obj , size , numberType ));
116+ } else {
117+ return false ;
118+ }
119+ }
120+
121+ public int First (int size = 4 ) {
122+ return this .m_Elements .FirstInorder (size );
123+ }
124+
125+ public int Next (int i , int size = 4 ) {
126+ return this .m_Elements .NextInorder (i , size );
127+ }
128+
129+ #if defined _smmem_included_
130+ // 何意味
131+ public void EnsureCapacity (int num , int size = 4 ) {
132+ this .m_Elements .m_Tree .EnsureCapacity (num , size );
133+ }
134+
135+ public void RemoveAt (int elem , int size = 4 , NumberType elementSize = NumberType_Int32 , UtlRBTreeDestructorFunc destructor ) {
136+ any p = this .m_Elements .GetKeyEx (elem , size ); // const char *
137+ free (p );
138+
139+ this .m_Elements .RemoveAt (elem , size , elementSize , destructor );
140+ }
141+
142+ public void Remove (Stringt search , int size = 4 , int insertSize , NumberType elementSize = NumberType_Int32 , UtlRBTreeDestructorFunc destructor ) {
143+ int node = this .Find (search , insertSize , elementSize );
144+ if (node != UtlRBTree .InvalidIndex ()) {
145+ this .m_Elements .RemoveAt (node , size , elementSize , destructor );
146+ }
147+ }
148+
149+ public void RemoveAll (int size = 4 , NumberType elementSize = NumberType_Int32 , UtlRBTreeDestructorFunc destructor ) {
150+ int index = this .m_Elements .FirstInorder (size );
151+ while (index != UtlRBTree .InvalidIndex ()) {
152+ any p = this .m_Elements .GetKeyEx (index , size );
153+ free (p );
154+
155+ index = this .m_Elements .NextInorder (index , size );
156+ }
157+
158+ this .m_Elements .RemoveAll (size , elementSize , destructor );
159+ }
160+
161+ public void Purge (int size , NumberType elementSize = NumberType_Int32 , UtlRBTreeDestructorFunc destructor ) {
162+ this .RemoveAll (size , elementSize , destructor );
163+ }
164+
165+ public void PurgeAndDeleteElements (bool bAlwaysFreeElems = true , int keySize , int elemSize , NumberType elementSize = NumberType_Int32 , UtlMapDestructorFunc destructor = null , UtlRBTreeDestructorFunc destructor2 ) {
166+ int index = this .m_Elements .FirstInorder (keySize + elemSize );
167+ while (index != UtlRBTree .InvalidIndex ()) {
168+ any p = this .m_Elements .GetKeyEx (index , keySize + elemSize ); // char *
169+ free (p );
170+
171+ // delete m_Elements[index];
172+ if (bAlwaysFreeElems && destructor ) {
173+ any elem = this .m_Elements .GetElement (index , elemSize , elementSize );
174+ any elemAddr = this .m_Elements .GetElementEx (index , elemSize );
175+
176+ this .m_Elements .Destruct (index , elemSize , elemAddr , elem , destructor );
177+ }
178+
179+ index = this .m_Elements .NextInorder (index , keySize + elemSize );
180+ }
181+
182+ this .RemoveAll (keySize + elemSize , elementSize , destructor2 );
183+ }
184+
185+ public int Insert (Stringt keyName , int keySize = 4 , any insert , int Insertsize = 4 , NumberType elementSize = NumberType_Int32 , UtlRBTreeConstructorFunc constructor ) {
186+ Stringt pDup = keyName .strdup ();
187+ this .m_Elements .Insert (pDup , keySize , insert , Insertsize , elementSize , constructor );
188+ }
189+
190+ public int InsertSafe (any obj , int size , UtlRBTreeConstructorFunc constructor ) {
191+ this .m_Elements .InsertSafe (obj , size , constructor );
192+ }
193+
194+ public int Find (Stringt search , int size = 4 , int insertSize , NumberType numberType = NumberType_Int32 ) {
195+ if (! search .IsNull ()) {
196+ return this .m_Elements .Find (search , size , insertSize , numberType );
197+ } else {
198+ return UtlRBTree .InvalidIndex ();
199+ }
200+ }
201+
202+ public bool HasElement (Stringt search , int size = 4 , NumberType numberType = NumberType_Int32 ) {
203+ if (! search .IsNull ()) {
204+ return this .IsValidIndex (this .m_Elements .Find (search , size , 0 , numberType ));
205+ } else {
206+ return false ;
207+ }
208+ }
209+ #endif
210+ }
0 commit comments