/// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sender">The network queue to send messages on</param>
        /// <param name="model">The presenter model</param>
        public StudentSubmissionNetworkService(SendingQueue sender, PresenterModel model)
        {
            this.m_Sender = sender;
            this.m_Model = model;
            this.m_SendingLock = false;
            this.m_SendingLockTimer = new System.Timers.Timer();
            if (model.ViewerState != null)
            {
                using (Synchronizer.Lock(this.m_Model.ViewerState.SyncRoot))
                {
                    this.m_SendingLockTimer.Interval = this.m_Model.ViewerState.StudentSubmissionInterval*1000;
                }
            }
            this.m_SendingLockTimer.Elapsed += new System.Timers.ElapsedEventHandler(SendingLockTimer_Elapsed);
            this.m_SendingLockTimer.Enabled = false;

            // Setup the event listener for this
            this.m_SendChangeDispatcher = new EventQueue.PropertyEventDispatcher( this.m_Sender, new PropertyEventHandler(this.HandleSendSubmission) );

            //FV: Not locking here resolves a lock order warning.
            //using( Synchronizer.Lock( this.m_Model.ViewerState.SyncRoot ) ) {
                this.m_Model.ViewerState.Changed["StudentSubmissionSignal"].Add( this.m_SendChangeDispatcher.Dispatcher );
            //}

            this.m_SubmissionIntervalDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleSubmissionIntervalChanged));
            this.m_Model.ViewerState.Changed["StudentSubmissionInterval"].Add(this.m_SubmissionIntervalDispatcher.Dispatcher);
        }
        /// <summary>
        /// Constructs a listener for changes to the deck traversal
        /// </summary>
        /// <param name="sender">The event queue for handling updates</param>
        /// <param name="presentation">The presentation</param>
        /// <param name="traversal">The deck traversal we care about </param>
        public DeckTraversalWebService(SendingQueue sender, PresentationModel presentation, DeckTraversalModel traversal)
        {
            this.m_Sender = sender;
            this.m_Presentation = presentation;
            this.m_DeckTraversal = traversal;

            // Create the deck object
            string deckName = "Untitled Deck";
            using (Synchronizer.Lock(this.m_DeckTraversal.SyncRoot))
            {
                using (Synchronizer.Lock(this.m_DeckTraversal.Deck))
                {
                    deckName = this.m_DeckTraversal.Deck.HumanName;
                }
            }
            SimpleWebDeck deck = new SimpleWebDeck();
            deck.Name = deckName;
            lock (WebService.Instance.GlobalModel) {
                WebService.Instance.GlobalModel.Decks.Add(deck);
            }
            WebService.Instance.UpdateModel();

            this.m_DeckWebService = new DeckWebService(this.m_Sender, this.m_Presentation, this.m_DeckTraversal.Deck);

            this.m_CurrentChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleCurrentChanged));
            this.m_DeckTraversal.Changed["Current"].Add(this.m_CurrentChangedDispatcher.Dispatcher);
        }
Example #3
0
        /// <summary>
        /// Construct a new deck web service
        /// </summary>
        /// <param name="sender">The event handler </param>
        /// <param name="presentation">The presentation model</param>
        /// <param name="deck">The deck model</param>
        public DeckWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck)
        {
            this.m_Sender = sender;
            this.m_Presentation = presentation;
            this.m_Deck = deck;

            this.m_SlideRemovedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleSlideRemoved));
            this.m_SlideAddedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleSlideAdded));
            //            this.m_SlideContentAddedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleSlideContentAdded));
            //            this.m_DeckBackgroundChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleDeckBackgroundChanged));

            this.m_SlideWebServices = new Hashtable();

            //            this.m_TableOfContentsWebService = new TableOfContentsWebService(this.m_Sender, this.m_Presentation, this.m_Deck);

            // Lock the deck so no content can be added between registering the event listeners and calling SendAllSlidesAndContent().
            using (Synchronizer.Lock(this.m_Presentation.SyncRoot))
            {
                using (Synchronizer.Lock(deck.SyncRoot))
                {

                    this.m_Deck.SlideRemoved += this.m_SlideRemovedDispatcher.Dispatcher;
                    this.m_Deck.SlideAdded += this.m_SlideAddedDispatcher.Dispatcher;
            //                    this.m_Deck.SlideContentAdded += this.m_SlideContentAddedDispatcher.Dispatcher;
            //                    this.m_Deck.Changed["DeckBackgroundColor"].Add(this.m_DeckBackgroundChangedDispatcher.Dispatcher);
            //                    this.m_Deck.Changed["DeckBackgroundTemplate"].Add(this.m_DeckBackgroundChangedDispatcher.Dispatcher);
                }
            }

            this.UpdateAllSlidesAndContent();
        }
