516 lines
12 KiB
C#
516 lines
12 KiB
C#
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<Circuit,int> valeurs, TimeSpan duree, TimeSpan transition)
|
|
{
|
|
_nom = nom;
|
|
_valeurs = new Dictionary<Circuit, int> (valeurs);
|
|
_duree = duree;
|
|
_transition = transition;
|
|
}
|
|
|
|
public string Nom {
|
|
get {
|
|
return _nom;
|
|
}
|
|
set {
|
|
_nom = value;
|
|
}
|
|
}
|
|
|
|
Dictionary<Circuit,int> _valeurs;
|
|
|
|
public int this [Circuit index] {
|
|
get {
|
|
if (!_valeurs.ContainsKey (index))
|
|
_valeurs.Add (index, 0);
|
|
return _valeurs [index];
|
|
}
|
|
}
|
|
|
|
public Dictionary<Circuit, int> Valeurs {
|
|
get {
|
|
return _valeurs;
|
|
}
|
|
}
|
|
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<Circuit, int> valeurs = new Dictionary<Circuit, int> ();
|
|
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;
|
|
TimeSpan tempsTransition = TimeSpan.Zero;
|
|
List<Circuit> circuitsSeq = new List<Circuit> ();
|
|
List<Effet> effets = new List<Effet> ();
|
|
Effet effetcourrant = null;
|
|
bool enTransition = false;
|
|
Dictionary<Circuit,int> valeurscourantes = new Dictionary<Circuit, int> ();
|
|
Dictionary<Circuit,int> valeursinitiales = new Dictionary<Circuit, int> ();
|
|
Dictionary<Circuit,bool> valeurschangees = new Dictionary<Circuit, bool> ();
|
|
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<Circuit> Circuits {
|
|
get {
|
|
return circuitsSeq.AsReadOnly ();
|
|
}
|
|
}
|
|
|
|
public ReadOnlyCollection<Effet> Effets {
|
|
get {
|
|
return effets.AsReadOnly ();
|
|
}
|
|
}
|
|
|
|
public void ChangeCircuits (System.Collections.Generic.List<Circuit> list)
|
|
{
|
|
foreach (var c in circuitsSeq.ToArray()) {
|
|
if (!list.Contains (c))
|
|
lock(this) RetireCircuit (c);
|
|
}
|
|
foreach (var c in list)
|
|
if (!circuitsSeq.Contains (c))
|
|
lock(this) AjouteCircuit (c);
|
|
circuitsSeq = list;
|
|
}
|
|
|
|
void AjouteCircuit (Circuit c)
|
|
{
|
|
valeurscourantes [c] = 0;
|
|
valeursinitiales [c] = 0;
|
|
}
|
|
|
|
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)
|
|
{
|
|
lock(this) {
|
|
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);
|
|
}
|
|
|
|
public bool EnTransition (Circuit c)
|
|
{
|
|
if(!enTransition) return false ;
|
|
return valeurscourantes [c] != effetcourrant [c];
|
|
}
|
|
bool paused=false;
|
|
|
|
public bool Paused {
|
|
get {
|
|
return paused;
|
|
}
|
|
set {
|
|
paused = value;
|
|
}
|
|
}
|
|
|
|
public override void Tick (TimeSpan time)
|
|
{
|
|
if (paused) return;
|
|
timeStamp += time;
|
|
lock(this) {
|
|
if (enTransition) {
|
|
if (timeStamp < tempsTransition) {
|
|
double progression = timeStamp.TotalMilliseconds / tempsTransition.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 ()
|
|
{
|
|
lock(this) {
|
|
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)
|
|
{
|
|
lock (this) {
|
|
effetcourrant = effets [index];
|
|
valeurschangees.Clear ();
|
|
valeursinitiales = new Dictionary<Circuit, int> (valeurscourantes);
|
|
tempsTransition = effetcourrant.Transition;
|
|
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));
|
|
CommandAdd(index);
|
|
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)
|
|
{
|
|
lock (this) {
|
|
effets.RemoveAt (index);
|
|
CommandRemove(index);
|
|
}
|
|
}
|
|
|
|
public int MonteEffet (int index)
|
|
{
|
|
lock (this) {
|
|
if (index >= effets.Count || index < 1)
|
|
return index;
|
|
Effet ef = effets [index];
|
|
effets.RemoveAt (index);
|
|
effets.Insert (index - 1, ef);
|
|
CommandSwap (index - 1);
|
|
return index - 1;
|
|
}
|
|
}
|
|
|
|
public int BaisseEffet (int index)
|
|
{
|
|
lock (this) {
|
|
if (index > effets.Count - 2 || index < 0)
|
|
return index;
|
|
Effet ef = effets [index];
|
|
effets.RemoveAt (index);
|
|
effets.Insert (index + 1, ef);
|
|
CommandSwap(index);
|
|
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 new 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));
|
|
}
|
|
|
|
static System.Text.RegularExpressions.Regex regexCommand1 = new System.Text.RegularExpressions.Regex(
|
|
@"(?<effet>\d+)(t(?<transition>\d+))?",
|
|
System.Text.RegularExpressions.RegexOptions.Compiled);
|
|
|
|
static System.Text.RegularExpressions.Regex regexCommand2 = new System.Text.RegularExpressions.Regex(
|
|
@"(?<effet>\d+)(?<params>(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 < effets.Count)
|
|
ChangeEffetCourrant (effet);
|
|
}
|
|
|
|
if (cmd.Groups ["transition"].Success) {
|
|
int transition = int.Parse (cmd.Groups ["transition"].Value);
|
|
tempsTransition = TimeSpan.FromMilliseconds( transition *100);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|