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;
            }
        }
Beispiel #2
0
        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);
        }