Example #4
0
        public BeaconService(SendingQueue sender)
        {
            this.m_Sender = sender;

            Thread thread = new Thread(new ThreadStart(this.BeaconSenderThreadStart));
            thread.IsBackground = true;
            thread.Start();
        }
        /// <summary>
        /// Build this model listener
        /// </summary>
        /// <param name="sender">The queue to use to send events</param>
        /// <param name="presentation">The presentation to listen to</param>
        /// <param name="deck">The deck to listen to</param>
        public TableOfContentsWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck)
        {
            this.m_Sender = sender;
            this.m_Presentation = presentation;
            this.m_Deck = deck;

            this.m_EntriesCollectionHelper = new EntriesCollectionHelper(this);
        }
        public PresenterNetworkService(SendingQueue sender, PresenterModel model)
        {
            this.m_Sender = sender;
            this.m_Model = model;

            this.m_ParticipantNetworkService = new ParticipantNetworkService(this.m_Sender, this.m_Model, this.m_Model.Participant);
            this.m_VersionExchangeNetworkService = new VersionExchangeNetworkService(m_Sender);
        }
        /// <summary>
        /// Constructor for the scripting network service
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="model"></param>
        /// <param name="diag"></param>
        public ScriptingNetworkService(SendingQueue sender, PresenterModel model)
        {
            this.Sender = sender;
            this.m_Model = model;
            this.m_Diagnostic = model.ViewerState.Diagnostic;

            // Set up the change listeners
            this.m_GenericChangeDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleGenericChange));
            this.m_Diagnostic.Changed["ExecuteRemoteScript"].Add(this.m_GenericChangeDispatcher.Dispatcher);
        }
        /// <summary>
        /// Constructor for the web service.
        /// </summary>
        /// <param name="sender">The event queue to use.</param>
        /// <param name="presentation">The web performance model to listen to.</param>
        public WebPerformanceWebService(SendingQueue sender, WebPerformanceModel performance)
        {
            this.m_Sender = sender;
            this.m_WebPerformance = performance;

            this.m_RequestSubmissionChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleRequestSubmissionChanged));
            this.m_WebPerformance.Changed["RequestSubmissionSignal"].Add(this.m_RequestSubmissionChangedDispatcher.Dispatcher);
            this.m_RequestLogChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleRequestLogChanged));
            this.m_WebPerformance.Changed["RequestLogSignal"].Add(this.m_RequestLogChangedDispatcher.Dispatcher);
        }
 public static RoleNetworkService ForRole(SendingQueue sender, PresenterModel model, RoleModel role)
 {
     if(role is InstructorModel) {
         return new InstructorNetworkService(sender, ((InstructorModel) role));
     } else if(role is StudentModel) {
         return new StudentNetworkService( sender, model, ((StudentModel) role) );
     } else {
         // Either the role type is unsupported, or it is a PublicModel
         // which currently have no published properties which need to be broadcast.
         return null;
     }
 }
