44/// Author: Maverick Liberty
55///////////////////////////////////////////////////////
66
7- using System ;
8- using System . Collections . Generic ;
97using System . Diagnostics . CodeAnalysis ;
10- using System . Runtime . CompilerServices ;
8+ using EppNet . Node ;
119
1210namespace EppNet . Data
1311{
@@ -17,161 +15,51 @@ namespace EppNet.Data
1715 /// specific instance
1816 /// </summary>
1917
20- public interface IDataHolder : IDisposable
18+ public interface IDataHolder : INodeDescendant
2119 {
22- /// <summary>
23- /// Global data dictionary. I considered using something with weak references but those
24- /// just hide poor memory management.
25- /// <br></br>Just make sure you call dispose!
26- /// </summary>
27- internal static readonly ConditionalWeakTable < IDataHolder , Dictionary < string , object > > _globalDataDict = new ( ) ;
28-
29- /// <summary>
30- /// Tries to get all data associated with a particular <see cref="IDataHolder"/><br></br>
31- /// </summary>
32- /// <param name="dataHolder"></param>
33- /// <returns>Whether or not an internal dictionary was cleared<br>
34- /// </br><b>NOTE:</b> Returns false if no custom data was set.</returns>
35-
36- public static bool DeleteAllData ( [ NotNull ] IDataHolder dataHolder )
37- {
38- if ( dataHolder == null )
39- return false ;
4020
41- return _globalDataDict . Remove ( dataHolder ) ;
42- }
21+ public bool Set < T > ( [ NotNull ] string key , T value ) =>
22+ Node . DataStorage . AddOrUpdateCustomDataEntry ( this , key , value ) ;
4323
44- /// <summary>
45- /// Tries to associate a value with a key<br/>
46- /// Key mustn't be null or empty.<br></br>
47- /// <b>NOTE:</b> Uses <see cref="GetOrCreateData"/>, so will only fail for invalid keys
48- /// </summary>
49- /// <param name="key"></param>
50- /// <param name="value"></param>
51- /// <returns>Whether or not the key was set to the value</returns>
52- /// <exception cref="ArgumentException">Key cannot be empty or null</exception>
53-
54- public bool Set ( string key , object value )
24+ public bool SetIfAbsent < T > ( [ NotNull ] string key , T value )
5525 {
56- var data = GetOrCreateData ( ) ;
57-
58- if ( string . IsNullOrEmpty ( key ) )
59- throw new ArgumentException ( "Key cannot be empty or null!" ) ;
26+ if ( ! Has ( key ) )
27+ return Set ( key , value ) ;
6028
61- if ( TryGetValue ( key , out object existing ) && existing == value )
62- // Data is already set
63- return false ;
64-
65- data [ key ] = value ;
66- return true ;
29+ return false ;
6730 }
6831
69- /// <summary>
70- /// Fetches a value by the key without any checks<br/>
71- /// Can result in an error if the key doesn't exist.
72- /// </summary>
73- /// <param name="key"></param>
74- /// <exception cref="KeyNotFoundException">The specified key could not be found</exception>
75- /// <returns></returns>
76-
77- public object Get ( string key ) => GetOrCreateData ( ) [ key ] ;
78-
79- /// <summary>
80- /// Tries to remove the specified key from the internal data dictionary
81- /// </summary>
82- /// <param name="key"></param>
83- /// <returns>Whether or not it was deleted</returns>
84-
85- public bool Remove ( string key ) => GetOrCreateData ( ) . Remove ( key ) ;
86-
87- /// <summary>
88- /// Tries to get an object by key
89- /// </summary>
90- /// <param name="key"></param>
91- /// <param name="value"></param>
92- /// <returns>Whether or not the key was valid</returns>
93-
94- public bool TryGetValue ( string key , out object value )
95- {
96- value = null ;
97-
98- var data = GetOrCreateData ( ) ;
32+ public T Get < T > ( [ NotNull ] string key ) =>
33+ ( T ) Node . DataStorage . GetCustomDataEntry ( this , key ) ;
9934
100- if ( data == null )
101- return false ;
35+ public object Get ( [ NotNull ] string key ) =>
36+ Node . DataStorage . GetCustomDataEntry ( this , key ) ;
10237
103- return data . TryGetValue ( key , out value ) ;
104- }
38+ public T GetOrDefault < T > ( [ NotNull ] string key , T fallback ) =>
39+ TryGet ( key , out T result ) ? result : fallback ;
10540
106- /// <summary>
107- /// Gets or creates an internal dictionary for data holding
108- /// </summary>
109- /// <returns>A dictionary</returns>
110-
111- public Dictionary < string , object > GetOrCreateData ( )
41+ public bool TryGet < T > ( [ NotNull ] string key , out T value )
11242 {
43+ bool fetched = Node . DataStorage . TryGetCustomDataEntry ( this , key , out object obj ) ;
44+ value = default ;
11345
114- Dictionary < string , object > data ;
115-
116- if ( ! _globalDataDict . TryGetValue ( this , out data ) )
46+ if ( fetched && obj is T casted )
11747 {
118- data = new ( StringComparer . Ordinal ) ;
119- _globalDataDict . Add ( this , data ) ;
48+ value = casted ;
49+ return true ;
12050 }
12151
122- return data ;
52+ return false ;
12353 }
12454
125- }
126-
127- public static class IDataHolderExtensions
128- {
55+ public bool TryGet ( [ NotNull ] string key , out object value ) =>
56+ Node . DataStorage . TryGetCustomDataEntry ( this , key , out value ) ;
12957
130- /// <summary>
131- /// Tries to associate a value with a key<br/>
132- /// Key mustn't be null or empty.<br></br>
133- /// <b>NOTE:</b> Uses <see cref="GetOrCreateData"/>, so will only fail for invalid keys
134- /// </summary>
135- /// <param name="key"></param>
136- /// <param name="value"></param>
137- /// <returns>Whether or not the key was set to the value</returns>
138- /// <exception cref="ArgumentException">Key cannot be empty or null</exception>
139- public static bool Set < T > ( this T holder , string key , object value ) where T : IDataHolder => holder . Set ( key , value ) ;
140-
141- /// <summary>
142- /// Fetches a value by the key without any checks<br/>
143- /// Can result in an error if the key doesn't exist.
144- /// </summary>
145- /// <param name="key"></param>
146- /// <exception cref="KeyNotFoundException">The specified key could not be found</exception>
147- /// <returns></returns>
148- public static object Get < T > ( this T holder , string key ) where T : IDataHolder => holder . Get ( key ) ;
149-
150- /// <summary>
151- /// Tries to remove the specified key from the internal data dictionary
152- /// </summary>
153- /// <param name="key"></param>
154- /// <returns>Whether or not it was deleted</returns>
155-
156- public static bool Remove < T > ( this T holder , string key ) where T : IDataHolder => holder . Remove ( key ) ;
157-
158- /// <summary>
159- /// Tries to get an object by key
160- /// </summary>
161- /// <param name="key"></param>
162- /// <param name="value"></param>
163- /// <returns>Whether or not the key was valid</returns>
164-
165- public static bool TryGetValue < T > ( this T holder , string key , out object value ) where T : IDataHolder => holder . TryGetValue ( key , out value ) ;
166-
167- /// <summary>
168- /// Gets or creates an internal dictionary for data holding
169- /// </summary>
170- /// <returns>A dictionary</returns>
171-
172- public static Dictionary < string , object > GetOrCreateData < T > ( this T holder ) where T : IDataHolder => holder . GetOrCreateData ( ) ;
58+ public bool Remove ( [ NotNull ] string key , out object value ) =>
59+ Node . DataStorage . RemoveCustomDataEntry ( this , key , out value ) ;
17360
61+ public bool Has ( [ NotNull ] string key ) =>
62+ Node . DataStorage . TryGetCustomDataEntry ( this , key , out _ ) ;
17463
17564 }
176-
17765}
0 commit comments