/* Copyright (C) Arnaud Houdelette 2012-2014 Copyright (C) Emmanuel Langlois 2012-2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; using System.Collections.Generic; using System.Xml; using System.Collections.ObjectModel; using System.Threading; namespace DMX2 { public class SequenceurOSC : Sequenceur { public class Ligne { public Ligne(){} string nom = string.Empty; TimeSpan top = TimeSpan.MinValue; string commande =null; public string Nom { get { return nom; } set { nom = value; } } public TimeSpan Top { get { return top; } set { top = value; } } public string Commande { get { return commande; } set{ commande = value; } } public void Save (XmlElement parent) { XmlElement el = parent.OwnerDocument.CreateElement ("Ligne"); parent.AppendChild (el); el.SetAttribute ("nom", nom); el.SetAttribute ("top", top.ToString ()); el.SetAttribute ("cmd", commande); } public static Ligne Load (Conduite c, XmlElement el) { Ligne l = new Ligne(); l.nom = el.GetAttribute ("nom"); l.top = TimeSpan.Parse(el.GetAttribute("top")); l.commande = el.GetAttribute ("cmd"); return l; } } List lignes = new List(); Ligne aSuivre = null; Ligne enCours = null; Ligne ligneMaitre = null; TimeSpan timeStamp = TimeSpan.Zero; TimeSpan topSuivant = TimeSpan.Zero; bool topPresent = false; actionEventTarget goNextEventTarget=null; actionEventTarget goBackEventTarget=null; SeqOscUI ui = null; bool change = false; bool paused=false; public bool Paused { get { return paused; } set { paused = value; } } public SequenceurOSC () { goNextEventTarget = new actionEventTarget ( delegate(EventData data) { if(data.value==255) LigneSuivante(); return true; } ); goBackEventTarget = new actionEventTarget ( delegate(EventData data) { if(data.value==255){ if (IndexLigneEnCours > 0) { IndexLigneaSuivre = IndexLigneEnCours - 1; LigneSuivante (); } } return true; } ); } public int IndexLigneEnCours { get { if (enCours == null) return -1; return lignes.IndexOf(enCours); } } public int IndexLigneaSuivre { get { if (aSuivre == null) return -1; return lignes.IndexOf (aSuivre); } set { aSuivre = lignes[value]; } } public int AjoutLigne (int pos) { lock (this) { lignes.Insert (pos, new Ligne ()); CommandAdd(pos); return pos; } } public void RetireLigne (int pos) { lock (this) { if (lignes [pos] == enCours) { enCours = null; if (pos + 1 < lignes.Count) aSuivre = lignes [pos + 1]; } if (lignes [pos] == aSuivre) aSuivre = null; lignes.RemoveAt (pos); CommandRemove(pos); } } public TimeSpan TimeStamp { get { return timeStamp; } } public ReadOnlyCollection Lignes { get { return lignes.AsReadOnly(); } } public override int ValeurCircuit (Circuit c) { return 0; } public override void Tick (TimeSpan time) { if (paused) return; timeStamp += time; if (Monitor.TryEnter (this)) { try { while (topPresent&&(timeStamp >= topSuivant)) { LigneSuivante (); } } finally { Monitor.Exit (this); } } } public void LigneSuivante () { lock (this) { if(lignes.Count==0) return; int index; change = true; topPresent = false; if(aSuivre==null) // selection souris { index = IndexLigneEnCours +1; // Premier effet si aucun précédement if(index>= lignes.Count) index = 0; // Boucle si arrivé à la fin enCours = lignes[index]; // Gestion de la Reprise // if(enCours.Circuits.ToLower().Equals("r") && ligneMaitre != null) // enCours = ligneMaitre; if(enCours.Nom.Length!=0) { ligneMaitre = enCours; timeStamp = TimeSpan.Zero; } } else { enCours = aSuivre; ligneMaitre = enCours; timeStamp = TimeSpan.Zero; } index = IndexLigneEnCours+1; if(index= TimeSpan.Zero) { topPresent = true; topSuivant= lignes[index].Top; } } aSuivre = null; LanceCommandeMidi(); if(ui!=null) ui.EffetChange(); } } void LanceCommandeMidi () { Console.WriteLine (enCours.Commande); } public bool LigneChange () { if (change) { change = false; return true; } return false; } public override void Save (System.Xml.XmlElement parent) { System.Xml.XmlElement el = parent.OwnerDocument.CreateElement ("SequenceurOSC"); System.Xml.XmlElement xmlEl; parent.AppendChild (el); el.SetAttribute ("id", ID.ToString ()); el.SetAttribute ("name", Name); //el.SetAttribute ("master", master.ToString ()); 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); foreach (Ligne li in lignes) { li.Save(el); } } public override SequenceurUI GetUI () { if (ui == null) { ui = new SeqOscUI (this); ui.Destroyed += UiDestroyed; } return ui; } void UiDestroyed (object sender, EventArgs e) { ui = null; } public void BindEffetSuivantEvent (string eventId) { if (eventId.Length == 0) { Conduite.Courante.EventManager.Unbind (goNextEventTarget); return; } Conduite.Courante.EventManager.Bind(eventId,goNextEventTarget); } public void BindEffetPrecedentEvent (string eventId) { if (eventId.Length == 0) { Conduite.Courante.EventManager.Unbind (goBackEventTarget); return; } Conduite.Courante.EventManager.Bind(eventId,goBackEventTarget); } public static new SequenceurOSC Load (Conduite conduite, System.Xml.XmlElement el) { SequenceurOSC seq = new SequenceurOSC(); 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"); XmlElement xmlE; if ((xmlE = el["EffetSuivant"])!= null) foreach(string id in EventManager.LoadBindings(xmlE)) BindEffetSuivantEvent(id); if ((xmlE = el["EffetPrecedent"])!= null) foreach(string id in EventManager.LoadBindings(xmlE)) BindEffetPrecedentEvent(id); foreach (var xe in el.GetElementsByTagName("Ligne")) lignes.Add(Ligne.Load(conduite,xe as System.Xml.XmlElement)); } static System.Text.RegularExpressions.Regex regexCommand1 = new System.Text.RegularExpressions.Regex( @"(?\d+)", System.Text.RegularExpressions.RegexOptions.Compiled); static System.Text.RegularExpressions.Regex regexCommand2 = new System.Text.RegularExpressions.Regex( @"(?\d+)(?(t\d+)?)?", System.Text.RegularExpressions.RegexOptions.Compiled); public override void Command (string command) { lock (this) { var cmd = regexCommand1.Match(command); if (cmd.Success) { if (cmd.Groups ["effet"].Success) { int effet = int.Parse (cmd.Groups ["effet"].Value) - 1; if(effet>=lignes.Count) return; enCours = lignes[effet]; ligneMaitre = enCours; timeStamp = TimeSpan.Zero; topPresent = false; int index = IndexLigneEnCours+1; if(index= TimeSpan.Zero) { topPresent = true; topSuivant= lignes[index].Top; } } aSuivre = null; LanceCommandeMidi(); if(ui!=null) ui.EffetChange(); } } } } void CommandAdd (int index) { lock (Conduite.Courante.SequenceurMaitre) { string[] commands = Conduite.Courante.SequenceurMaitre.GetCommands (this); for (int i = 0; i < commands.Length; i++) { var cmd = regexCommand2.Match(commands[i]); if(cmd.Success){ int ef = int.Parse(cmd.Groups["effet"].Value); if (ef-1>index) { ef++; commands[i] = ef.ToString() + cmd.Groups["params"].Value; } } } Conduite.Courante.SequenceurMaitre.SetCommands(this,commands); } } void CommandRemove (int index) { lock (Conduite.Courante.SequenceurMaitre) { string[] commands = Conduite.Courante.SequenceurMaitre.GetCommands (this); for (int i = 0; i < commands.Length; i++) { var cmd = regexCommand2.Match(commands[i]); if(cmd.Success){ int ef = int.Parse(cmd.Groups["effet"].Value); if (ef-1 == index) commands[i] = string.Empty; else if (ef-1>index) { ef--; commands[i] = ef.ToString() + cmd.Groups["params"].Value; } } } Conduite.Courante.SequenceurMaitre.SetCommands(this,commands); } } void CommandSwap (int index) { lock (Conduite.Courante.SequenceurMaitre) { string[] commands = Conduite.Courante.SequenceurMaitre.GetCommands (this); // numeros a swapper int a = index+1; int b = index+2; for (int i = 0; i < commands.Length; i++) { var cmd = regexCommand2.Match(commands[i]); if(cmd.Success){ int ef = int.Parse(cmd.Groups["effet"].Value); if (ef == a) commands[i] = b.ToString() + cmd.Groups["params"].Value; if (ef == b) commands[i] = a.ToString() + cmd.Groups["params"].Value; } } Conduite.Courante.SequenceurMaitre.SetCommands(this,commands); } } } }