- moving LoadSessionStates and SaveSessionStates from BotBase to SessionBase

This commit is contained in:
FlorianDahn 2020-04-09 11:18:23 +02:00
parent 54176f9136
commit fd6f6fef34
2 changed files with 156 additions and 154 deletions

View File

@ -175,7 +175,7 @@ namespace TelegramBotBase
if (this.StateMachine != null)
{
LoadSessionStates();
this.Sessions.LoadSessionStates(this.StateMachine);
}
this.Client.TelegramClient.StartReceiving();
@ -197,7 +197,7 @@ namespace TelegramBotBase
if (this.StateMachine != null)
{
SaveSessionStates();
this.Sessions.SaveSessionStates(this.StateMachine);
}
}
@ -474,158 +474,6 @@ namespace TelegramBotBase
}
/// <summary>
/// Loads the previously saved states from the machine.
/// </summary>
private async void LoadSessionStates()
{
if (this.StateMachine == null)
{
throw new ArgumentNullException("StateMachine", "No StateMachine defined. Please set one to property BotBase.StateMachine");
}
var container = this.StateMachine.LoadFormStates();
foreach (var s in container.States)
{
Type t = Type.GetType(s.QualifiedName);
if (t == null || !t.IsSubclassOf(typeof(FormBase)))
{
continue;
}
var form = t.GetConstructor(new Type[] { }).Invoke(new object[] { }) as FormBase;
if (s.Values != null && s.Values.Count > 0)
{
var properties = s.Values.Where(a => a.Key.StartsWith("$"));
var fields = form.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
foreach (var p in properties)
{
var f = fields.FirstOrDefault(a => a.Name == p.Key.Substring(1));
if (f == null)
continue;
try
{
f.SetValue(form, p.Value);
}
catch (ArgumentException ex)
{
}
catch
{
}
}
}
//Is Subclass of IStateForm
var iform = form as IStateForm;
if (iform != null)
{
var ls = new LoadStateEventArgs();
ls.Values = s.Values;
iform.LoadState(ls);
}
form.Client = Client;
var device = new DeviceSession(s.DeviceId, form);
device.ChatTitle = s.ChatTitle;
this.Sessions.SessionList.Add(s.DeviceId, device);
try
{
await form.OnInit(new InitEventArgs());
await form.OnOpened(new EventArgs());
}
catch
{
//Skip on exception
this.Sessions.SessionList.Remove(s.DeviceId);
}
}
}
/// <summary>
/// Saves all open states into the machine.
/// </summary>
private void SaveSessionStates()
{
if (this.StateMachine == null)
{
throw new ArgumentNullException("StateMachine", "No StateMachine defined. Please set one to property BotBase.StateMachine");
}
var states = new List<StateEntry>();
foreach (var s in Sessions.SessionList)
{
if (s.Value == null)
{
continue;
}
var form = s.Value.ActiveForm;
try
{
var se = new StateEntry();
se.DeviceId = s.Key;
se.ChatTitle = s.Value.ChatTitle;
se.FormUri = form.GetType().FullName;
se.QualifiedName = form.GetType().AssemblyQualifiedName;
if (form.GetType().GetCustomAttributes(typeof(IgnoreState), true).Length != 0)
{
continue;
}
//Is Subclass of IStateForm
var iform = form as IStateForm;
if (iform != null)
{
//Loading Session states
SaveStateEventArgs ssea = new SaveStateEventArgs();
iform.SaveState(ssea);
se.Values = ssea.Values;
}
//Search for public properties with SaveState attribute
var fields = form.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
foreach (var f in fields)
{
var val = f.GetValue(form);
se.Values.Add("$" + f.Name, val);
}
states.Add(se);
}
catch
{
//Continue on error (skip this form)
continue;
}
}
var sc = new StateContainer();
sc.States = states;
this.StateMachine.SaveFormStates(new SaveStatesEventArgs(sc));
}
/// <summary>
/// Will be called if a session/context gets started
/// </summary>

View File

@ -4,8 +4,10 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Args;
using TelegramBotBase.Attributes;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
using TelegramBotBase.Interfaces;
using TelegramBotBase.Sessions;
namespace TelegramBotBase
{
@ -107,5 +109,157 @@ namespace TelegramBotBase
{
return this.SessionList.Where(a => a.Key < 0).Select(a => a.Value).ToList();
}
/// <summary>
/// Loads the previously saved states from the machine.
/// </summary>
public async void LoadSessionStates(IStateMachine statemachine)
{
if (statemachine == null)
{
throw new ArgumentNullException("StateMachine", "No StateMachine defined. Please set one to property BotBase.StateMachine");
}
var container = statemachine.LoadFormStates();
foreach (var s in container.States)
{
Type t = Type.GetType(s.QualifiedName);
if (t == null || !t.IsSubclassOf(typeof(FormBase)))
{
continue;
}
var form = t.GetConstructor(new Type[] { }).Invoke(new object[] { }) as FormBase;
if (s.Values != null && s.Values.Count > 0)
{
var properties = s.Values.Where(a => a.Key.StartsWith("$"));
var fields = form.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
foreach (var p in properties)
{
var f = fields.FirstOrDefault(a => a.Name == p.Key.Substring(1));
if (f == null)
continue;
try
{
f.SetValue(form, p.Value);
}
catch (ArgumentException ex)
{
}
catch
{
}
}
}
//Is Subclass of IStateForm
var iform = form as IStateForm;
if (iform != null)
{
var ls = new LoadStateEventArgs();
ls.Values = s.Values;
iform.LoadState(ls);
}
form.Client = Client;
var device = new DeviceSession(s.DeviceId, form);
device.ChatTitle = s.ChatTitle;
this.SessionList.Add(s.DeviceId, device);
try
{
await form.OnInit(new InitEventArgs());
await form.OnOpened(new EventArgs());
}
catch
{
//Skip on exception
this.SessionList.Remove(s.DeviceId);
}
}
}
/// <summary>
/// Saves all open states into the machine.
/// </summary>
public void SaveSessionStates(IStateMachine statemachine)
{
if (statemachine == null)
{
throw new ArgumentNullException("StateMachine", "No StateMachine defined. Please set one to property BotBase.StateMachine");
}
var states = new List<StateEntry>();
foreach (var s in this.SessionList)
{
if (s.Value == null)
{
continue;
}
var form = s.Value.ActiveForm;
try
{
var se = new StateEntry();
se.DeviceId = s.Key;
se.ChatTitle = s.Value.ChatTitle;
se.FormUri = form.GetType().FullName;
se.QualifiedName = form.GetType().AssemblyQualifiedName;
//Skip classes where IgnoreState attribute is existing
if (form.GetType().GetCustomAttributes(typeof(IgnoreState), true).Length != 0)
{
continue;
}
//Is Subclass of IStateForm
var iform = form as IStateForm;
if (iform != null)
{
//Loading Session states
SaveStateEventArgs ssea = new SaveStateEventArgs();
iform.SaveState(ssea);
se.Values = ssea.Values;
}
//Search for public properties with SaveState attribute
var fields = form.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
foreach (var f in fields)
{
var val = f.GetValue(form);
se.Values.Add("$" + f.Name, val);
}
states.Add(se);
}
catch
{
//Continue on error (skip this form)
continue;
}
}
var sc = new StateContainer();
sc.States = states;
statemachine.SaveFormStates(new SaveStatesEventArgs(sc));
}
}
}