Example #10
0
        /// <summary>
        /// Construct a listener for a generic sheet
        /// </summary>
        /// <param name="sender">The event queue</param>
        /// <param name="presentation">The presentation</param>
        /// <param name="deck">The deck</param>
        /// <param name="slide">The slide</param>
        /// <param name="sheet">The sheet</param>
        /// <param name="selector">The collection that this is part of</param>
        public SheetWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector)
        {
            this.m_Sender = sender;
            this.m_Presentation = presentation;
            this.m_Deck = deck;
            this.m_Slide = slide;
            this.m_Sheet = sheet;
            this.m_Selector = selector;

            //            this.m_BoundsChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleBoundsChanged));
            //            this.m_Sheet.Changed["Bounds"].Add(this.m_BoundsChangedDispatcher.Dispatcher);
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sender">The network queue to send messages on</param>
        /// <param name="model">The presenter model</param>
        public StudentSubmissionNetworkService(SendingQueue sender, PresenterModel model)
        {
            this.m_Sender = sender;
            this.m_Model = model;

            // Setup the event listener for this
            this.m_SendChangeDispatcher = new EventQueue.PropertyEventDispatcher( this.m_Sender, new PropertyEventHandler(this.HandleSendSubmission) );

            //FV: Not locking here resolves a lock order warning.
            //using( Synchronizer.Lock( this.m_Model.ViewerState.SyncRoot ) ) {
                this.m_Model.ViewerState.Changed["StudentSubmissionSignal"].Add( this.m_SendChangeDispatcher.Dispatcher );
            //}
        }
        /// <summary>
        /// Constructor for the web service
        /// </summary>
        /// <param name="sender">The event queue to use</param>
        /// <param name="presentation">The presentation to listen to</param>
        public QuickPollWebService( SendingQueue sender, PresentationModel presentation )
        {
            this.m_Sender = sender;
            this.m_Presentation = presentation;
            using (Synchronizer.Lock(this.m_Presentation.SyncRoot))
            {
                this.m_QuickPoll = this.m_Presentation.QuickPoll;
            }

            if (this.m_QuickPoll != null)
            {
            //                this.m_QuickPollResultCollectionHelper = new QuickPollResultCollectionHelper(this);
            }
        }
        /// <summary>
        /// Construct the InkSheetWebService, this class listens for strokes to finish 
        /// and sends them across the network
        /// </summary>
        /// <param name="sender">The queue to use</param>
        /// <param name="presentation">The presentation model</param>
        /// <param name="deck">The deck model</param>
        /// <param name="slide">The slide model</param>
        /// <param name="sheet">The sheet model</param>
        /// <param name="selector">The sheet collection we are part of</param>
        public InkSheetWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector)
            : base(sender, presentation, deck, slide, sheet, selector)
        {
            // Keep track of our sheet
            this.m_Sheet = (InkSheetModel)sheet;

            // Get the slide ID
            using (Synchronizer.Lock(slide.SyncRoot)) {
                m_SlideID = slide.Id;
            }

            // Set Events
            this.m_Sheet.InkAdded += new StrokesEventHandler(this.HandleInkAdded);
            //            this.m_Sheet.InkDeleting += new StrokesEventHandler(this.HandleInkDeleting);
        }
