public override bool RemoveCapability(ICapability capability) { bool ret = base.RemoveCapability(capability); if (ret) { // Remove the ObjectReceived event handler. // This form is going away, but the Capability may be replayed in which case we'd receive this event into a disposed form! m_Capability.ObjectReceived -= new CapabilityObjectReceivedEventHandler(objectReceived); m_CapabilitySender.Dispose(); m_Capability = null; m_CapabilitySender = null; } return(ret); }
public override bool RemoveCapability(ICapability capability) { bool ret = base.RemoveCapability(capability); if (ret) { // Remove the ObjectReceived event handler. // This form is going away, but the Capability may be replayed in which case we'd receive this event into a disposed form! m_Capability.ObjectReceived -= new CapabilityObjectReceivedEventHandler(objectReceived); m_CapabilitySender.Dispose(); m_Capability = null; m_CapabilitySender = null; } return ret; }
public override void AddCapability(ICapability capability) { base.AddCapability(capability); if (m_Capability == null) { m_Capability = (PresenterCapability)capability; // Hook the ObjectReceived event so we can receive incoming data m_Capability.ObjectReceived += new CapabilityObjectReceivedEventHandler(objectReceived); //Set the role to instructor if we initiated the capability. if (m_Capability.IsSender) { //Set the instructor role InstructorModel instructor = new InstructorModel(Guid.NewGuid()); using (Synchronizer.Lock(this.m_Model.Participant.SyncRoot)) { m_Model.Participant.Role = instructor; } using (Synchronizer.Lock(this.m_Model.ViewerState.SyncRoot)) { this.m_Model.ViewerState.iRole = 2; } //We also need to set up a couple of other things to make the instructor functional: A network association // and an empty presentation. PresentationModel pres = new PresentationModel(Guid.NewGuid(), m_Model.Participant, "Untitled Presentation", true); using (Synchronizer.Lock(m_Model.Network.SyncRoot)) { m_Model.Network.Association = m_Model.Participant; } using (Synchronizer.Lock(instructor.SyncRoot)) { instructor.CurrentPresentation = pres; } } else { //Set student role using (Synchronizer.Lock(this.m_Model.Participant.SyncRoot)) { m_Model.Participant.Role = new StudentModel(Guid.NewGuid()); } using (Synchronizer.Lock(this.m_Model.ViewerState.SyncRoot)) { this.m_Model.ViewerState.iRole = 1; } } //Before we create the CXPCapabilityMessageSender, we want to wait until the Play and Send methods have completed. //Otherwise we can end up trying to send before the capability is ready to accept messages. bool createCapabilitySenderNow = false; lock (m_Capability) { //This section synchronized with the PresenterCapability instance. if (m_Capability.IsPlayingAndSending) { createCapabilitySenderNow = true; } else { m_Capability.OnPlay += new PresenterCapability.OnPlayHandler(OnCapabilityPlay); } } if (createCapabilitySenderNow) { m_CapabilitySender = new CXPCapabilityMessageSender(m_Model, m_Capability); } } }
public CXPCapabilityMessageSender(PresenterModel model, PresenterCapability capability) { this.m_Model = model; this.m_LocalId = m_Model.Participant.Guid; this.m_Classroom = new ClassroomModel(null, "CXP Capability Classroom", ClassroomModelType.CXPCapability); this.m_Capability = capability; this.m_Participants = new Dictionary<string, ParticipantModel>(); this.m_SsrcToSenderId = new Dictionary<uint, Guid>(); this.m_Receivers = new Dictionary<string, CXPCapabilityMessageReceiver>(); m_Capability.OnStreamAdded += new PresenterCapability.OnStreamAddedHandler(OnStreamAdded); m_Capability.OnStreamRemoved +=new PresenterCapability.OnStreamRemovedHandler(OnStreamRemoved); using(Synchronizer.Lock(this)) { // Initialize the message chunking utilities. this.m_Encoder = new Chunk.ChunkEncoder(); // TODO: Make the buffer size dynamic, ie., grow if we send a single very large message. // Make the buffer store up to 5MB worth of data. this.m_FrameBuffer = new FrameBuffer(5 * 1024 * 1024 / this.m_Encoder.MaximumChunkSize); // Create the NackManager which is responsible for sending NACKs on behalf of // our set of RTPMessageReceivers. this.m_NackManager = new RTPNackManager(this, this.m_Classroom); } // Create network services outside of the "lock(this)" so they can lock their own objects // without worrying about locking order. // Create the PresenterNetworkService which will watch for changes to the model and send messages. this.m_PresenterNetworkService = new PresenterNetworkService(this, this.m_Model); // Create the StudentSubmissionsNetworkService which will watch for requests to submit and send messages. this.m_StudentSubmissionNetworkService = new StudentSubmissionNetworkService(this, this.m_Model); // Create the SynchronizationNetworkService which will watch for all synchronization messages. this.m_SynchronizationNetworkService = new SynchronizationNetworkService( this, this.m_Model ); // Create the ScriptingNetworkService which will watch for all scripting messages. this.m_ScriptingNetworkService = new ScriptingNetworkService( this, this.m_Model ); // Create the BeaconService which will broadcast periodic information about the presentation. this.m_BeaconService = new Beacons.DefaultBeaconService(this, this.m_Model); // Report Network status to the UI m_CapabilityNetworkStatus = new CapabilityNetworkStatus(this.m_Model); m_CapabilityNetworkStatus.Register(); // Send an initial message to announce our node to others in the venue. SendObject(new CapabilityMessageWrapper(null, m_LocalId, Guid.Empty, m_Capability.IsSender)); }