Update to latest version of NAudio and SharpLibHid.
2 // Copyright (C) 2014-2015 Stéphane Lenclud.
4 // This file is part of SharpDisplayManager.
6 // SharpDisplayManager is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
11 // SharpDisplayManager is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with SharpDisplayManager. If not, see <http://www.gnu.org/licenses/>.
21 using System.Collections.Generic;
24 using System.Threading.Tasks;
25 using System.Windows.Forms;
27 using System.ServiceModel;
28 using System.ServiceModel.Channels;
31 namespace SharpDisplayClient
36 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
37 public class Callback : ICallback, IDisposable
39 private MainForm MainForm { get; set; }
41 public Callback(MainForm aMainForm)
46 public void OnConnected()
48 //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);
49 //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId);
51 MessageBox.Show("OnConnected()", "Client");
55 public void OnCloseOrder()
57 //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);
58 //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId);
60 //MessageBox.Show("OnServerClosing()", "Client");
61 MainForm.CloseConnectionThreadSafe();
62 MainForm.CloseThreadSafe();
76 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
77 public class Client : DuplexClientBase<IService>
79 public string SessionId { get { return InnerChannel.SessionId; } }
81 public Client(ICallback aCallback)
82 : base(new InstanceContext(aCallback), new NetTcpBinding(SecurityMode.None, true), new EndpointAddress("net.tcp://localhost:8001/DisplayService"))
85 public void SetName(string aClientName)
87 Channel.SetName(aClientName);
90 public void SetLayout(TableLayout aLayout)
92 Channel.SetLayout(aLayout);
95 public void SetField(DataField aField)
97 Channel.SetField(aField);
100 public void SetFields(System.Collections.Generic.IList<DataField> aFields)
102 Channel.SetFields(aFields);
105 public int ClientCount()
107 return Channel.ClientCount();
110 public bool IsReady()
112 return State == CommunicationState.Opened || State == CommunicationState.Created;
118 /// Handle connection with our Sharp Display Server.
119 /// If the connection is faulted it will attempt to restart it.
121 public class DisplayClient
123 private Client iClient;
124 private Callback iCallback;
125 private bool resetingConnection = false;
127 private MainForm MainForm { get; set; }
128 public string SessionId { get { return iClient.SessionId; } }
129 public string Name { get; private set; }
130 private TableLayout Layout { get; set; }
131 private System.Collections.Generic.IList<DataField> Fields { get; set; }
134 public DisplayClient(MainForm aMainForm)
136 MainForm = aMainForm;
138 Fields = new DataField[]{};
142 /// Initialize our server connection.
146 iCallback = new Callback(MainForm);
147 iClient = new Client(iCallback);
151 /// Terminate our server connection.
162 /// Tells whether a server connection is available.
164 /// <returns>True if a server connection is available. False otherwise.</returns>
165 public bool IsReady()
167 return (iClient != null && iCallback != null && iClient.IsReady());
171 /// Check if our server connection is available and attempt reset it if it isn't.
172 /// This is notably dealing with timed out connections.
174 public void CheckConnection()
176 if (!IsReady() && !resetingConnection)
181 //Avoid stack overflow in case of persisting failure
182 resetingConnection = true;
186 //On reconnect there is a bunch of properties we need to reset
189 iClient.SetName(Name);
193 iClient.SetFields(Fields);
197 //Make sure our this state does not get out of sync
198 resetingConnection = true;
203 public void SetName(string aClientName)
207 iClient.SetName(aClientName);
211 public void SetLayout(TableLayout aLayout)
215 iClient.SetLayout(aLayout);
219 /// Set the specified field.
221 /// <param name="aField"></param>
222 /// <returns>True if the specified field was set client side. False means you need to redefine all your fields using CreateFields.</returns>
223 public bool SetField(DataField aField)
226 bool fieldFound = false;
227 foreach (DataField field in Fields)
229 if (field.Index == aField.Index)
231 //Update our field then
241 //Field not found, make to use SetFields with all your fields at least once after setting your layout.
246 iClient.SetField(aField);
251 /// Use this function when updating existing fields.
253 /// <param name="aFields"></param>
254 public bool SetFields(System.Collections.Generic.IList<DataField> aFields)
256 int fieldFoundCount = 0;
257 foreach (DataField fieldUpdate in aFields)
260 foreach (DataField existingField in Fields)
262 if (existingField.Index == fieldUpdate.Index)
264 //Update our field then
265 Fields[i] = fieldUpdate;
267 //Move on to the next field
275 if (fieldFoundCount!=aFields.Count)
277 //Field not found, make sure to use SetFields with all your fields at least once after setting your layout.
282 iClient.SetFields(aFields);
287 /// Use this function when creating your fields.
289 /// <param name="aFields"></param>
290 public void CreateFields(System.Collections.Generic.IList<DataField> aFields)
294 iClient.SetFields(aFields);
297 public int ClientCount()
300 return iClient.ClientCount();