Example #14
0
        /// <summary>
        /// Construct the service
        /// </summary>
        /// <param name="sender">The event queue</param>
        /// <param name="presentation">The presentation</param>
        /// <param name="deck">The deck</param>
        /// <param name="slide">The slide</param>
        public SlideWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide)
        {
            this.m_Sender = sender;
            this.m_Presentation = presentation;
            this.m_Deck = deck;
            this.m_Slide = slide;

            this.m_ChangeDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleChange));
            this.m_Slide.Changed["Bounds"].Add(this.m_ChangeDispatcher.Dispatcher);
            this.m_Slide.Changed["Zoom"].Add(this.m_ChangeDispatcher.Dispatcher);
            this.m_Slide.Changed["BackgroundColor"].Add(this.m_ChangeDispatcher.Dispatcher);
            this.m_Slide.Changed["BackgroundTemplate"].Add(this.m_ChangeDispatcher.Dispatcher);

            this.m_ContentSheetsCollectionHelper = new SheetsCollectionHelper(this, "ContentSheets", SheetMessage.SheetCollection.ContentSheets);
            this.m_AnnotationSheetsCollectionHelper = new SheetsCollectionHelper(this, "AnnotationSheets", SheetMessage.SheetCollection.AnnotationSheets);
        }
        /// <summary>
        /// Constructor for the synchronization network service
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="model"></param>
        /// <param name="diag"></param>
        public SynchronizationNetworkService(SendingQueue sender, PresenterModel model)
        {
            this.Sender = sender;
            this.m_Model = model;
            this.m_Diagnostic = model.ViewerState.Diagnostic;

            // Set up the change listeners
            this.m_ServerChangeDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleServerStateChange));
            this.m_Diagnostic.Changed["ServerState"].Add(this.m_ServerChangeDispatcher.Dispatcher);
            this.m_ClientChangeDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleClientStateChange));
            this.m_Diagnostic.Changed["ClientState"].Add(this.m_ClientChangeDispatcher.Dispatcher);

            this.m_Timer = new System.Windows.Forms.Timer();
            this.m_Timer.Interval = 5000;
            this.m_Timer.Tick += new EventHandler( this.OnTimerTick );
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sender">The sending queue to post messages to</param>
        /// <param name="role">The InstructorModel to create this class for</param>
        public InstructorWebService(SendingQueue sender, InstructorModel role)
        {
            this.m_Sender = sender;
            this.m_Instructor = role;

            // Handle basic changes
            this.m_GenericChangeDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleGenericChange));
            this.m_Instructor.Changed["ForcingStudentNavigationLock"].Add(this.m_GenericChangeDispatcher.Dispatcher);
            this.m_Instructor.Changed["AcceptingStudentSubmissions"].Add(this.m_GenericChangeDispatcher.Dispatcher);
            this.m_Instructor.Changed["AcceptingQuickPollSubmissions"].Add(this.m_GenericChangeDispatcher.Dispatcher);

            // Handle changes to the current deck traversal
            this.m_CurrentDeckTraversalChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleCurrentDeckTraversalChanged));
            this.m_Instructor.Changed["CurrentDeckTraversal"].Add(this.m_CurrentDeckTraversalChangedDispatcher.Dispatcher);
            this.m_CurrentDeckTraversalChangedDispatcher.Dispatcher(this, null);
        }
        public DefaultBeaconService(SendingQueue sender, PresenterModel model)
            : base(sender)
        {
            this.m_Sender = sender;
            this.m_Model = model;

            this.m_RoleChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender,
                new PropertyEventHandler(this.HandleRoleChanged));
            this.m_Model.Participant.Changed["Role"].Add(this.m_RoleChangedDispatcher.Dispatcher);
            this.m_RoleChangedDispatcher.Dispatcher(this, null);

            this.m_BeaconIntervalChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender,
                new PropertyEventHandler(this.HandleBeaconIntervalChanged));
            this.m_Model.ViewerState.Changed["BeaconInterval"].Add(this.m_BeaconIntervalChangedDispatcher.Dispatcher);
            this.m_BeaconIntervalChangedDispatcher.Dispatcher(this, null);
        }
        /// <summary>
        /// Build the network service
        /// </summary>
        /// <param name="sender">The message queue to use for these messages</param>
        /// <param name="presentation">The presentation to listen to changes to</param>
        public PresentationWebService( SendingQueue sender, PresentationModel presentation )
        {
            handler = new WebService.SSEventHandler(HandleStudentSubmission);
            WebService.Instance.SubmissionReceived += handler;
            qpHandler = new WebService.QPEventHandler(HandleQuickPollReceived);
            WebService.Instance.QuickPollReceived += qpHandler;

            this.m_Sender = sender;
            this.m_Presentation = presentation;

            this.m_DeckTraversalsCollectionHelper = new DeckTraversalsCollectionHelper(this);

            //            this.m_QuickPollWebService = new QuickPollWebService(this.m_Sender, this.m_Presentation);

            this.m_QuickPollChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleQuickPollChanged));
            this.m_Presentation.Changed["QuickPoll"].Add(this.m_QuickPollChangedDispatcher.Dispatcher);
        }
        public BridgeBeaconService(SendingQueue sender, PresenterModel model)
            : base(sender)
        {
            this.m_Sender = sender;
            this.m_Model = model;
            this.m_NonInstructorId = Guid.NewGuid();

            //Get the interval from app.config
            this.m_BeaconIntervalSeconds = 3;
            String tmp = System.Configuration.ConfigurationManager.AppSettings[this.GetType().ToString() + ".BeaconIntervalSeconds"];
            if ((tmp != null) && (tmp.Trim() != "")) {
                int tmpint;
                if (int.TryParse(tmp, out tmpint)) {
                    if ((tmpint > 0) && (tmpint <= 20)) {
                        Trace.WriteLine("Setting BeaconIntervalSeconds from app.config: " + tmpint.ToString(), this.GetType().ToString());
                        this.m_BeaconIntervalSeconds = tmpint;
                    }
                }
            }

            this.BeaconInterval = new TimeSpan(0, 0, 0, m_BeaconIntervalSeconds, 0);
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sender">The sending queue for this class</param>
        /// <param name="model">The PresenterModel for the network service</param>
        /// <param name="role">The StudentModel for this network service</param>
        public StudentNetworkService(SendingQueue sender, PresenterModel model, StudentModel role)
            : base(sender, role)
        {
            this.m_Student = role;
            this.m_Model = model;

            // Instanciate the submission status service
            submission_status_service_ = new SubmissionStatusNetworkService(this.Sender, role);

            // Create a delegate that will update the local copy of the current
            // presentation whenever it changes in the workspace.
            //
            // This causes the set{} accessor for CurrentPresentation to be run,
            // which as a side effect disposes of and recreates all the network
            // services associated with the student.
            this.m_PresentationChangedDispatcher =
                this.m_Model.Workspace.CurrentPresentation.ListenAndInitialize(sender,
                    delegate(Property<PresentationModel>.EventArgs args) {
                        if (args.New != null) {
                            this.CurrentPresentation = args.New;
                        }
                    });
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sender">The sending queue to post messages to</param>
        /// <param name="role">The InstructorModel to create this class for</param>
        public InstructorNetworkService(SendingQueue sender, InstructorModel role)
            : base(sender, role)
        {
            this.m_Instructor = role;

            // Create the submission status service
            submission_status_service_ = new SubmissionStatusNetworkService(this.Sender, role);

            // Handle basic changes
            this.m_GenericChangeDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleGenericChange));
            this.m_Instructor.Changed["ForcingStudentNavigationLock"].Add(this.m_GenericChangeDispatcher.Dispatcher);
            this.m_Instructor.Changed["AcceptingStudentSubmissions"].Add(this.m_GenericChangeDispatcher.Dispatcher);
            this.m_Instructor.Changed["AcceptingQuickPollSubmissions"].Add(this.m_GenericChangeDispatcher.Dispatcher);

            // Handle changes to the current presentation
            this.m_CurrentPresentationChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleCurrentPresentationChanged));
            this.m_Instructor.Changed["CurrentPresentation"].Add(this.m_CurrentPresentationChangedDispatcher.Dispatcher);
            this.m_CurrentPresentationChangedDispatcher.Dispatcher(this, null);

            // Handle changes to the current deck traversal
            this.m_CurrentDeckTraversalChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleCurrentDeckTraversalChanged));
            this.m_Instructor.Changed["CurrentDeckTraversal"].Add(this.m_CurrentDeckTraversalChangedDispatcher.Dispatcher);
            this.m_CurrentDeckTraversalChangedDispatcher.Dispatcher(this, null);
        }
