loupiottes/DMX-2.0/Conduite.cs
2013-11-15 10:34:59 +00:00

452 lines
8.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Threading;
using System.Xml;
namespace DMX2
{
public class Conduite : IComparer<Circuit>, IDisposable
{
static Conduite courante = null;
public static Conduite Courante { get { return courante; } }
Timer timer = null;
DateTime dernierTick;
DateTime derniereMaj;
string _name;
int master=100;
List<Circuit> circuits = new List<Circuit>();
List<UniversDMX> univers = new List<UniversDMX>();
List<DriverDMX> drivers = new List<DriverDMX>();
SequenceurMaitre seqmaitre = new SequenceurMaitre();
MidiEventProvider midip=null;
actionEventTarget masterEventTarget;
public Conduite()
{
if(courante!= null)
courante.Dispose();
courante = this;
timer = new Timer(new TimerCallback(TimerTick),this, 1000,10);
derniereMaj = dernierTick=DateTime.Now;
// Crée l'univers par défaut
var u = new UniversDMX();
Patches.Add(u);
u.Nom = "Univers par Défaut";
Pause = false;
midip = new MidiEventProvider(eventManager);
masterEventTarget = new actionEventTarget(
delegate(EventData data){
Master = 100 * data.value /255;
return true;
});
}
EventManager eventManager = new EventManager();
public EventManager EventManager {
get {
return eventManager;
}
set {
eventManager = value;
}
}
public ReadOnlyCollection<Circuit> Circuits {
get {
return circuits.AsReadOnly();
}
}
public Circuit NouveauCircuit ()
{
lock (this) {
Circuit c = new Circuit ();
circuits.Add (c);
return c;
}
}
/* public void SupprimeCircuits (IEnumerable<Circuit> lc)
{
lock (this) {
foreach(var c in lc)
circuits.Remove (c);
foreach(var seq in Sequenceurs)
seq.MajCircuitsSupprimes();
}
}*/
public Circuit GetCircuitByID (int i)
{
foreach(Circuit c in circuits)
if(c.ID == i) return c;
return null;
}
public string Name {
get {
return _name;
}
set {
_name = value;
}
}
public int Master {
get {
return master;
}
set {
master= value;
}
}
public bool Pause { get; set; }
public bool BlackOut { get; set ; }
public SequenceurMaitre SequenceurMaitre {
get {
return seqmaitre;
}
}
public List<DriverDMX> Drivers {
get {
return drivers;
}
}
int IComparer<Circuit>.Compare (Circuit x, Circuit y)
{
return Conduite.Courante.circuits.IndexOf(x) -
Conduite.Courante.circuits.IndexOf(y);
}
List<Sequenceur> sequenceurs= new List<Sequenceur>();
public ReadOnlyCollection<Sequenceur> Sequenceurs {
get {
return sequenceurs.AsReadOnly();
}
}
public void AjoutSequenceur (Sequenceur seq)
{
lock (this) {
sequenceurs.Add(seq);
seq.Renamed += SequenceurRenomme;
}
}
void SequenceurRenomme (object sender, Sequenceur.SeqRenamedEventArgs e)
{
MainWindow.Win.NextUpdateFull();
}
public Sequenceur GetSeqByID (int i)
{
foreach(Sequenceur seq in sequenceurs)
if(seq.ID == i)
return seq;
return null;
}
public List<UniversDMX> Patches {
get {
return univers;
}
}
static public void TimerTick (object state)
{
Conduite.Courante.Tick();
}
void Tick ()
{
DateTime tickTime = DateTime.Now;
TimeSpan deltaT = tickTime - dernierTick;
dernierTick = tickTime;
if (!Pause) {
/* if (deltaT > TimeSpan.FromMilliseconds (15))
Info.Publish(string.Format ("{0}", deltaT));*/
lock (this) {
seqmaitre.Tick (deltaT);
// 'Actionne' les sequenceurs
foreach (var seq in sequenceurs) {
seq.Tick (deltaT);
}
// Mets a jour les valeurs circuits.
if(BlackOut)
{
foreach (var c in circuits)
c.ValeurCourante = 0;
}
else
{
foreach (var c in circuits) {
int val = 0;
foreach (var seq in Sequenceurs) {
val = Math.Max (val, seq.ValeurCircuit (c));
}
c.ValeurCourante = val * master / 100;
}
}
EventManager.ProcessEvents();
}
// Cette fonction retourne quasi immédiatement, même si il y'a beaucoup a faire sur l'affichage
}
if(tickTime - derniereMaj > TimeSpan.FromMilliseconds(50)){
MainWindow.Win.ScheduleUpdate();
derniereMaj = DateTime.Now;
}
}
public void BindMaster (string eventId)
{
if (eventId.Length == 0) {
Conduite.Courante.EventManager.Unbind (masterEventTarget);
return;
}
Conduite.Courante.EventManager.Bind(eventId,masterEventTarget);
}
#region IDisposable implementation
bool disposed=false;
public void Dispose()
{
if(courante==this)
courante = null;
disposed=true;
if(timer!=null)
timer.Dispose();
if(midip!=null)
midip.Dispose();
foreach(var driver in Drivers)
driver.Dispose();
timer=null;
}
void IDisposable.Dispose ()
{
if(!disposed)
Dispose();
}
#endregion
#region Sauvegarde
public XmlDocument Save ()
{
XmlDocument xmlDoc = new XmlDocument ();
XmlElement xmlRoot = xmlDoc.CreateElement ("Conduite");
xmlDoc.AppendChild (xmlRoot);
xmlRoot.SetAttribute ("nom", this.Name);
XmlElement xmlCircuits = xmlDoc.CreateElement ("Circuits");
xmlRoot.AppendChild (xmlCircuits);
foreach (Circuit c in circuits) {
c.Save(xmlCircuits);
}
XmlElement xmlSequenceurs = xmlDoc.CreateElement("Sequenceurs");
xmlRoot.AppendChild(xmlSequenceurs);
foreach(Sequenceur seq in sequenceurs)
{
seq.Save(xmlSequenceurs);
}
XmlElement xmlUniversList = xmlDoc.CreateElement("ListeUnivers");
xmlRoot.AppendChild(xmlUniversList);
foreach(UniversDMX univ in univers)
{
univ.Save(xmlUniversList);
}
XmlElement xmlMaster = xmlDoc.CreateElement("Master");
xmlMaster.SetAttribute("value",master.ToString());
EventManager.SaveBindings(xmlMaster,masterEventTarget);
xmlRoot.AppendChild(xmlMaster);
seqmaitre.Save(xmlRoot);
return xmlDoc;
}
public static Conduite Load (XmlDocument doc)
{
Conduite cond = new Conduite ();
cond.LoadDoc (doc);
return cond;
// cond.Dispose();
// return null;
}
private void LoadDoc (XmlDocument doc)
{
XmlElement root = doc.DocumentElement;
_name = root.Attributes ["nom"].Value;
foreach (var xc in root["Circuits"].ChildNodes) {
Circuit c = Circuit.Load (xc as XmlElement);
if (c != null)
circuits.Add (c);
}
foreach (var xs in root["Sequenceurs"].ChildNodes) {
Sequenceur s = Sequenceur.Load (this, xs as XmlElement);
if (s != null){
sequenceurs.Add (s);
s.Renamed += SequenceurRenomme;
}
}
univers.Clear();
foreach (var xu in root["ListeUnivers"].ChildNodes) {
UniversDMX u = UniversDMX.Load(this,xu as XmlElement);
if(u!=null)
univers.Add(u);
}
XmlElement xmlMaster;
if((xmlMaster = root["Master"])!=null)
{
master = int.Parse( xmlMaster.GetAttribute("value"));
foreach(string id in EventManager.LoadBindings(xmlMaster))
BindMaster(id);
}
seqmaitre = SequenceurMaitre.Load(this,root["SequenceurMaitre"]);
}
#endregion
}
public class Circuit
{
static int maxid=1;
string name;
public const int SNLen= 8;
public Circuit()
{
id=maxid++;
Name = "Circuit n°" + id.ToString();
ShortName = "Cir" + id.ToString();
}
public string Name {
get {
return name;
}
set {
name = value;
}
}
string shortName;
public string ShortName {
get {
return shortName;
}
set {
if (value.Length > SNLen)
shortName = value.Substring(0,SNLen);
else
shortName = value;
}
}
int id;
public int ID {
get {
return id;
}
}
int _curval;
public int ValeurCourante {
get {
return _curval;
}
set {
_curval = value;
}
}
public void Save (XmlElement parent)
{
XmlElement el= parent.OwnerDocument.CreateElement ("Circuit");
parent.AppendChild(el);
el.SetAttribute("ID",id.ToString());
el.SetAttribute("name",name);
el.SetAttribute("shortName",shortName);
}
public static Circuit Load (XmlElement xc)
{
if(xc.Name!="Circuit") throw new ErreurLectureFichier("<Circuit> attendu.");
return new Circuit(xc);
}
private Circuit(XmlElement xc)
{
id = int.Parse(xc.GetAttribute("ID"));
maxid = Math.Max (maxid,id+1);
name = xc.GetAttribute("name");
shortName = xc.GetAttribute("shortName");
}
}
}