using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace DMX2 { public class SequenceurLineaire : Sequenceur { public class Effet { string _nom; public Effet (string nom, Dictionary valeurs, TimeSpan duree, TimeSpan transition) { _nom = nom; _valeurs = new Dictionary (valeurs); _duree = duree; _transition = transition; } public string Nom { get { return _nom; } set { _nom = value; } } Dictionary _valeurs; public int this [Circuit index] { get { if (!_valeurs.ContainsKey (index)) _valeurs.Add (index, 0); return _valeurs [index]; } } public void RetireCircuit (Circuit c) { _valeurs.Remove (c); } TimeSpan _duree = TimeSpan.Zero ; TimeSpan _transition = TimeSpan.Zero; public TimeSpan Duree { get { return _duree; } set { _duree = value; } } public TimeSpan Transition { get { return _transition; } set { _transition = value; } } public void Save (System.Xml.XmlElement parent) { System.Xml.XmlElement el = parent.OwnerDocument.CreateElement ("Effet"); System.Xml.XmlElement xmlVal; parent.AppendChild (el); el.SetAttribute("nom",_nom); el.SetAttribute ("duree", _duree.ToString ()); el.SetAttribute ("transition", _transition.ToString ()); foreach (var valeur in _valeurs) { xmlVal = parent.OwnerDocument.CreateElement("Valeur"); el.AppendChild(xmlVal); xmlVal.SetAttribute("circuit",valeur.Key.ID.ToString()); xmlVal.SetAttribute("valeur",valeur.Value.ToString()); } } public static Effet Load (Conduite conduite, System.Xml.XmlElement el) { Dictionary valeurs = new Dictionary (); foreach (var xv in el.GetElementsByTagName("Valeur")) { System.Xml.XmlElement xval = xv as System.Xml.XmlElement; valeurs.Add( conduite.GetCircuitByID(int.Parse(xval.GetAttribute("circuit"))), int.Parse(xval.GetAttribute("valeur")) ); } return new Effet( el.GetAttribute("nom"),valeurs, TimeSpan.Parse(el.GetAttribute("duree")), TimeSpan.Parse(el.GetAttribute("transition")) ); } } TimeSpan timeStamp = TimeSpan.Zero; List circuitsSeq = new List (); List effets = new List (); Effet effetcourrant = null; bool enTransition = false; Dictionary valeurscourantes = new Dictionary (); Dictionary valeursinitiales = new Dictionary (); Dictionary valeurschangees = new Dictionary (); SeqLinUI ui = null; int master = 100; public int Master { get { return master; } set { master = value; } } public SequenceurLineaire () { effetcourrant = new Effet ("",valeurscourantes , TimeSpan.Zero, TimeSpan.Zero); } public TimeSpan TimeStamp { get { return timeStamp; } } public ReadOnlyCollection Circuits { get { return circuitsSeq.AsReadOnly (); } } public ReadOnlyCollection Effets { get { return effets.AsReadOnly (); } } public void ChangeCircuits (System.Collections.Generic.List list) { lock (this) { foreach (var c in circuitsSeq.ToArray()) { if (!list.Contains (c)) RetireCircuit (c); } foreach (var c in list) if (!circuitsSeq.Contains (c)) AjouteCircuit (c); circuitsSeq = list; } } void AjouteCircuit (Circuit c) { valeurscourantes [c] = 0; valeursinitiales [c] = 0; } private void RetireCircuit (Circuit c) { foreach (var ef in effets) { ef.RetireCircuit (c); } circuitsSeq.Remove (c); valeurscourantes.Remove (c); valeursinitiales.Remove (c); } public override void MajCircuitsSupprimes () { lock (this) { foreach (var c in circuitsSeq.ToArray()) { if (!Conduite.Courante.Circuits.Contains (c)) RetireCircuit (c); } } } public override int ValeurCircuit (Circuit c) { if (!circuitsSeq.Contains (c)) return 0; if(master !=100) return valeurscourantes [c] * master /100; return valeurscourantes [c]; } public int ValeurBruteCircuit (Circuit c) { if (!circuitsSeq.Contains (c)) return 0; return valeurscourantes [c]; } public void ChangeValeur (Circuit c, int value) { valeurschangees [c] = true; valeurscourantes [c] = value; } public bool EstChange (Circuit c) { return valeurschangees.ContainsKey (c); } bool paused=false; public bool Paused { get { return paused; } set { paused = value; } } public override void Tick (TimeSpan time) { if (paused) return; timeStamp += time; if (enTransition) { if (timeStamp < effetcourrant.Transition) { double progression = timeStamp.TotalMilliseconds / effetcourrant.Transition.TotalMilliseconds; foreach (Circuit c in circuitsSeq) { if (valeurscourantes [c] != effetcourrant [c] && !valeurschangees.ContainsKey (c)) { valeurscourantes [c] = (int)(progression * (effetcourrant [c] - valeursinitiales [c]) + valeursinitiales [c]); } } } else { FinDeTransition (); } } if (effetcourrant.Duree != TimeSpan.Zero && timeStamp >= effetcourrant.Duree) { int index = effets.IndexOf (effetcourrant) + 1; if (index < effets.Count) ChangeEffetCourrant (index); } } public void FinDeTransition () { enTransition = false; foreach (Circuit c in circuitsSeq) if(!valeurschangees.ContainsKey (c)) valeurscourantes [c] = effetcourrant [c]; } public SequenceurLineaire.Effet EffetCourrant { get { return effetcourrant; } } public int IndexEffetCourrant { get { return effets.IndexOf(effetcourrant); } set { if(value>=0 && value < effets.Count) ChangeEffetCourrant(value); } } void ChangeEffetCourrant (int index) { effetcourrant = effets [index]; valeurschangees.Clear (); valeursinitiales = new Dictionary (valeurscourantes); enTransition = true; timeStamp = TimeSpan.Zero; if(ui!=null) ui.EffetChange(); } public int SauveEffet (string nom, TimeSpan duree, TimeSpan transition) { lock (this) { effets.Add (effetcourrant = new Effet (nom, valeurscourantes, duree, transition)); return effets.Count-1; } } public int InsereEffetApres (int index, string nom, TimeSpan duree, TimeSpan transition) { lock (this) { int pos = index+1; if (pos >= effets.Count) return SauveEffet(nom,duree,transition); effets.Insert (pos,effetcourrant = new Effet (nom, valeurscourantes, duree, transition)); return pos; } } public void RemplaceEffet (int index) { lock (this) { Effet ef = effets[index]; effets[index] = new Effet (ef.Nom, valeurscourantes, ef.Duree, ef.Transition); effetcourrant = effets[index]; } } public void SupprimeEffet (int index) { effets.RemoveAt(index); } public int MonteEffet (int index) { if(index>= effets.Count || index < 1 ) return index; Effet ef = effets[index]; effets.RemoveAt(index); effets.Insert(index-1, ef); return index -1; } public int BaisseEffet (int index) { if(index> effets.Count-2 || index <0) return index; Effet ef = effets[index]; effets.RemoveAt(index); effets.Insert(index+1, ef); return index +1; } public override void Save (System.Xml.XmlElement parent) { System.Xml.XmlElement el = parent.OwnerDocument.CreateElement ("SequenceurLineaire"); System.Xml.XmlElement xmlC; parent.AppendChild (el); el.SetAttribute ("id", ID.ToString ()); el.SetAttribute ("name", Name); el.SetAttribute ("master", master.ToString ()); foreach (Circuit c in circuitsSeq) { el.AppendChild(xmlC = parent.OwnerDocument.CreateElement ("CircuitSeq")); xmlC.SetAttribute("id",c.ID.ToString()); } foreach (Effet ef in effets) { ef.Save(el); } } public override SequenceurUI GetUI () { if (ui == null) { ui = new SeqLinUI (this); ui.Destroyed += UiDestroyed; } return ui; } void UiDestroyed (object sender, EventArgs e) { ui = null; } public static SequenceurLineaire Load (Conduite conduite, System.Xml.XmlElement el) { SequenceurLineaire seq = new SequenceurLineaire(); seq.LoadSeq(conduite,el); return seq; } private void LoadSeq (Conduite conduite, System.Xml.XmlElement el) { ID = int.Parse (el.GetAttribute ("id")); Name = el.GetAttribute ("name"); master = int.Parse (el.GetAttribute ("master")); foreach (var xc in el.GetElementsByTagName("CircuitSeq")) { System.Xml.XmlElement xcir = xc as System.Xml.XmlElement; Circuit c = conduite.GetCircuitByID (int.Parse (xcir.GetAttribute ("id"))); circuitsSeq.Add (c); AjouteCircuit (c); } foreach (var xe in el.GetElementsByTagName("Effet")) effets.Add(Effet.Load(conduite,xe as System.Xml.XmlElement)); } } }