loupiottes/DMX-2.0/OSCServer.cs
2018-10-04 17:12:24 +02:00

367 lines
8.8 KiB
C#

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Generic;
namespace DMX2
{
public class OSCServer : IDisposable
{
UdpClient udpCli=null;
Thread pollThread = null;
bool running=true;
public OSCServer ()
{
pollThread = new Thread(new ThreadStart(Loop));
pollThread.Start();
}
void Loop ()
{
udpCli = new UdpClient (7772);
byte[] recv;
IPEndPoint remep = new IPEndPoint (IPAddress.Any, 0);
try {
while (running) {
recv = udpCli.Receive (ref remep);
//Console.WriteLine(remep);
OSCMessage msg = new OSCMessage(recv);
#if DEBUG
Console.Write(msg.Address);
Console.Write(" ");
foreach(var arg in msg.Args)
Console.WriteLine(arg.GetString());
#endif
try{
ProcessMessage(msg,remep);
}catch{}
}
} catch (SocketException ex) {
}
finally {
}
}
/// <summary>
/// /master <X---
/// /masterseq/
/// go
/// goback
/// next <X---
/// goto
///
/// /seq/X/
/// go
/// goback
/// goto
/// master <X---
/// circuit/X <X---
///
/// /universe/X/
/// on/D
/// off
/// onval
///
///
/// </summary>
void ProcessMessage (OSCMessage msg,IPEndPoint remep)
{
if(Conduite.Courante == null) return;
string[] toks = msg.Address.Split (new char[]{'/'},StringSplitOptions.RemoveEmptyEntries);
int arg;
switch (toks [0]) {
case "refresh":
IPEndPoint ep = new IPEndPoint(remep.Address,msg.Args[0].GetInt());
SendRefresh(ep);
break;
case "master":
arg = msg.Args[0].GetInt();
if (arg<0) arg=0;
if (arg>100)arg=100;
Conduite.Courante.Master = arg;
break;
case "masterseq":
switch(toks[1]){
case "go":
if( msg.Args[0].GetInt() !=0)
Conduite.Courante.SequenceurMaitre.EffetSuivant();
break;
case "goback":
if( msg.Args[0].GetInt() !=0)
Conduite.Courante.SequenceurMaitre.EffetPrecedent();
break;
case "next":
arg = msg.Args[0].GetInt();
Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre = arg;
break;
case "goto":
arg = msg.Args[0].GetInt();
Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre = arg;
Conduite.Courante.SequenceurMaitre.EffetSuivant();
break;
}
break;
case "seq":
ProcessMessageSeq(msg,toks);
break;
case "universe":
ProcessMessageUniv(msg,toks);
break;
case "circuitTel":
ProcessMessageCircuit(msg,toks);
break;
}
}
void ProcessMessageSeq (OSCMessage msg, string[] toks)
{
int seqId;
Sequenceur seq = null;
if (int.TryParse (toks [1], out seqId)) {
if (seqId < 0 || seqId > Conduite.Courante.Sequenceurs.Count)
return;
seq = Conduite.Courante.Sequenceurs [seqId-1];
}
if (seq is SequenceurLineaire) {
SequenceurLineaire seql = seq as SequenceurLineaire;
switch(toks[2]){
case "go":
if( msg.Args[0].GetInt() !=0)
seql.IndexEffetCourrant++;
break;
case "goback":
if( msg.Args[0].GetInt() !=0)
seql.IndexEffetCourrant--;
break;
case "goto":
int arg = msg.Args[0].GetInt();
seql.IndexEffetCourrant = arg;
break;
case "master":
arg = msg.Args[0].GetInt();
if (arg<0) arg=0;
if (arg>100)arg=100;
seql.Master = arg;
break;
case "circuit":
int cirId;
arg = msg.Args[0].GetInt();
arg = Math.Max(0,arg);
arg = Math.Min(255,arg);
if(!int.TryParse(toks[3],out cirId)) return;
Circuit c = Conduite.Courante.GetCircuitByID (cirId);
if(seql.Circuits.Contains(c))
seql.ChangeValeur(c,arg);
break;
}
}
if (seq is SequenceurMacro) {
SequenceurMacro seqm = seq as SequenceurMacro;
switch(toks[2]){
case "go":
if( msg.Args[0].GetInt() !=0)
seqm.LigneSuivante();
break;
case "goto":
int arg = msg.Args[0].GetInt();
seqm.IndexLigneaSuivre = arg;
seqm.LigneSuivante();
break;
case "next":
arg = msg.Args[0].GetInt();
seqm.IndexLigneaSuivre = arg;
break;
case "master":
arg = msg.Args[0].GetInt();
if (arg<0) arg=0;
if (arg>100)arg=100;
seqm.Master = arg;
break;
}
}
if (seq is SequenceurSon) {
SequenceurSon seqs = seq as SequenceurSon;
switch(toks[2]){
case "master":
int arg = msg.Args[0].GetInt();
if (arg<0) arg=0;
if (arg>100)arg=100;
seqs.Volume = (uint)arg;
break;
}
}
}
void ProcessMessageUniv (OSCMessage msg, string[] toks)
{
int univId;
if (!int.TryParse (toks [1], out univId))
return;
if (univId <= 0 || univId > Conduite.Courante.Patches.Count)
return;
UniversDMX univ = Conduite.Courante.Patches [univId-1];
switch (toks [2]) {
case "on":
int dimId;
if(!int.TryParse(toks[3],out dimId))return;
if( msg.Args[0].GetInt() !=0)
if(!univ.AllumageForce.Contains(dimId))
univ.AllumageForce.Add(dimId);
break;
case "off":
if(!int.TryParse(toks[3],out dimId))return;
if( msg.Args[0].GetInt() !=0)
if(univ.AllumageForce.Contains(dimId))
univ.AllumageForce.Remove(dimId);
break;
case "alloff":
univ.AllumageForce.Clear();
break;
case "onval":
int val = msg.Args[0].GetInt();
if(val<0) val=0;
if(val>255) val=255;
univ.AllumageForceVal = val;
break;
}
}
void ProcessMessageCircuit (OSCMessage msg, string[] toks)
{
switch (toks [1]) {
case "on":
{
int cirId;
if (!int.TryParse (toks [2], out cirId))
return;
if (msg.Args [0].GetInt () != 0) {
if (cirId > 0 && cirId <= Conduite.Courante.Circuits.Count) {
Circuit c = Conduite.Courante.Circuits [cirId - 1];
if (!Conduite.Courante.CircuitTelecomande.Contains (c))
Conduite.Courante.CircuitTelecomande.Add (c);
}
}
}
break;
case "off":
{
int cirId;
if (!int.TryParse (toks [2], out cirId))
return;
if (msg.Args [0].GetInt () != 0) {
if (cirId > 0 && cirId <= Conduite.Courante.Circuits.Count) {
Circuit c = Conduite.Courante.Circuits [cirId - 1];
if (Conduite.Courante.CircuitTelecomande.Contains (c))
Conduite.Courante.CircuitTelecomande.Remove (c);
}
}
}
break;
case "alloff":
Conduite.Courante.CircuitTelecomande.Clear();
break;
case "onval":
int val = msg.Args[0].GetInt();
if(val<0) val=0;
if(val>255) val=255;
Conduite.Courante.CircuitTelecomandeVal = val;
break;
}
}
void SendRefresh (IPEndPoint ep)
{
OSCMessage msg = new OSCMessage ("/master");
msg.AddFloat (Conduite.Courante.Master);
byte[] buff = msg.Encode ();
udpCli.Send (buff, buff.Length, ep);
var id = Conduite.Courante.SequenceurMaitre.IndexLigneEnCours - 1;
msg = new OSCMessage ("/masterseq/prevstep");
if (id >= 0) {
msg.AddString (
string.Format ("{0}. {1}", id + 1,
Conduite.Courante.SequenceurMaitre.Lignes [id].Nom)
);
} else {
msg.AddString ("---");
}
buff = msg.Encode ();
udpCli.Send (buff, buff.Length, ep);
id = Conduite.Courante.SequenceurMaitre.IndexLigneEnCours;
string auto = string.Empty;
msg = new OSCMessage ("/masterseq/curstep");
if (id >= 0) {
msg.AddString (
string.Format ("{0}. {1}", id + 1,
Conduite.Courante.SequenceurMaitre.Lignes [id].Nom)
);
if(Conduite.Courante.SequenceurMaitre.Lignes[id].Duree!= TimeSpan.Zero)
auto = string.Format(" (AUTO {0})",Conduite.Courante.SequenceurMaitre.Lignes[id].Duree.TotalMilliseconds/100);
} else {
msg.AddString ("---");
}
buff = msg.Encode();
udpCli.Send (buff, buff.Length, ep);
id = Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre;
if (id == -1)
id = Conduite.Courante.SequenceurMaitre.IndexLigneEnCours + 1;
msg = new OSCMessage ("/masterseq/nextstep");
if (id >= 0 && id < Conduite.Courante.SequenceurMaitre.Lignes.Count) {
msg.AddString (
string.Format ("{0}. {1}{2}", id + 1,
Conduite.Courante.SequenceurMaitre.Lignes [id].Nom,auto)
);
} else {
msg.AddString ("---");
}
buff = msg.Encode ();
udpCli.Send (buff, buff.Length, ep);
msg = new OSCMessage("/masterseq/time");
msg.AddFloat(((float) Conduite.Courante.SequenceurMaitre.TimeStamp.TotalMilliseconds/1000 ));
buff = msg.Encode();
udpCli.Send (buff, buff.Length, ep);
}
#region IDisposable implementation
public void Dispose ()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose (bool disposing)
{
if (disposing) {
running=false;
if(udpCli!=null)
udpCli.Close();
if(pollThread!=null)
{
if(!pollThread.Join(100))
pollThread.Abort();
pollThread=null;
}
}
}
#endregion
}
}