private void SendSlideInformation(SlideModel slide, Group receivers) { Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); // Ensure that nothing about the slide can change between sending the slide's information // and creating the SlideNetworkService to listen for changes. // TODO: Find a way to also ensure that nothing about the SheetModels change either, but this is less of a concern. using (Synchronizer.Lock(this.m_SlideNetworkServices.SyncRoot)) { using (Synchronizer.Lock(slide.SyncRoot)) { deck.InsertChild(new SlideInformationMessage(slide)); message.Tags = new MessageTags(); message.Tags.SlideID = slide.Id; this.m_Sender.Send(message); if (!this.m_SlideNetworkServices.ContainsKey(slide)) { SlideNetworkService service = new SlideNetworkService(this.m_Sender, this.m_Presentation, this.m_Deck, slide); this.m_SlideNetworkServices.Add(slide, service); } } } }
private void SendImageHelper(Group receivers) { //Don't send message if it's an instructor note. if (this.sheet_.Disposition != SheetDisposition.Instructor) { Message message, deck, slide; message = new PresentationInformationMessage(this.Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); slide.InsertChild(new ImageSheetMessage(this.sheet_, this.SheetCollectionSelector)); using (Synchronizer.Lock(m_SlideModel.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = m_SlideModel.Id; } if (this.sheet_.Image != null) { using (Synchronizer.Lock(this.sheet_.SyncRoot)) { this.Sender.Send(message); } } else { this.Sender.Send(message); } } }
/// <summary> /// The only thing in this message that we might care about is the background color. /// If the color changed and the current slide has no explicit background color set, /// then we want to send a RTUpdate. Otherwise, just note the new background color. /// </summary> /// <param name="dim"></param> /// <returns></returns> internal object UpdateDeckInformation(CP3Msgs.DeckInformationMessage dim) { bool sendRTUpdate = false; if (!toc.DeckBackgroundColors.ContainsKey((Guid)dim.TargetId)) { toc.DeckBackgroundColors.Add((Guid)dim.TargetId, dim.DeckBackgroundColor); //If set and non-white we need to issue a RTUpdate for the current slide. if ((!dim.DeckBackgroundColor.Equals(Color.White)) && (!dim.DeckBackgroundColor.Equals(Color.Empty))) { sendRTUpdate = true; } } else { if (!toc.DeckBackgroundColors[(Guid)dim.TargetId].Equals(dim.DeckBackgroundColor)) { toc.DeckBackgroundColors[(Guid)dim.TargetId] = dim.DeckBackgroundColor; //Color change, issue a RTUpdate for current slide. sendRTUpdate = true; } } if (sendRTUpdate) { return(toc.GetRtUpdateForSlideId(this.currentSlideId)); } return(null); }
private void HandleSlideContentAdded(object sender, PropertyEventArgs args_) { PropertyCollectionEventArgs args = ((PropertyCollectionEventArgs)args_); ByteArray hash = ((ByteArray)args.Added); // For the purposes of ForceUpdate, this information is sent by SendAllSlidesAndContent. Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); deck.InsertChild(new DeckSlideContentMessage(this.m_Deck, hash)); if ((this.m_Deck.Disposition & (DeckDisposition.StudentSubmission | DeckDisposition.QuickPoll)) != 0) { // If we get here in response to a new student submission received // we don't need to send anything because we can assume the public display // already has the slide, however if the instructor manually adds new // slides to a student submission deck, the public display may not have them. // For now we send in both cases, but that could be improved. // In any case we only send slides from a Student Submission deck to Public nodes. message.Group = Group.Submissions; } this.m_Sender.Send(message, MessagePriority.Low); }
private void SendAllSlidesAndContent(Group receivers) { using (Synchronizer.Lock(this.m_Deck.SyncRoot)) { foreach (SlideModel slide in this.m_Deck.Slides) { this.SendSlideInformation(slide, receivers); } foreach (ByteArray hash in this.m_Deck.SlideContentKeys) { Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); deck.InsertChild(new DeckSlideContentMessage(this.m_Deck, hash)); message.Tags = new MessageTags(); message.Tags.BridgePriority = MessagePriority.Lowest; SlideModel slide = this.m_Deck.GetSlideFromContent(hash); if (slide != null) { using (Synchronizer.Lock(slide.SyncRoot)) { message.Tags.SlideID = slide.Id; } } this.m_Sender.Send(message, MessagePriority.Low); } } }
public void SendSheetInformation(SheetModel sheet, SheetMessage.SheetCollection selector, Group receivers) { // TODO: Also pass the index so the sheet can be inserted into the correct index on the remote side. Message message, deck, slide; message = new PresentationInformationMessage(this.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.m_Slide)); Message sm = SheetMessage.RemoteForSheet(sheet, selector); //if sm is null that means that the sheet is an instructor note and shouldn't be sent. if (sm != null) { slide.InsertChild(sm); } using (Synchronizer.Lock(this.m_Slide.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = this.m_Slide.Id; } if (sheet is ImageSheetModel && ((ImageSheetModel)sheet).Image != null) { using (Synchronizer.Lock(sheet.SyncRoot)) { this.m_Sender.Send(message); } } else { this.m_Sender.Send(message); } }
/// <summary> /// This is similar to the texthelpermethod, but here we send a removal message /// if the message is private. I am having two different methods for the sake of seperating /// the two different types of messages. /// </summary> /// <param name="receivers"></param> private void SendPublicHelper(Group receivers) { Message message, deck, slide; message = new PresentationInformationMessage(this.Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); ///send the text message bool sheet_is_public; using (Synchronizer.Lock(sheet_.SyncRoot)) { sheet_is_public = sheet_.IsPublic; } ///if the sheet is private, the users should not be able to see any part of the sheet, ///so we should just remove a private sheet. if (sheet_is_public) { slide.InsertChild(new TextSheetMessage(this.sheet_, this.SheetCollectionSelector)); } else { slide.InsertChild(new SheetRemovedMessage(this.sheet_, this.SheetCollectionSelector)); } using (Synchronizer.Lock(this.Slide.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = this.Slide.Id; } this.Sender.Send(message); }
protected override void TearDownMember(int index, object member, object tag) { if (tag == null) { return; } SheetModel sheet = ((SheetModel)member); Message message, deck, slide; message = new PresentationInformationMessage(this.m_Service.m_Presentation); message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.m_Service.m_Slide)); slide.InsertChild(new SheetRemovedMessage(sheet, this.m_Selector)); using (Synchronizer.Lock(this.m_Service.m_Slide.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = this.m_Service.m_Slide.Id; } this.m_Service.m_Sender.Send(message); ((SheetNetworkService)tag).Dispose(); }
/// <summary> /// This is similar to the texthelpermethod, but here we send a removal message /// if the message is private. I am having two different methods for the sake of seperating /// the two different types of messages. /// </summary> /// <param name="receivers"></param> private void SendPublicHelper(Group receivers) { Message message, deck, slide; message = new PresentationInformationMessage(this.Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); ///send the text message bool sheet_is_public; using (Synchronizer.Lock(sheet_.SyncRoot)) { sheet_is_public = sheet_.IsPublic; } ///if the sheet is private, the users should not be able to see any part of the sheet, ///so we should just remove a private sheet. if (sheet_is_public) { slide.InsertChild(new TextSheetMessage(this.sheet_, this.SheetCollectionSelector)); } else { slide.InsertChild(new SheetRemovedMessage(this.sheet_, this.SheetCollectionSelector)); } using (Synchronizer.Lock(this.Slide.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = this.Slide.Id; } this.Sender.Send(message); }
private void HandleInkDeletingHelper(string[] ids) { Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(GetSubmissionSlideModel(), false)); slide.InsertChild(sheet = new InkSheetStrokesDeletingMessage(this.m_Sheet, this.SheetCollectionSelector, ids)); this.Sender.Send(message); }
private void HandleCurrentDrawingAttributesChanged(object sender, PropertyEventArgs args) { Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(GetSubmissionSlideModel(), false)); slide.InsertChild(sheet = SheetMessage.RemoteForSheet(this.Sheet, this.SheetCollectionSelector)); this.Sender.Send(message); }
private void SendEntryAdded(TableOfContentsModel.Entry entry, Group receivers) { Message message, deck, slide; message = new PresentationInformationMessage(this.m_Service.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck)); deck.InsertChild(slide = new SlideInformationMessage(entry.Slide)); slide.InsertChild(new TableOfContentsEntryMessage(entry)); this.m_Service.m_Sender.Send(message); }
private void HandleInkAddedHelper(Ink extracted) { Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(GetSubmissionSlideModel(), false)); slide.InsertChild(sheet = new InkSheetStrokesAddedMessage(this.m_Sheet, (Guid)slide.TargetId, this.SheetCollectionSelector, extracted)); sheet.AddOldestPredecessor(SheetMessage.RemoteForSheet(this.m_Sheet, this.SheetCollectionSelector)); this.Sender.Send(message); }
private void SendTraversalInformation(DeckTraversalModel traversal, Group receivers) { Message message, deck; message = new PresentationInformationMessage(this.m_Service.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(traversal.Deck)); deck.InsertChild(DeckTraversalMessage.ForDeckTraversal(traversal)); this.m_Service.m_Sender.Send(message); }
private void SendGenericChange(Group receivers) { // Send a generic update with information about the slide (including the new bounds/zoom). Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); deck.InsertChild(new SlideInformationMessage(this.m_Slide)); this.m_Sender.Send(message); }
private void HandleInkDeletingHelper(string[] ids) { Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); slide.InsertChild(sheet = new InkSheetStrokesDeletingMessage(this.m_Sheet, this.SheetCollectionSelector, ids)); message.Tags = new MessageTags(); message.Tags.SlideID = m_SlideID; message.Tags.BridgePriority = MessagePriority.Higher; this.Sender.Send(message); }
protected virtual void HandleBoundsChanged(object sender, PropertyEventArgs args) { // Send a generic update with information about the sheet (including the new bounds). Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); slide.InsertChild(sheet = SheetMessage.RemoteForSheet(this.Sheet, this.SheetCollectionSelector)); using (Synchronizer.Lock(this.m_Slide.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = this.m_Slide.Id; } this.Sender.Send(message); }
protected override void TearDownMember(int index, object member, object tag) { if (tag == null) { return; } TableOfContentsModel.Entry entry = ((TableOfContentsModel.Entry)member); Message message, deck, slide; message = new PresentationInformationMessage(this.m_Service.m_Presentation); message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck)); deck.InsertChild(slide = new SlideInformationMessage(entry.Slide)); slide.InsertChild(new TableOfContentsEntryRemovedMessage(entry)); this.m_Service.m_Sender.Send(message); }
private void SendTextHelper(Group receivers) { Message message, deck, slide; message = new PresentationInformationMessage(this.Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); ///send the text message slide.InsertChild(new TextSheetMessage(this.sheet_, this.SheetCollectionSelector)); using (Synchronizer.Lock(this.Slide.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = this.Slide.Id; } this.Sender.Send(message); }
private void SendCurrentChanged(Group receivers) { Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_DeckTraversal.Deck)); deck.InsertChild(DeckTraversalMessage.ForDeckTraversal(this.m_DeckTraversal)); #if DEBUG // Add logging of slide change events string pres_name = ""; using (Synchronizer.Lock(this.m_Presentation.SyncRoot)) pres_name = this.m_Presentation.HumanName; string deck_name = ""; using (Synchronizer.Lock(this.m_DeckTraversal.Deck.SyncRoot)) deck_name = this.m_DeckTraversal.Deck.HumanName; int slide_index = 0; Guid slide_guid = Guid.Empty; using (Synchronizer.Lock(this.m_DeckTraversal.SyncRoot)) { if (this.m_DeckTraversal.Current != null) { using (Synchronizer.Lock(this.m_DeckTraversal.Current.SyncRoot)) { slide_index = this.m_DeckTraversal.Current.IndexInParent; using (Synchronizer.Lock(this.m_DeckTraversal.Current.Slide.SyncRoot)) { slide_guid = this.m_DeckTraversal.Current.Slide.Id; } } } } Debug.WriteLine(string.Format("SLIDE CHANGE ({0}): Pres -- {1}, Deck -- {2}, Slide -- {3}, Guid -- {4}", System.DateTime.Now.Ticks, pres_name, deck_name, slide_index, slide_guid)); #endif message.Tags = new MessageTags(); message.Tags.BridgePriority = MessagePriority.Higher; this.m_Sender.Send(message); }
private void SendQuickPollSheetHelper( Group receivers ) { //Don't send message if it's an instructor note. if( this.sheet.Disposition != SheetDisposition.Instructor ) { Message message, deck, poll, slide; message = new PresentationInformationMessage( this.Presentation ); message.Group = receivers; message.InsertChild( deck = new DeckInformationMessage( this.Deck ) ); deck.InsertChild( slide = new SlideInformationMessage( this.Slide ) ); using( Synchronizer.Lock( this.Sheet.SyncRoot ) ) { slide.InsertChild( poll = new QuickPollInformationMessage( this.sheet.QuickPoll ) ); } poll.InsertChild( new QuickPollSheetMessage( this.sheet, this.SheetCollectionSelector ) ); using( Synchronizer.Lock( m_SlideModel.SyncRoot ) ) { message.Tags = new MessageTags(); message.Tags.SlideID = m_SlideModel.Id; } this.Sender.Send( message ); } }
protected void HandleSubmissionStyleChange(object sender, PropertyEventArgs args) { // Send the Student Submission Message using (Synchronizer.Lock(this.m_Slide.SyncRoot)){ if (this.m_Slide.SubmissionStyle == SlideModel.StudentSubmissionStyle.Shared) { Guid TOCEntryGuid = Guid.NewGuid(); this.m_Slide.SubmissionSlideGuid = SendStudentSubmission(TOCEntryGuid); LocalAddStudentSubmission(this.m_Slide.SubmissionSlideGuid, TOCEntryGuid); } } // Send a generic update with information about the slide (including the new bounds/zoom). Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); deck.InsertChild(new SlideInformationMessage(this.m_Slide)); this.m_Sender.Send(message); }
private void HandleSlideRemoved(object sender, PropertyEventArgs args_) { PropertyCollectionEventArgs args = ((PropertyCollectionEventArgs)args_); SlideModel slide = ((SlideModel)args.Removed); using (Synchronizer.Lock(this.m_SlideNetworkServices.SyncRoot)) { SlideNetworkService service = ((SlideNetworkService)this.m_SlideNetworkServices[slide]); if (service != null) { this.m_SlideNetworkServices.Remove(service); service.Dispose(); } } Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); deck.InsertChild(new SlideDeletedMessage(slide)); this.m_Sender.Send(message); }
private void SendQuickPollSheetHelper(Group receivers) { //Don't send message if it's an instructor note. if (this.sheet.Disposition != SheetDisposition.Instructor) { Message message, deck, poll, slide; message = new PresentationInformationMessage(this.Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); using (Synchronizer.Lock(this.Sheet.SyncRoot)) { slide.InsertChild(poll = new QuickPollInformationMessage(this.sheet.QuickPoll)); } poll.InsertChild(new QuickPollSheetMessage(this.sheet, this.SheetCollectionSelector)); using (Synchronizer.Lock(m_SlideModel.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = m_SlideModel.Id; } this.Sender.Send(message); } }
/// <summary> /// When a new quickpoll is started we get this with parents: QuickPollInformationMessage, Slide..,Deck..,Presentation.. /// The SheetMessage base class has dimensions, but they appear to all be zeros. /// </summary> /// <param name="quickPollSheetMessage"></param> /// <returns></returns> internal object AddQuickPollSheet(UW.ClassroomPresenter.Network.Messages.Presentation.QuickPollSheetMessage qpsm) { if ((qpsm.Parent is CP3Msgs.QuickPollInformationMessage) && (qpsm.Parent.Parent is CP3Msgs.SlideInformationMessage) && (qpsm.Parent.Parent.Parent is CP3Msgs.DeckInformationMessage) && (qpsm.Parent.Parent.Parent.Parent is CP3Msgs.PresentationInformationMessage)) { CP3Msgs.QuickPollInformationMessage qpim = (CP3Msgs.QuickPollInformationMessage)qpsm.Parent; CP3Msgs.SlideInformationMessage sim = (CP3Msgs.SlideInformationMessage)qpsm.Parent.Parent; CP3Msgs.DeckInformationMessage dim = (CP3Msgs.DeckInformationMessage)qpsm.Parent.Parent.Parent; CP3Msgs.QuickPollMessage qpm = (CP3Msgs.QuickPollMessage)qpim; // Note: OriginalSlideId is not in the TOC. What is that?? //TableOfContents.TocEntry te = toc.LookupBySlideId(qpModel.OriginalSlideId); /// sim.TargetID seems to give us a good TOC entry for the quickpoll /// slide with association information filled in correctly: TableOfContents.TocEntry qptoc = toc.LookupBySlideId((Guid)sim.TargetId); if (qptoc == null) { Debug.WriteLine("***Failed to find slide for QuickPoll Sheet!"); return(null); } m_QuickPollAggregator.AddQuickPoll(qpm.Model); toc.AddQuickPollIdForSlide((Guid)sim.TargetId, qpm.Model.Id); //Send the initial RtQuickPoll with empty results int[] results = new int[0]; ArchiveRTNav.RTQuickPoll rtqp = new ArchiveRTNav.RTQuickPoll((ArchiveRTNav.QuickPollStyle)qpm.Model.PollStyle, results, qptoc.DeckId, qptoc.SlideIndex); return(rtqp); } else { Debug.WriteLine("****Unexpected QuickPollSheetMessage: " + qpsm.ToString()); } return(null); }
private void SendImageHelper(Group receivers) { //Don't send message if it's an instructor note. if (this.sheet_.Disposition != SheetDisposition.Instructor) { Message message, deck, slide; message = new PresentationInformationMessage(this.Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); slide.InsertChild(new ImageSheetMessage(this.sheet_, this.SheetCollectionSelector)); using (Synchronizer.Lock(m_SlideModel.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = m_SlideModel.Id; } if (this.sheet_.Image != null) { using (Synchronizer.Lock(this.sheet_.SyncRoot)) { this.Sender.Send(message); } } else this.Sender.Send(message); } }
protected Guid SendStudentSubmission() { Guid newSlideGuid = Guid.Empty; UW.ClassroomPresenter.Network.Messages.Message pres, deck, slide, sheet; // Add the presentation if (this.Presentation == null) { return(Guid.Empty); } pres = new PresentationInformationMessage(this.Presentation); pres.Group = Groups.Group.Submissions; //Add the current deck model that corresponds to this slide deck at the remote location deck = new DeckInformationMessage(this.Deck); deck.Group = Groups.Group.Submissions; pres.InsertChild(deck); // Add the Slide Message newSlideGuid = Guid.NewGuid(); slide = new StudentSubmissionSlideInformationMessage(this.Slide, newSlideGuid, Guid.NewGuid()); slide.Group = Groups.Group.Submissions; deck.InsertChild(slide); // Find the correct user ink layer to send RealTimeInkSheetModel m_Sheet = null; using (Synchronizer.Lock(this.Slide.SyncRoot)) { foreach (SheetModel s in this.Slide.AnnotationSheets) { if (s is RealTimeInkSheetModel && (s.Disposition & SheetDisposition.Remote) == 0) { m_Sheet = (RealTimeInkSheetModel)s; break; } } } // Find the existing ink on the slide Microsoft.Ink.Ink extracted; using (Synchronizer.Lock(m_Sheet.Ink.Strokes.SyncRoot)) { // Ensure that each stroke has a Guid which will uniquely identify it on the remote side foreach (Microsoft.Ink.Stroke stroke in m_Sheet.Ink.Strokes) { if (!stroke.ExtendedProperties.DoesPropertyExist(InkSheetMessage.StrokeIdExtendedProperty)) { stroke.ExtendedProperties.Add(InkSheetMessage.StrokeIdExtendedProperty, Guid.NewGuid().ToString()); } } // Extract all of the strokes extracted = m_Sheet.Ink.ExtractStrokes(m_Sheet.Ink.Strokes, Microsoft.Ink.ExtractFlags.CopyFromOriginal); } // Find the Realtime ink on the slide RealTimeInkSheetModel newSheet = null; using (Synchronizer.Lock(m_Sheet.SyncRoot)) { newSheet = new RealTimeInkSheetModel(Guid.NewGuid(), m_Sheet.Disposition | SheetDisposition.Remote, m_Sheet.Bounds); using (Synchronizer.Lock(newSheet.SyncRoot)) { newSheet.CurrentDrawingAttributes = m_Sheet.CurrentDrawingAttributes; } } // Add the Sheet Message for the existing sheet = new InkSheetStrokesAddedMessage(newSheet, (Guid)slide.TargetId, SheetMessage.SheetCollection.AnnotationSheets, extracted); sheet.Group = Groups.Group.Submissions; slide.InsertChild(sheet); // Add the Sheet Message for the real-time ink sheet = SheetMessage.ForSheet(newSheet, SheetMessage.SheetCollection.AnnotationSheets); sheet.Group = Groups.Group.Submissions; slide.AddOldestPredecessor(sheet); // Send the message this.m_Sender.Send(pres); return(newSlideGuid); }
private void SendSlideInformation(SlideModel slide, Group receivers) { Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); // Ensure that nothing about the slide can change between sending the slide's information // and creating the SlideNetworkService to listen for changes. // TODO: Find a way to also ensure that nothing about the SheetModels change either, but this is less of a concern. using (Synchronizer.Lock(this.m_SlideNetworkServices.SyncRoot)) { using (Synchronizer.Lock(slide.SyncRoot)) { deck.InsertChild(new SlideInformationMessage(slide)); message.Tags = new MessageTags(); message.Tags.SlideID = slide.Id; this.m_Sender.Send(message); if (!this.m_SlideNetworkServices.ContainsKey(slide)) { SlideNetworkService service = new SlideNetworkService(this.m_Sender, this.m_Presentation, this.m_Deck, slide); this.m_SlideNetworkServices.Add(slide, service); } } } }
private void HandleInkDeletingHelper(string[] ids) { Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); slide.InsertChild(sheet = new InkSheetStrokesDeletingMessage(this.m_Sheet, this.SheetCollectionSelector, ids)); message.Tags = new MessageTags(); message.Tags.SlideID = m_SlideID; message.Tags.BridgePriority = MessagePriority.Higher; this.Sender.Send(message); }
private void SendGenericChange(Group receivers) { // Send a generic update with information about the slide (including the new bounds/zoom). Message message, deck; message = new PresentationInformationMessage( this.m_Presentation ); message.Group = receivers; message.InsertChild( deck = new DeckInformationMessage( this.m_Deck ) ); deck.InsertChild( new SlideInformationMessage( this.m_Slide ) ); this.m_Sender.Send( message ); }
protected void HandleSubmissionStyleChange( object sender, PropertyEventArgs args ) { // Send the Student Submission Message using( Synchronizer.Lock( this.m_Slide.SyncRoot ) ){ if( this.m_Slide.SubmissionStyle == SlideModel.StudentSubmissionStyle.Shared ) { Guid TOCEntryGuid = Guid.NewGuid(); this.m_Slide.SubmissionSlideGuid = SendStudentSubmission( TOCEntryGuid ); LocalAddStudentSubmission( this.m_Slide.SubmissionSlideGuid, TOCEntryGuid ); } } // Send a generic update with information about the slide (including the new bounds/zoom). Message message, deck; message = new PresentationInformationMessage( this.m_Presentation ); message.InsertChild( deck = new DeckInformationMessage( this.m_Deck ) ); deck.InsertChild( new SlideInformationMessage( this.m_Slide ) ); this.m_Sender.Send( message ); }
protected virtual void HandleBoundsChanged(object sender, PropertyEventArgs args) { // Send a generic update with information about the sheet (including the new bounds). Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); slide.InsertChild( sheet = SheetMessage.RemoteForSheet( this.Sheet, this.SheetCollectionSelector ) ); using (Synchronizer.Lock(this.m_Slide.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = this.m_Slide.Id; } this.Sender.Send(message); }
private void HandleInkAddedHelper(Ink extracted) { Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage( GetSubmissionSlideModel(), false )); slide.InsertChild(sheet = new InkSheetStrokesAddedMessage(this.m_Sheet, (Guid)slide.TargetId, this.SheetCollectionSelector, extracted)); sheet.AddOldestPredecessor( SheetMessage.RemoteForSheet( this.m_Sheet, this.SheetCollectionSelector ) ); this.Sender.Send(message); }
private void HandleInkDeletingHelper(string[] ids) { Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage( GetSubmissionSlideModel(), false )); slide.InsertChild(sheet = new InkSheetStrokesDeletingMessage(this.m_Sheet, this.SheetCollectionSelector, ids)); this.Sender.Send(message); }
/// <summary> /// Send the current ink as a student submission slide /// </summary> /// <param name="sender">The object which sent this event, i.e. this class</param> /// <param name="args">The parameters for the property</param> private void HandleSendSubmission( object sender, PropertyEventArgs args ) { if (this.m_SendingLock) return; using (Synchronizer.Lock(SubmissionStatusModel.GetInstance().SyncRoot)) { SubmissionStatusModel.GetInstance().SubmissionStatus = SubmissionStatusModel.Status.NotReceived; } ///declare variables we will be using UW.ClassroomPresenter.Network.Messages.Message pres, deck, slide, sheet; // Construct the message to send using( this.m_Model.Workspace.Lock() ) { // Add the presentation if( this.m_Model.Workspace.CurrentPresentation == null ) return; ///the presentation message we will be sending pres = new PresentationInformationMessage( this.m_Model.Workspace.CurrentPresentation ); pres.Group = Groups.Group.Submissions; //Add the current deck model that corresponds to this slide deck at the remote location if( (~this.m_Model.Workspace.CurrentDeckTraversal) == null ) return; using( Synchronizer.Lock( (~this.m_Model.Workspace.CurrentDeckTraversal).SyncRoot ) ) { DeckModel dModel = (~this.m_Model.Workspace.CurrentDeckTraversal).Deck; foreach( DeckPairModel match in this.m_Model.Workspace.DeckMatches ) { ///check to see if the decks are the same if( match.LocalDeckTraversal.Deck == (~this.m_Model.Workspace.CurrentDeckTraversal).Deck ) dModel = match.RemoteDeckTraversal.Deck; } ///create the deck message from this matched deck deck = new DeckInformationMessage( dModel ); ///make the deck a submission type deck. deck.Group = Groups.Group.Submissions; ///tack this message onto the end. pres.InsertChild( deck ); ///add the particular slide we're on the to message. if( (~this.m_Model.Workspace.CurrentDeckTraversal).Current == null ) return; using( Synchronizer.Lock( (~this.m_Model.Workspace.CurrentDeckTraversal).Current.Slide.SyncRoot ) ) { // Add the Slide Message slide = new StudentSubmissionSlideInformationMessage( (~this.m_Model.Workspace.CurrentDeckTraversal).Current.Slide, Guid.NewGuid(), Guid.NewGuid() ); slide.Group = Groups.Group.Submissions; deck.InsertChild( slide ); // Find the correct user ink layer to send RealTimeInkSheetModel m_Sheet = null; int count = 0; foreach( SheetModel s in (~this.m_Model.Workspace.CurrentDeckTraversal).Current.Slide.AnnotationSheets ) { if( s is RealTimeInkSheetModel && (s.Disposition & SheetDisposition.Remote) == 0 ) { m_Sheet = (RealTimeInkSheetModel)s; count++; } } // DEBUGGING if( count > 1 ) Debug.Assert( true, "Bad Count", "Bad" ); // Find the existing ink on the slide Ink extracted; using( Synchronizer.Lock( m_Sheet.Ink.Strokes.SyncRoot ) ) { // Ensure that each stroke has a Guid which will uniquely identify it on the remote side foreach( Stroke stroke in m_Sheet.Ink.Strokes ) { if( !stroke.ExtendedProperties.DoesPropertyExist( InkSheetMessage.StrokeIdExtendedProperty ) ) stroke.ExtendedProperties.Add( InkSheetMessage.StrokeIdExtendedProperty, Guid.NewGuid().ToString() ); } // Extract all of the strokes extracted = m_Sheet.Ink.ExtractStrokes( m_Sheet.Ink.Strokes, ExtractFlags.CopyFromOriginal ); } // Find the Realtime ink on the slide RealTimeInkSheetModel newSheet = null; using( Synchronizer.Lock( m_Sheet.SyncRoot ) ) { newSheet = new RealTimeInkSheetModel( Guid.NewGuid(), m_Sheet.Disposition | SheetDisposition.Remote, m_Sheet.Bounds ); using( Synchronizer.Lock( newSheet.SyncRoot ) ) { newSheet.CurrentDrawingAttributes = m_Sheet.CurrentDrawingAttributes; } } // Add a message to *create* the student's RealTimeInkSheetModel on the instructor client (without any ink). sheet = SheetMessage.ForSheet(newSheet, SheetMessage.SheetCollection.AnnotationSheets); sheet.Group = Groups.Group.Submissions; slide.InsertChild(sheet); //Scale the ink if necessary if (ViewerStateModel.NonStandardDpi) { extracted.Strokes.Transform(ViewerStateModel.DpiNormalizationSendMatrix); } // Add a message to copy the ink from the student's RealTimeInkSheetModel to the just-created sheet on the instructor. sheet = new InkSheetStrokesAddedMessage(newSheet, (Guid)slide.TargetId, SheetMessage.SheetCollection.AnnotationSheets, extracted); sheet.Group = Groups.Group.Submissions; slide.InsertChild( sheet ); ///Add each text and image sheet into the message as children of the ink sheet if it is public foreach( SheetModel s in (~this.m_Model.Workspace.CurrentDeckTraversal).Current.Slide.AnnotationSheets ) { if( s is TextSheetModel && !(s is StatusLabel) && (s.Disposition & SheetDisposition.Remote) == 0) { TextSheetModel text_sheet = (TextSheetModel) s; text_sheet = (TextSheetModel) text_sheet.Clone(); ///some ugly code here due to synchronization bool sheet_is_public; using (Synchronizer.Lock(text_sheet.SyncRoot)) { sheet_is_public = text_sheet.IsPublic; } if (sheet_is_public) { TextSheetMessage t_message = new TextSheetMessage(text_sheet, SheetMessage.SheetCollection.AnnotationSheets); t_message.Group = Groups.Group.Submissions; slide.InsertChild(t_message); } } if (s is ImageSheetModel && !(s is StatusLabel) && (s.Disposition & SheetDisposition.Remote) == 0) { ImageSheetModel image_sheet = (ImageSheetModel)s; image_sheet = (ImageSheetModel) image_sheet.Clone(); ImageSheetMessage i_message = new ImageSheetMessage(image_sheet, SheetMessage.SheetCollection.AnnotationSheets); i_message.Group = Groups.Group.Submissions; slide.InsertChild(i_message); } } //Lock the current sending. this.LockSending(); // Send the message this.m_Sender.Send(pres); } } } }
private void HandleCurrentDrawingAttributesChanged(object sender, PropertyEventArgs args) { Message message, deck, slide, sheet; message = new PresentationInformationMessage(this.Presentation); message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); slide.InsertChild( sheet = SheetMessage.RemoteForSheet( this.Sheet, this.SheetCollectionSelector ) ); message.Tags = new MessageTags(); message.Tags.SlideID = m_SlideID; this.Sender.Send(message); }
private void SendEntryAdded(TableOfContentsModel.Entry entry, Group receivers) { Message message, deck, slide; message = new PresentationInformationMessage(this.m_Service.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck)); deck.InsertChild(slide = new SlideInformationMessage(entry.Slide)); slide.InsertChild(new TableOfContentsEntryMessage(entry)); this.m_Service.m_Sender.Send(message); }
public void SendSheetInformation( SheetModel sheet, SheetMessage.SheetCollection selector, Group receivers ) { // TODO: Also pass the index so the sheet can be inserted into the correct index on the remote side. Message message, deck, slide; message = new PresentationInformationMessage( this.m_Presentation ); message.Group = receivers; message.InsertChild( deck = new DeckInformationMessage( this.m_Deck ) ); deck.InsertChild( slide = new SlideInformationMessage( this.m_Slide ) ); Message sm = SheetMessage.RemoteForSheet(sheet, selector); //if sm is null that means that the sheet is an instructor note and shouldn't be sent. if (sm != null) { slide.InsertChild(sm); } using( Synchronizer.Lock( this.m_Slide.SyncRoot ) ) { message.Tags = new MessageTags(); message.Tags.SlideID = this.m_Slide.Id; } if (sheet is ImageSheetModel && ((ImageSheetModel)sheet).Image != null) { using (Synchronizer.Lock(sheet.SyncRoot)) { this.m_Sender.Send( message ); } } else this.m_Sender.Send(message); }
protected override void TearDownMember(int index, object member, object tag) { if(tag == null) return; TableOfContentsModel.Entry entry = ((TableOfContentsModel.Entry) member); Message message, deck, slide; message = new PresentationInformationMessage(this.m_Service.m_Presentation); message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck)); deck.InsertChild(slide = new SlideInformationMessage(entry.Slide)); slide.InsertChild(new TableOfContentsEntryRemovedMessage(entry)); this.m_Service.m_Sender.Send(message); }
protected Guid SendStudentSubmission( Guid TOCEntryGuid ) { Guid newSlideGuid = Guid.Empty; UW.ClassroomPresenter.Network.Messages.Message pres, deck, slide, sheet; // Add the presentation if( this.m_Presentation == null ) return Guid.Empty; pres = new PresentationInformationMessage( this.m_Presentation ); pres.Group = Groups.Group.Submissions; //Add the current deck model that corresponds to this slide deck at the remote location deck = new DeckInformationMessage( this.m_Deck ); deck.Group = Groups.Group.Submissions; pres.InsertChild( deck ); // Add the Slide Message newSlideGuid = Guid.NewGuid(); TOCEntryGuid = Guid.NewGuid(); slide = new StudentSubmissionSlideInformationMessage( this.m_Slide, newSlideGuid, TOCEntryGuid ); slide.Group = Groups.Group.Submissions; deck.InsertChild( slide ); // Find the correct user ink layer to send RealTimeInkSheetModel m_Sheet = null; using( Synchronizer.Lock( this.m_Slide.SyncRoot ) ) { foreach( SheetModel s in this.m_Slide.AnnotationSheets ) { if( s is RealTimeInkSheetModel && (s.Disposition & SheetDisposition.Remote) == 0 ) { m_Sheet = (RealTimeInkSheetModel)s; break; } } } // Find the existing ink on the slide Microsoft.Ink.Ink extracted; using( Synchronizer.Lock( m_Sheet.Ink.Strokes.SyncRoot ) ) { // Ensure that each stroke has a Guid which will uniquely identify it on the remote side foreach( Microsoft.Ink.Stroke stroke in m_Sheet.Ink.Strokes ) { if( !stroke.ExtendedProperties.DoesPropertyExist( InkSheetMessage.StrokeIdExtendedProperty ) ) stroke.ExtendedProperties.Add( InkSheetMessage.StrokeIdExtendedProperty, Guid.NewGuid().ToString() ); } // Extract all of the strokes extracted = m_Sheet.Ink.ExtractStrokes( m_Sheet.Ink.Strokes, Microsoft.Ink.ExtractFlags.CopyFromOriginal ); } // Find the Realtime ink on the slide RealTimeInkSheetModel newSheet = null; using( Synchronizer.Lock( m_Sheet.SyncRoot ) ) { newSheet = new RealTimeInkSheetModel( Guid.NewGuid(), m_Sheet.Disposition | SheetDisposition.Remote, m_Sheet.Bounds ); using( Synchronizer.Lock( newSheet.SyncRoot ) ) { newSheet.CurrentDrawingAttributes = m_Sheet.CurrentDrawingAttributes; } } // Add the Sheet Message for the existing ink sheet = new InkSheetStrokesAddedMessage(newSheet, (Guid)slide.TargetId, SheetMessage.SheetCollection.AnnotationSheets, extracted); sheet.Group = Groups.Group.Submissions; slide.InsertChild( sheet ); // Add the Sheet Message for the real-time ink sheet = SheetMessage.ForSheet( newSheet, SheetMessage.SheetCollection.AnnotationSheets ); sheet.Group = Groups.Group.Submissions; slide.AddOldestPredecessor( sheet ); // Send the message this.m_Sender.Send( pres ); return newSlideGuid; }
private void HandleSlideContentAdded(object sender, PropertyEventArgs args_) { PropertyCollectionEventArgs args = ((PropertyCollectionEventArgs) args_); ByteArray hash = ((ByteArray) args.Added); // For the purposes of ForceUpdate, this information is sent by SendAllSlidesAndContent. Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); deck.InsertChild(new DeckSlideContentMessage(this.m_Deck, hash)); if( ( this.m_Deck.Disposition & (DeckDisposition.StudentSubmission | DeckDisposition.QuickPoll) ) != 0 ) { // If we get here in response to a new student submission received // we don't need to send anything because we can assume the public display // already has the slide, however if the instructor manually adds new // slides to a student submission deck, the public display may not have them. // For now we send in both cases, but that could be improved. // In any case we only send slides from a Student Submission deck to Public nodes. message.Group = Group.Submissions; } this.m_Sender.Send(message, MessagePriority.Low); }
protected override void TearDownMember(int index, object member, object tag) { if(tag == null) return; SheetModel sheet = ((SheetModel) member); Message message, deck, slide; message = new PresentationInformationMessage(this.m_Service.m_Presentation); message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.m_Service.m_Slide)); slide.InsertChild(new SheetRemovedMessage(sheet, this.m_Selector)); using (Synchronizer.Lock(this.m_Service.m_Slide.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = this.m_Service.m_Slide.Id; } this.m_Service.m_Sender.Send(message); ((SheetNetworkService) tag).Dispose(); }
private void HandleSlideRemoved(object sender, PropertyEventArgs args_) { PropertyCollectionEventArgs args = ((PropertyCollectionEventArgs) args_); SlideModel slide = ((SlideModel) args.Removed); using(Synchronizer.Lock(this.m_SlideNetworkServices.SyncRoot)) { SlideNetworkService service = ((SlideNetworkService) this.m_SlideNetworkServices[slide]); if(service != null) { this.m_SlideNetworkServices.Remove(service); service.Dispose(); } } Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); deck.InsertChild(new SlideDeletedMessage(slide)); this.m_Sender.Send(message); }
private void SendTraversalInformation(DeckTraversalModel traversal, Group receivers) { Message message, deck; message = new PresentationInformationMessage(this.m_Service.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(traversal.Deck)); deck.InsertChild(DeckTraversalMessage.ForDeckTraversal(traversal)); this.m_Service.m_Sender.Send(message); }
private void SendAllSlidesAndContent(Group receivers) { using(Synchronizer.Lock(this.m_Deck.SyncRoot)) { foreach (SlideModel slide in this.m_Deck.Slides) this.SendSlideInformation(slide, receivers); foreach(ByteArray hash in this.m_Deck.SlideContentKeys) { Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); deck.InsertChild(new DeckSlideContentMessage(this.m_Deck, hash)); message.Tags = new MessageTags(); message.Tags.BridgePriority = MessagePriority.Lowest; SlideModel slide = this.m_Deck.GetSlideFromContent(hash); if (slide != null) { using (Synchronizer.Lock(slide.SyncRoot)) { message.Tags.SlideID = slide.Id; } } this.m_Sender.Send(message, MessagePriority.Low); } } }
private void SendCurrentChanged(Group receivers) { Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_DeckTraversal.Deck)); deck.InsertChild(DeckTraversalMessage.ForDeckTraversal(this.m_DeckTraversal)); #if DEBUG // Add logging of slide change events string pres_name = ""; using( Synchronizer.Lock( this.m_Presentation.SyncRoot ) ) pres_name = this.m_Presentation.HumanName; string deck_name = ""; using( Synchronizer.Lock( this.m_DeckTraversal.Deck.SyncRoot ) ) deck_name = this.m_DeckTraversal.Deck.HumanName; int slide_index = 0; Guid slide_guid = Guid.Empty; using( Synchronizer.Lock( this.m_DeckTraversal.SyncRoot ) ) { if( this.m_DeckTraversal.Current != null ) using( Synchronizer.Lock( this.m_DeckTraversal.Current.SyncRoot ) ) { slide_index = this.m_DeckTraversal.Current.IndexInParent; using (Synchronizer.Lock(this.m_DeckTraversal.Current.Slide.SyncRoot)) { slide_guid = this.m_DeckTraversal.Current.Slide.Id; } } } Debug.WriteLine( string.Format("SLIDE CHANGE ({0}): Pres -- {1}, Deck -- {2}, Slide -- {3}, Guid -- {4}", System.DateTime.Now.Ticks, pres_name, deck_name, slide_index, slide_guid ) ); #endif message.Tags = new MessageTags(); message.Tags.BridgePriority = MessagePriority.Higher; this.m_Sender.Send(message); }
private void SendTextHelper(Group receivers) { Message message, deck, slide; message = new PresentationInformationMessage(this.Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.Deck)); deck.InsertChild(slide = new SlideInformationMessage(this.Slide)); ///send the text message slide.InsertChild(new TextSheetMessage(this.sheet_, this.SheetCollectionSelector)); using (Synchronizer.Lock(this.Slide.SyncRoot)) { message.Tags = new MessageTags(); message.Tags.SlideID = this.Slide.Id; } this.Sender.Send(message); }