1.1 --- a/Server/MainForm.cs Fri Aug 15 13:26:38 2014 +0200
1.2 +++ b/Server/MainForm.cs Sat Aug 16 11:15:42 2014 +0200
1.3 @@ -20,6 +20,27 @@
1.4
1.5 namespace SharpDisplayManager
1.6 {
1.7 + /// <summary>
1.8 + /// A UI thread copy of a client relevant data.
1.9 + /// Keeping this copy in the UI thread helps us deal with threading issues.
1.10 + /// </summary>
1.11 + public class ClientData
1.12 + {
1.13 + public ClientData(string aSessionId, IDisplayServiceCallback aCallback)
1.14 + {
1.15 + SessionId = aSessionId;
1.16 + Name = "";
1.17 + Texts = new List<string>();
1.18 + Callback = aCallback;
1.19 + }
1.20 +
1.21 + public string SessionId { get; set;}
1.22 + public string Name { get; set;}
1.23 + public List<string> Texts { get; set;}
1.24 + public IDisplayServiceCallback Callback { get; set;}
1.25 + }
1.26 +
1.27 +
1.28 public partial class MainForm : Form
1.29 {
1.30 DateTime LastTickTime;
1.31 @@ -30,14 +51,14 @@
1.32 /// <summary>
1.33 /// Our collection of clients
1.34 /// </summary>
1.35 - public Dictionary<string, IDisplayServiceCallback> iClients;
1.36 + public Dictionary<string, ClientData> iClients;
1.37 public bool iClosing;
1.38
1.39 public MainForm()
1.40 {
1.41 LastTickTime = DateTime.Now;
1.42 iDisplay = new Display();
1.43 - iClients = new Dictionary<string, IDisplayServiceCallback>();
1.44 + iClients = new Dictionary<string, ClientData>();
1.45
1.46 InitializeComponent();
1.47 UpdateStatus();
1.48 @@ -406,7 +427,7 @@
1.49 try
1.50 {
1.51 Trace.TraceInformation("BroadcastCloseEvent - " + client.Key);
1.52 - client.Value.OnCloseOrder(/*eventData*/);
1.53 + client.Value.Callback.OnCloseOrder(/*eventData*/);
1.54 }
1.55 catch (Exception ex)
1.56 {
1.57 @@ -454,6 +475,7 @@
1.58
1.59 }
1.60
1.61 + //Delegates are used for our thread safe method
1.62 public delegate void AddClientDelegate(string aSessionId, IDisplayServiceCallback aCallback);
1.63 public delegate void RemoveClientDelegate(string aSessionId);
1.64 public delegate void SetTextDelegate(int aLineIndex, string aText);
1.65 @@ -468,7 +490,7 @@
1.66 /// <param name="aCallback"></param>
1.67 public void AddClientThreadSafe(string aSessionId, IDisplayServiceCallback aCallback)
1.68 {
1.69 - if (this.treeViewClients.InvokeRequired)
1.70 + if (this.InvokeRequired)
1.71 {
1.72 //Not in the proper thread, invoke ourselves
1.73 AddClientDelegate d = new AddClientDelegate(AddClientThreadSafe);
1.74 @@ -478,9 +500,10 @@
1.75 {
1.76 //We are in the proper thread
1.77 //Add this session to our collection of clients
1.78 - Program.iMainForm.iClients.Add(aSessionId, aCallback);
1.79 + ClientData newClient = new ClientData(aSessionId, aCallback);
1.80 + Program.iMainForm.iClients.Add(aSessionId, newClient);
1.81 //Add this session to our UI
1.82 - Program.iMainForm.treeViewClients.Nodes.Add(aSessionId, aSessionId);
1.83 + UpdateClientTreeViewNode(newClient);
1.84 }
1.85 }
1.86
1.87 @@ -490,7 +513,7 @@
1.88 /// <param name="aSessionId"></param>
1.89 public void RemoveClientThreadSafe(string aSessionId)
1.90 {
1.91 - if (this.treeViewClients.InvokeRequired)
1.92 + if (this.InvokeRequired)
1.93 {
1.94 //Not in the proper thread, invoke ourselves
1.95 RemoveClientDelegate d = new RemoveClientDelegate(RemoveClientThreadSafe);
1.96 @@ -499,7 +522,7 @@
1.97 else
1.98 {
1.99 //We are in the proper thread
1.100 - //Remove this session from both client collection and UI tree view
1.101 + //Remove this session from both client collection and UI tree view
1.102 if (Program.iMainForm.iClients.Keys.Contains(aSessionId))
1.103 {
1.104 Program.iMainForm.iClients.Remove(aSessionId);
1.105 @@ -524,7 +547,7 @@
1.106 /// <param name="aText"></param>
1.107 public void SetTextThreadSafe(int aLineIndex, string aText)
1.108 {
1.109 - if (this.treeViewClients.InvokeRequired)
1.110 + if (this.InvokeRequired)
1.111 {
1.112 //Not in the proper thread, invoke ourselves
1.113 SetTextDelegate d = new SetTextDelegate(SetTextThreadSafe);
1.114 @@ -536,11 +559,11 @@
1.115 //Only support two lines for now
1.116 if (aLineIndex == 0)
1.117 {
1.118 - Program.iMainForm.marqueeLabelTop.Text = aText;
1.119 + marqueeLabelTop.Text = aText;
1.120 }
1.121 else if (aLineIndex == 1)
1.122 {
1.123 - Program.iMainForm.marqueeLabelBottom.Text = aText;
1.124 + marqueeLabelBottom.Text = aText;
1.125 }
1.126 }
1.127 }
1.128 @@ -551,7 +574,7 @@
1.129 /// <param name="aTexts"></param>
1.130 public void SetTextsThreadSafe(System.Collections.Generic.IList<string> aTexts)
1.131 {
1.132 - if (this.treeViewClients.InvokeRequired)
1.133 + if (this.InvokeRequired)
1.134 {
1.135 //Not in the proper thread, invoke ourselves
1.136 SetTextsDelegate d = new SetTextsDelegate(SetTextsThreadSafe);
1.137 @@ -565,11 +588,11 @@
1.138 {
1.139 if (i == 0)
1.140 {
1.141 - Program.iMainForm.marqueeLabelTop.Text = aTexts[i];
1.142 + marqueeLabelTop.Text = aTexts[i];
1.143 }
1.144 else if (i == 1)
1.145 {
1.146 - Program.iMainForm.marqueeLabelBottom.Text = aTexts[i];
1.147 + marqueeLabelBottom.Text = aTexts[i];
1.148 }
1.149 }
1.150 }
1.151 @@ -592,17 +615,73 @@
1.152 else
1.153 {
1.154 //We are in the proper thread
1.155 - //Remove this session from both client collection and UI tree view
1.156 - if (Program.iMainForm.iClients.Keys.Contains(aSessionId))
1.157 + //Get our client
1.158 + ClientData client = iClients[aSessionId];
1.159 + if (client != null)
1.160 {
1.161 - //Change our session node text
1.162 - TreeNode node = Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0];
1.163 - node.Text = aName;
1.164 + //Set its name
1.165 + client.Name = aName;
1.166 + //Update our tree-view
1.167 + UpdateClientTreeViewNode(client);
1.168 + }
1.169 + }
1.170 + }
1.171 +
1.172 + /// <summary>
1.173 + ///
1.174 + /// </summary>
1.175 + /// <param name="aClient"></param>
1.176 + private void UpdateClientTreeViewNode(ClientData aClient)
1.177 + {
1.178 + if (aClient == null)
1.179 + {
1.180 + return;
1.181 + }
1.182 +
1.183 + TreeNode node = null;
1.184 + //Check that our client node already exists
1.185 + //Get our client root node using its key which is our session ID
1.186 + TreeNode[] nodes = treeViewClients.Nodes.Find(aClient.SessionId, false);
1.187 + if (nodes.Count()>0)
1.188 + {
1.189 + //We already have a node for that client
1.190 + node = nodes[0];
1.191 + //Clear children as we are going to recreate them below
1.192 + node.Nodes.Clear();
1.193 + }
1.194 + else
1.195 + {
1.196 + //Client node does not exists create a new one
1.197 + treeViewClients.Nodes.Add(aClient.SessionId, aClient.SessionId);
1.198 + node = treeViewClients.Nodes.Find(aClient.SessionId, false)[0];
1.199 + }
1.200 +
1.201 + if (node != null)
1.202 + {
1.203 + //Change its name
1.204 + if (aClient.Name != "")
1.205 + {
1.206 + //We have a name, us it as text for our root node
1.207 + node.Text = aClient.Name;
1.208 //Add a child with SessionId
1.209 - node.Nodes.Add(new TreeNode(aSessionId));
1.210 -
1.211 - //Program.iMainForm.iClients.Remove(aSessionId);
1.212 - //Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]);
1.213 + node.Nodes.Add(new TreeNode(aClient.SessionId));
1.214 + }
1.215 + else
1.216 + {
1.217 + //No name, use session ID instead
1.218 + node.Text = aClient.SessionId;
1.219 + }
1.220 +
1.221 + if (aClient.Texts.Count > 0)
1.222 + {
1.223 + //Create root node for our texts
1.224 + TreeNode textsRoot = new TreeNode("Text");
1.225 + node.Nodes.Add(textsRoot);
1.226 + //For each text add a new entry
1.227 + foreach (string text in aClient.Texts)
1.228 + {
1.229 + textsRoot.Nodes.Add(new TreeNode(text));
1.230 + }
1.231 }
1.232 }
1.233 }