private void FlushPackets(int stylusId, int strokeId) { using (Synchronizer.Lock(this)) { List <int> buffer; if (this.PacketBuffers.TryGetValue(stylusId, out buffer) && buffer.Count != 0) { int[] packets = buffer.ToArray(); buffer.Clear(); if (ViewerStateModel.NonStandardDpi) { RealTimeInkSheetModel.ScalePackets(packets, ViewerStateModel.DpiNormalizationSendMatrix); } // FIXME: Dispatch to the SendingQueue's thread. Message message = new RealTimeInkSheetPacketsMessage(this.m_Sheet, stylusId, strokeId, packets); message.Tags = new MessageTags(); message.Tags.SlideID = m_SlideID; message.Tags.Priority = MessagePriority.RealTime; message.Tags.BridgePriority = MessagePriority.RealTime; this.Sender.Send(message, MessagePriority.RealTime); } this.PacketFlushTimes[stylusId] = DateTime.Now.Ticks; } }
protected override MergeAction MergeInto(Message other_) { if (other_ is RealTimeInkSheetPacketsMessage) { RealTimeInkSheetPacketsMessage other = ((RealTimeInkSheetPacketsMessage)other_); if (this.StylusId == other.StylusId && this.StrokeId == other.StrokeId) { this.Packets = ConcatenatePackets(other.Packets, this.Packets); return(MergeAction.DiscardOther); } } return(base.MergeInto(other_)); }
private void FlushPackets(int stylusId, int strokeId) { using(Synchronizer.Lock(this)) { List<int> buffer; if(this.PacketBuffers.TryGetValue(stylusId, out buffer) && buffer.Count != 0) { int[] packets = buffer.ToArray(); buffer.Clear(); if (ViewerStateModel.NonStandardDpi) { RealTimeInkSheetModel.ScalePackets(packets, ViewerStateModel.DpiNormalizationSendMatrix); } // FIXME: Dispatch to the SendingQueue's thread. Message message = new RealTimeInkSheetPacketsMessage(this.m_Sheet, stylusId, strokeId, packets); message.Tags = new MessageTags(); message.Tags.SlideID = m_SlideID; message.Tags.Priority = MessagePriority.RealTime; message.Tags.BridgePriority = MessagePriority.RealTime; this.Sender.Send(message, MessagePriority.RealTime); } this.PacketFlushTimes[stylusId] = DateTime.Now.Ticks; } }
/// <summary> /// Translate real-time ink packets to a stroke and return RTStrokeAdded. /// </summary> /// <param name="rtispm"></param> /// <returns></returns> internal object AddRealTimeInkSheetPackets(UW.ClassroomPresenter.Network.Messages.Presentation.RealTimeInkSheetPacketsMessage rtispm) { //Resolve the sheetId to a slideId, and use it to look up a TOC entry. if (!sheetToSlideLookup.ContainsKey(rtispm.TargetId)) { if (this.currentSlideId.Equals(Guid.Empty)) { warning += "Warning: found real-time ink on an unknown sheet. Ignoring the ink. "; return(null); } //Can we assume current slide?? Probably.. sheetToSlideLookup.Add(rtispm.TargetId, currentSlideId); } TableOfContents.TocEntry tocEntry = toc.LookupBySlideId((Guid)sheetToSlideLookup[rtispm.TargetId]); if (tocEntry == null) { warning += "Warning: Failed to find a TOC entry for a slide when applying real-time ink. Ignoring the ink. "; return(null); } //Tablet Properties should have been received in a StylusDown message. if (previousTabletProperties == null) { warning += "Warning: Received real-time ink without tablet properties. Ignoring the ink. "; return(null); } //Debug.WriteLine("***** Realtime Ink packets StrokeID=" + rtispm.StrokeId.ToString() + "; stylusId=" + rtispm.StylusId.ToString()); // Verify that the stroke we're about to render matches the StrokeId // from the most recent StylusDown event. (If not, then something // probably got lost over the network.) if (this.previousRealTimeStroke != rtispm.StrokeId) { previousRealTimeStroke = rtispm.StrokeId; previousRealTimePackets = new int[] { }; } // Get the DrawingAttributes which were in effect on StylusDown. We should have received this in a // RealTimeInkSheetInformationMessage previously. if (!this.sheetToDrawingAttributesLookup.ContainsKey(rtispm.TargetId)) { //Note: this seems to happen all the time, but I don't notice any ill effects. Ignore the ink but leave out the warning. //this.warning += "Warning: Real-time ink was found that lacks DrawingAttributes. The ink will be ignored. "; return(null); } DrawingAttributes atts = (DrawingAttributes)this.sheetToDrawingAttributesLookup[rtispm.TargetId]; // Ink packets for this stroke so far. Initial packets should have been received in the Stylus Down message. if (this.previousRealTimePackets == null) { this.warning += "Warning: Failed to find previous real-time ink packets. The ink will be ignored. "; return(null); } // Assemble the completed information we'll need to create the mini-stroke. int[] combinedPackets = new int[this.previousRealTimePackets.Length + rtispm.Packets.Length]; this.previousRealTimePackets.CopyTo(combinedPackets, 0); rtispm.Packets.CopyTo(combinedPackets, this.previousRealTimePackets.Length); // Store the new data. this.previousRealTimePackets = combinedPackets; // Now that we have the data, we're ready to create the temporary stroke. Ink ink = new Ink(); Stroke stroke = ink.CreateStroke(combinedPackets, previousTabletProperties); stroke.DrawingAttributes = atts; //Look up the data for this stroke, or assign a new Guid if needed. RTStrokeData rtsData; if (!realTimeStrokesPending.TryGetValue(rtispm.StrokeId, out rtsData)) { rtsData = new RTStrokeData(Guid.NewGuid(), tocEntry.DeckId, tocEntry.SlideIndex); realTimeStrokesPending.Add(rtispm.StrokeId, rtsData); } Guid strokeId = rtsData.StrokeId; //WebViewer requires the CP2 extended property to allow deletion of the stroke ink.Strokes[0].ExtendedProperties.Add(CP2StrokeIdExtendedProperty, (object)strokeId.ToString()); //WebViewer wants ink to be scaled to 500x500 ink.Strokes.Scale(500f / getCurrentSlideWidth(), 500f / getCurrentSlideHeight()); Debug.WriteLine("***** Adding Real-time Stroke ID=" + strokeId.ToString()); RTDrawStroke rtds = new RTDrawStroke(ink, strokeId, false, tocEntry.DeckId, tocEntry.SlideIndex); return(rtds); }