using System; using System.Collections.Generic; using System.Xml; using System.Collections.ObjectModel; namespace DMX2 { public class SequenceurMaitre { public class Ligne { public Ligne(){} string nom; TimeSpan duree = TimeSpan.Zero; Dictionary data = new Dictionary(); public string Nom { get { return nom; } set { nom = value; } } public TimeSpan Duree { get { return duree; } set { duree = value; } } public string this [Sequenceur index] { get { string value; if(!data.TryGetValue(index, out value)) return string.Empty; return value; } set { if(value.Length==0) { if(data.ContainsKey(index)) data.Remove(index); } else data[index] = value; } } public void Save (XmlElement parent) { XmlElement el = parent.OwnerDocument.CreateElement ("Ligne"); parent.AppendChild (el); el.SetAttribute ("nom", nom); el.SetAttribute ("duree", duree.ToString ()); XmlElement xmlSeq; foreach (var val in data) { el.AppendChild(xmlSeq=parent.OwnerDocument.CreateElement ("data")); xmlSeq.SetAttribute("seq",val.Key.ID.ToString()); xmlSeq.SetAttribute("val",val.Value); } } public static Ligne Load (Conduite c, XmlElement el) { Ligne l = new Ligne(); l.nom = el.GetAttribute ("nom"); l.duree = TimeSpan.Parse(el.GetAttribute("duree")); foreach (var xv in el.GetElementsByTagName("data")) { XmlElement xmlSeq = xv as XmlElement; Sequenceur seq = c.GetSeqByID(int.Parse(xmlSeq.GetAttribute("seq"))); l[seq]= xmlSeq.GetAttribute ("val"); } return l; } } List lignes = new List(); Ligne enCours = null; TimeSpan timeStamp = TimeSpan.Zero; actionEventTarget goNextEventTarget=null; actionEventTarget goBackEventTarget=null; bool change = false; public TimeSpan TimeStamp { get { return timeStamp; } } public int IndexLigneEnCours { get { if (enCours == null) return -1; return lignes.IndexOf(enCours); } } Ligne aSuivre = null; public int IndexLigneaSuivre { get { if (aSuivre == null) return -1; return lignes.IndexOf (aSuivre); } set { aSuivre = lignes[value]; } } public void EffetSuivant () { lock (this) { if(lignes.Count==0) return; if (aSuivre == null) { if (IndexLigneEnCours + 1 < lignes.Count) enCours = lignes [IndexLigneEnCours + 1]; else enCours = lignes [0]; } else { enCours = aSuivre; } aSuivre = null; timeStamp = TimeSpan.Zero; change = true; LanceSequenceurs(); } } public void EffetPrecedent () { lock (this) { if(lignes.Count==0) return; if (IndexLigneEnCours > 0) enCours = lignes [IndexLigneEnCours - 1]; else enCours = lignes [0]; aSuivre = null; timeStamp = TimeSpan.Zero; change = true; LanceSequenceurs(); } } void LanceSequenceurs () { foreach (Sequenceur s in Conduite.Courante.Sequenceurs) { if(enCours[s].Length > 0) s.Command(enCours[s]); } } public string[] GetCommands(Sequenceur s) { string[] res = new string[lignes.Count]; for (int i = 0; i < lignes.Count; i++) { res[i] = lignes[i][s]; } return res; } public void SetCommands (Sequenceur s, string[] commands) { lock (this) { for (int i = 0; i < Math.Max(lignes.Count,commands.Length); i++) { lignes [i] [s] = commands [i]; } change= true; } } public ReadOnlyCollection Lignes { get { return lignes.AsReadOnly(); } } public SequenceurMaitre () { //lignes.Add(new Ligne()); goNextEventTarget = new actionEventTarget( delegate(EventData data){ if(data.value!=0) EffetSuivant(); return true; }); goBackEventTarget = new actionEventTarget( delegate(EventData data){ if(data.value!=0) EffetPrecedent(); return true; }); } public int AjoutLigne (int pos) { lock (this) { lignes.Insert (pos, new Ligne ()); return pos; } } public void RetireLigne (int pos) { lock (this) { if(pos<0 || pos >= lignes.Count) return; if(lignes[pos]== enCours) { enCours=null; if(pos+1 < lignes.Count) aSuivre = lignes[pos+1]; } if(lignes[pos] == aSuivre) aSuivre=null; lignes.RemoveAt(pos); } } public void Tick (TimeSpan deltaT) { timeStamp += deltaT; if(enCours != null) if (enCours.Duree != TimeSpan.Zero && enCours.Duree <= timeStamp ) { EffetSuivant(); } } public bool EffetChange () { if (change) { change = false; return true; } return false; } public void BindEffetSuivant (string eventId) { if (eventId.Length == 0) { Conduite.Courante.EventManager.Unbind (goNextEventTarget); return; } Conduite.Courante.EventManager.Bind(eventId,goNextEventTarget); } public void BindEffetPrecedent (string eventId) { if (eventId.Length == 0) { Conduite.Courante.EventManager.Unbind (goBackEventTarget); return; } Conduite.Courante.EventManager.Bind(eventId,goBackEventTarget); } public void Save (XmlElement parent) { XmlElement el = parent.OwnerDocument.CreateElement("SequenceurMaitre"); parent.AppendChild(el); foreach(Ligne l in lignes) l.Save(el); XmlElement xmlEl = parent.OwnerDocument.CreateElement ("EffetSuivant"); if(Conduite.Courante.EventManager.SaveBindings(xmlEl,goNextEventTarget )) el.AppendChild(xmlEl); xmlEl = parent.OwnerDocument.CreateElement ("EffetPrecedent"); if(Conduite.Courante.EventManager.SaveBindings(xmlEl,goBackEventTarget )) el.AppendChild(xmlEl); } public static SequenceurMaitre Load (Conduite c, XmlElement el) { SequenceurMaitre seq = new SequenceurMaitre (); foreach (var xl in el.GetElementsByTagName("Ligne")) { seq.lignes.Add(Ligne.Load(c,xl as XmlElement)); } XmlElement xmlE; if ((xmlE = el["EffetSuivant"])!= null) foreach(string id in EventManager.LoadBindings(xmlE)) seq.BindEffetSuivant(id); if ((xmlE = el["EffetPrecedent"])!= null) foreach(string id in EventManager.LoadBindings(xmlE)) seq.BindEffetPrecedent(id); return seq; } } }