1+ using System . Reflection ;
2+
3+ namespace Deployf . Botf ;
4+
5+ public struct BotControllerStateService
6+ {
7+ public static Dictionary < Type , Func < BotController , Task > ? > _savers = new ( ) ;
8+ public static Dictionary < Type , Func < BotController , Task > ? > _loaders = new ( ) ;
9+
10+ public async Task Load ( BotController controller )
11+ {
12+ var controllerType = controller . GetType ( ) ;
13+ if ( _loaders . TryGetValue ( controllerType , out var loader ) && loader != null )
14+ {
15+ await loader ( controller ) ;
16+ return ;
17+ }
18+
19+ List < FieldInfo > fields ;
20+ List < PropertyInfo > props ;
21+ ExtractMembers ( controllerType , out fields , out props ) ;
22+
23+ if ( fields . Count > 0 || props . Count > 0 )
24+ {
25+ loader = async ( BotController _controller ) =>
26+ {
27+ var storage = _controller . Store ! ;
28+
29+ foreach ( var field in fields )
30+ {
31+ var value = await storage . Get ( _controller . FromId , GetKey ( field , controllerType ) , null ) ;
32+ field . SetValue ( _controller , value ) ;
33+ }
34+
35+ foreach ( var prop in props )
36+ {
37+ var value = await storage . Get ( _controller . FromId , GetKey ( prop , controllerType ) , null ) ;
38+ prop . SetValue ( _controller , value ) ;
39+ }
40+ } ;
41+
42+ _loaders [ controllerType ] = loader ;
43+
44+ await loader ( controller ) ;
45+ }
46+ else
47+ {
48+ _loaders [ controllerType ] = null ;
49+ }
50+ }
51+
52+ public async Task Save ( BotController controller )
53+ {
54+ var controllerType = controller . GetType ( ) ;
55+ if ( _savers . TryGetValue ( controllerType , out var saver ) && saver != null )
56+ {
57+ await saver ( controller ) ;
58+ return ;
59+ }
60+
61+ List < FieldInfo > fields ;
62+ List < PropertyInfo > props ;
63+ ExtractMembers ( controllerType , out fields , out props ) ;
64+
65+ if ( fields . Count > 0 || props . Count > 0 )
66+ {
67+ saver = async ( BotController _controller ) =>
68+ {
69+ var storage = _controller . Store ! ;
70+
71+ foreach ( var field in fields )
72+ {
73+ var value = field . GetValue ( _controller ) ;
74+ var key = GetKey ( field , controllerType ) ;
75+ if ( value != null )
76+ {
77+ await storage . Set ( _controller . FromId , key , value ) ;
78+ }
79+ else
80+ {
81+ await storage . Remove ( _controller . FromId , key ) ;
82+ }
83+ }
84+
85+ foreach ( var prop in props )
86+ {
87+ var value = prop . GetValue ( _controller ) ;
88+ var key = GetKey ( prop , controllerType ) ;
89+ if ( value != null )
90+ {
91+ await storage . Set ( _controller . FromId , key , value ) ;
92+ }
93+ else
94+ {
95+ await storage . Remove ( _controller . FromId , key ) ;
96+ }
97+ }
98+ } ;
99+
100+ _savers [ controllerType ] = saver ;
101+
102+ await saver ( controller ) ;
103+ }
104+ else
105+ {
106+ _savers [ controllerType ] = null ;
107+ }
108+ }
109+
110+ static void ExtractMembers ( Type controllerType , out List < FieldInfo > fields , out List < PropertyInfo > props )
111+ {
112+ const BindingFlags bindingFlags = BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . FlattenHierarchy ;
113+
114+ fields = controllerType
115+ . GetFields ( bindingFlags )
116+ . Where ( c => c . GetCustomAttribute < StateAttribute > ( ) != null )
117+ . ToList ( ) ;
118+ props = controllerType
119+ . GetProperties ( bindingFlags )
120+ . Where ( c => c . GetCustomAttribute < StateAttribute > ( ) != null )
121+ . ToList ( ) ;
122+ }
123+
124+ static string GetKey ( MemberInfo member , Type controllerType )
125+ {
126+ return $ "$ctrl-state_{ controllerType . Name } .{ member . Name } ";
127+ }
128+ }
0 commit comments