StephaneLenclud@210: // StephaneLenclud@210: StephaneLenclud@210: StephaneLenclud@210: using System; Stephane@212: using System.Collections.Generic; StephaneLenclud@253: using System.Diagnostics; StephaneLenclud@265: using System.Linq; StephaneLenclud@210: using System.Runtime.Serialization; StephaneLenclud@210: using System.Threading; StephaneLenclud@258: using System.Threading.Tasks; StephaneLenclud@210: StephaneLenclud@210: namespace SharpLib.Ear StephaneLenclud@210: { StephaneLenclud@210: [DataContract] StephaneLenclud@266: [AttributeObject(Id = "Action", Name = "Action Group", Description = "Use it to group other actions together.")] StephaneLenclud@265: public class Action: Object StephaneLenclud@210: { StephaneLenclud@264: [DataMember] StephaneLenclud@264: [AttributeObjectProperty StephaneLenclud@264: ( StephaneLenclud@264: Id = "Action.Iterations", StephaneLenclud@264: Name = "Iterations", StephaneLenclud@264: Description = "Specifies the number of time this action should execute.", StephaneLenclud@264: Minimum = "0", StephaneLenclud@264: Maximum = "10000", StephaneLenclud@264: Increment = "1" StephaneLenclud@264: ) StephaneLenclud@264: ] StephaneLenclud@264: public int Iterations { get; set; } = 1; StephaneLenclud@264: StephaneLenclud@264: /// StephaneLenclud@264: /// StephaneLenclud@264: /// StephaneLenclud@264: public bool Enabled StephaneLenclud@264: { StephaneLenclud@264: get { return Iterations > 0; } StephaneLenclud@264: } StephaneLenclud@264: StephaneLenclud@266: StephaneLenclud@266: public override bool IsValid() StephaneLenclud@266: { StephaneLenclud@266: // We don't want to override this behaviour for derived classes StephaneLenclud@266: if (GetType() == typeof(Action)) StephaneLenclud@266: { StephaneLenclud@266: // Avoid having empty actions with no name StephaneLenclud@266: return !string.IsNullOrEmpty(Name); StephaneLenclud@266: } StephaneLenclud@266: StephaneLenclud@266: return base.IsValid(); StephaneLenclud@266: } StephaneLenclud@266: StephaneLenclud@266: StephaneLenclud@265: /// StephaneLenclud@265: /// Basic action just does nothing StephaneLenclud@265: /// StephaneLenclud@265: /// StephaneLenclud@265: protected virtual async Task DoExecute() StephaneLenclud@265: { StephaneLenclud@265: StephaneLenclud@265: } StephaneLenclud@223: StephaneLenclud@231: /// StephaneLenclud@231: /// Allows testing from generic edit dialog. StephaneLenclud@231: /// StephaneLenclud@231: public void Test() StephaneLenclud@231: { StephaneLenclud@253: Trace.WriteLine("Action test"); StephaneLenclud@231: Execute(); StephaneLenclud@231: } StephaneLenclud@231: StephaneLenclud@264: /// StephaneLenclud@264: /// Execute our action N times. StephaneLenclud@264: /// StephaneLenclud@264: /// StephaneLenclud@258: public async Task Execute() StephaneLenclud@223: { StephaneLenclud@239: if (!IsValid()) StephaneLenclud@239: { StephaneLenclud@264: Trace.WriteLine("EAR: Action.Execute: WARNING: Action invalid, aborting execution: " + Brief()); StephaneLenclud@239: return; StephaneLenclud@239: } StephaneLenclud@264: StephaneLenclud@264: if (!Enabled) StephaneLenclud@264: { StephaneLenclud@264: Trace.WriteLine("EAR: Action.Execute: Action disabled: " + Brief()); StephaneLenclud@264: return; StephaneLenclud@264: } StephaneLenclud@264: StephaneLenclud@264: for (int i = Iterations; i > 0; i--) StephaneLenclud@264: { StephaneLenclud@264: Trace.WriteLine($"EAR: Action.Execute: [{Iterations - i + 1}/{Iterations}] - {BriefBase()}"); StephaneLenclud@265: //For each iteration StephaneLenclud@265: //We first execute ourselves StephaneLenclud@264: await DoExecute(); StephaneLenclud@265: StephaneLenclud@265: //Then our children StephaneLenclud@265: foreach (Action a in Objects.OfType()) StephaneLenclud@265: { StephaneLenclud@265: await a.Execute(); StephaneLenclud@265: } StephaneLenclud@264: } StephaneLenclud@223: } StephaneLenclud@210: StephaneLenclud@265: /// StephaneLenclud@265: /// For inherited classes to override. StephaneLenclud@265: /// StephaneLenclud@265: /// StephaneLenclud@264: public virtual string BriefBase() StephaneLenclud@264: { StephaneLenclud@266: return string.IsNullOrEmpty(Name)? AttributeName : Name; StephaneLenclud@264: } StephaneLenclud@264: StephaneLenclud@264: /// StephaneLenclud@264: /// Dynamic object description. StephaneLenclud@264: /// StephaneLenclud@264: /// StephaneLenclud@264: public sealed override string Brief() StephaneLenclud@264: { StephaneLenclud@264: return Iterations > 1 ? $"{Iterations} x " + BriefBase():BriefBase(); StephaneLenclud@264: } StephaneLenclud@264: StephaneLenclud@264: StephaneLenclud@264: StephaneLenclud@264: StephaneLenclud@264: StephaneLenclud@264: StephaneLenclud@210: } StephaneLenclud@210: StephaneLenclud@210: StephaneLenclud@210: }