Example #22
0
 /// <summary>
 /// Construct the appropriate sheet web service
 /// </summary>
 /// <param name="sender">The queue</param>
 /// <param name="presentation">The presentation</param>
 /// <param name="deck">The deck</param>
 /// <param name="slide">The slide</param>
 /// <param name="sheet">The sheet</param>
 /// <param name="selector">The sheet collection type</param>
 /// <returns>A sheet web service appropriate for the sheet model</returns>
 public static SheetWebService ForSheet(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector)
 {
     if (sheet is InkSheetModel) {
         return new InkSheetWebService( sender, presentation, deck, slide, sheet, selector );
     } else {
         return new SheetWebService( sender, presentation, deck, slide, sheet, selector );
     }
 }
 public RoleNetworkService(SendingQueue sender, RoleModel role)
 {
     this.Sender = sender;
     this.m_Role = role;
 }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sender">The sending queue to post messages to</param>
        /// <param name="role">The InstructorModel to create this class for</param>
        public InstructorNetworkService(SendingQueue sender, InstructorModel role)
            : base(sender, role)
        {
            this.m_Instructor = role;

            // Create the submission status service
            submission_status_service_ = new SubmissionStatusNetworkService(this.Sender, role);

            // Handle basic changes
            this.m_GenericChangeDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleGenericChange));
            this.m_Instructor.Changed["ForcingStudentNavigationLock"].Add(this.m_GenericChangeDispatcher.Dispatcher);
            this.m_Instructor.Changed["AcceptingStudentSubmissions"].Add(this.m_GenericChangeDispatcher.Dispatcher);
            this.m_Instructor.Changed["AcceptingQuickPollSubmissions"].Add(this.m_GenericChangeDispatcher.Dispatcher);
            this.m_Instructor.Changed["StudentNavigationType"].Add(this.m_GenericChangeDispatcher.Dispatcher);

            // Handle changes to the current presentation
            this.m_CurrentPresentationChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleCurrentPresentationChanged));
            this.m_Instructor.Changed["CurrentPresentation"].Add(this.m_CurrentPresentationChangedDispatcher.Dispatcher);
            this.m_CurrentPresentationChangedDispatcher.Dispatcher(this, null);

            // Handle changes to the current deck traversal
            this.m_CurrentDeckTraversalChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleCurrentDeckTraversalChanged));
            this.m_Instructor.Changed["CurrentDeckTraversal"].Add(this.m_CurrentDeckTraversalChangedDispatcher.Dispatcher);
            this.m_CurrentDeckTraversalChangedDispatcher.Dispatcher(this, null);

            #if WEBSERVER
            // Create the web service equivalent to this service
            this.m_InstructorWebService = new Web.Network.InstructorWebService( this.Sender, role );

            using (Synchronizer.Lock(PresenterModel.TheInstance.SyncRoot)) {
                using (Synchronizer.Lock(PresenterModel.TheInstance.ViewerState.SyncRoot)) {
                    this.m_WebPerformanceWebService = new Web.Network.WebPerformanceWebService(this.Sender, PresenterModel.TheInstance.ViewerState.WebPerformance);
                }
            }
            #endif
        }