/// <summary> /// Append a contact to the list of contacts in this report. Note you cannot call this more than 'MaxContactsPerReport' per report. /// </summary> /// <param name="pContact">The contact to add.</param> public void addContact(HidContactInfo pContact) { // If we have reached the maximum number of contacts - throw an error. if (lContacts.Count == MaxContactsPerReport) { throw new InvalidOperationException("Cannot add more than " + MaxContactsPerReport + " to a MultiTouchReport."); } // All is well so add it. lContacts.Add(pContact); }
/// <summary> /// This is called to enqueue a HID contact onto the list to send out. /// </summary> /// <param name="contactInfo"></param> private void enqueueContact(HidContactInfo pContact) { // Obtain mutual exclusion over the queue. this.pContactLock.WaitOne(); // Add it to the queue. this.lCurrentContacts.Enqueue(pContact); // Release exclusion. this.pContactLock.ReleaseMutex(); }
/// <summary> /// Calling this will send all the currently queued contacts off to the HID driver. /// </summary> public void sendContacts() { // Build the list of contacts to send. List <HidContactInfo> lContacts = new List <HidContactInfo>(); // Get mutual exclusion over the queue. this.pContactLock.WaitOne(); // While there are still contacts to deal with... while (this.lCurrentContacts.Count > 0) { // Pop the one off the start of the queue. HidContactInfo pContact = this.lCurrentContacts.Dequeue(); // If there is a previous contact it had a remove signal then we want to ignore the event. HidContactInfo pPreviousContact; if (this.dLastContacts.TryGetValue(pContact.Id, out pPreviousContact)) { // If we got an update for the new contact and a remove in the previous state then drop the contact. if (pContact.State == HidContactState.Updated && pPreviousContact.State == HidContactState.Removing) { continue; } } // Update the contact list to contain the latest reference. this.dLastContacts[pContact.Id] = pContact; // Append it to the list of contacts we want to ship out. lContacts.Add(pContact); } // Release access to the queue. this.pContactLock.ReleaseMutex(); // Add all existing contacts in the table to the send-list which are not already in there and set to update. lContacts.AddRange(this.dLastContacts.Values.Except(lContacts, this.pComparer).Where(c => c.State == HidContactState.Updated).ToList()); // If we have more than one contact after all that... if (lContacts.Count > 0) { this.sendContacts(lContacts); } // Remove all active contacts which are flagged as removed from the table. // TODO: Perhaps put a watchdog do to this but with a timeout? foreach (ushort id in this.dLastContacts.Values.Where(c => c.State == HidContactState.Removed).Select(c => c.Id).ToList()) { this.dLastContacts.Remove(id); } // Queue up all contacts which are flagged as removing and send a remove event. foreach (HidContactInfo pContact in this.dLastContacts.Values.Where(c => c.State == HidContactState.Removing).ToList()) { this.enqueueContact(new HidContactInfo(HidContactState.Removed, pContact.Contact)); } // Queue up all contacts which are flagged as added and send an updated event. foreach (HidContactInfo pContact in this.dLastContacts.Values.Where(c => c.State == HidContactState.Adding).ToList()) { this.enqueueContact(new HidContactInfo(HidContactState.Updated, pContact.Contact)); } }