/// <summary> /// Toggle on and off subscription to /// automatic cloud updates. /// </summary> public static ExternalEvent ToggleSubscription( // EventHandler<IdlingEventArgs> handler IExternalEventHandler handler) { if (Subscribed) { Debug.Print("Unsubscribing..."); //_uiapp.Idling -= _handler; //_handler = null; _event.Dispose(); _event = null; _buttons[_subscribeButtonIndex].ItemText = _subscribe; _timer.Stop(); _timer.Report("Subscription timing"); _timer = null; Debug.Print("Unsubscribed."); } else { Debug.Print("Subscribing..."); //_uiapp.Idling += handler; //_handler = handler; _event = ExternalEvent.Create(handler); _buttons[_subscribeButtonIndex].ItemText = _unsubscribe; _timer = new JtTimer("Subscription"); Debug.Print("Subscribed."); } return(_event); }
public DbUpdater(UIApplication uiapp) { using (JtTimer pt = new JtTimer("DbUpdater ctor")) { //_doc = doc; _uiapp = uiapp; _creapp = _uiapp.Application.Create; } }
public DbUpdater( UIApplication uiapp ) { using( JtTimer pt = new JtTimer( "DbUpdater ctor" ) ) { //_doc = doc; _uiapp = uiapp; _creapp = _uiapp.Application.Create; } }
public RoomEditorDb() { using (JtTimer pt = new JtTimer("RoomEditorDb ctor")) { if (null == _client) { _client = new CouchClient(_url_local, 5984); } if (null == _db) { _db = _client.GetDatabase(_database_name, true); } } }
/// <summary> /// Determine whether the given sequence number /// matches the most up-to-date status. /// </summary> public bool LastSequenceNumberChanged(int since) { using (JtTimer pt = new JtTimer( "LastSequenceNumberChanged")) { ChangeOptions opt = new ChangeOptions(); opt.Since = since; opt.IncludeDocs = false; CouchChanges <DbFurniture> changes = _db.GetChanges <DbFurniture>(opt); CouchChangeResult <DbFurniture> r = changes.Results.LastOrDefault < CouchChangeResult <DbFurniture> >(); Debug.Assert(null == r || since < r.Sequence, "expected monotone growing sequence number"); return(null != r && since < r.Sequence); } }
/// <summary> /// Repeatedly check database status and raise /// external event when updates are pending. /// Relinquish control and wait for timeout /// period between each attempt. Run in a /// separate thread. /// </summary> static void CheckForPendingDatabaseChanges() { while (null != _event) { ++_nLoopCount; Debug.Assert(null != _event, "expected non-null external event"); if (null != _event) { break; } if (_event.IsPending) { Util.Log(string.Format( "CheckForPendingDatabaseChanges loop {0} - " + "database update event is pending", _nLoopCount)); } else { using (JtTimer pt = new JtTimer( "CheckForPendingDatabaseChanges")) { ++_nCheckCount; Util.Log(string.Format( "CheckForPendingDatabaseChanges loop {0} - " + "check for changes {1}", _nLoopCount, _nCheckCount)); RoomEditorDb rdb = new RoomEditorDb(); if (rdb.LastSequenceNumberChanged( DbUpdater.LastSequence)) { _event.Raise(); ++_nUpdatesRequested; Util.Log(string.Format( "database update pending event raised {0} times", _nUpdatesRequested)); #region Obsolete attempts that failed // Move the mouse in case the user does // not. Otherwise, it may take a while // before Revit forwards the event Raise // to the event handler Execute method. // Just moving the mouse is not enough: //System.Drawing.Point p = Cursor.Position; //Cursor.Position = new System.Drawing // .Point( p.X + 1, p.Y ); //Cursor.Position = p; // This did not work either: //[DllImport( "user32.dll" )] //static extern IntPtr SetFocus( // IntPtr hwnd ); //IWin32Window revit_window // = new JtWindowHandle( // ComponentManager.ApplicationWindow ); //IntPtr hwnd = SetFocus( revit_window.Handle ); //IntPtr hwnd2 = SetFocus( hwnd ); //Debug.Print( "set to rvt {0} --> {1} --> {2}", // revit_window.Handle, hwnd, hwnd2 ); // Try SendKeys? #endregion // Obsolete attempts that failed // Set focus to Revit for a moment. // Otherwise, it may take a while before // Revit forwards the event Raise to the // event handler Execute method. IntPtr hBefore = GetForegroundWindow(); SetForegroundWindow( ComponentManager.ApplicationWindow); SetForegroundWindow(hBefore); } } } // Wait a moment and relinquish control before // next check for pending database updates. Thread.Sleep(_timeout); } }
/// <summary> /// Apply all current cloud database /// changes to the BIM. /// </summary> public void UpdateBim() { Util.Log("UpdateBim begin"); using (JtTimer pt = new JtTimer("UpdateBim")) { Document doc = _uiapp.ActiveUIDocument.Document; // Retrieve all room unique ids in model: FilteredElementCollector rooms = new FilteredElementCollector(doc) .OfClass(typeof(SpatialElement)) .OfCategory(BuiltInCategory.OST_Rooms); IEnumerable <string> roomUniqueIds = rooms.Select <Element, string>( e => e.UniqueId); // Convert to a dictionary for faster lookup: _roomUniqueIdDict = new Dictionary <string, int>( roomUniqueIds.Count()); foreach (string s in roomUniqueIds) { _roomUniqueIdDict.Add(s, 1); } //string ids = "?keys=[%22" + string.Join( // "%22,%22", roomUniqueIds ) + "%22]"; // Retrieve all furniture transformations // after the last sequence number: CouchDatabase db = new RoomEditorDb().Db; ChangeOptions opt = new ChangeOptions(); opt.IncludeDocs = true; opt.Since = LastSequence; opt.View = "roomedit/map_room_to_furniture"; // I tried to add a filter to this view, but // that is apparently not supported by the // CouchDB or DreamSeat GetChanges functionality. //+ ids; // failed attempt to filter view by room id keys // Specify filter function defined in // design document to get updates //opt.Filter = CouchChanges <DbFurniture> changes = db.GetChanges <DbFurniture>(opt); CouchChangeResult <DbFurniture>[] results = changes.Results; foreach (CouchChangeResult <DbFurniture> result in results) { UpdateBimFurniture(result.Doc); LastSequence = result.Sequence; } } Util.Log("UpdateBim end"); }
/// <summary> /// Toggle on and off subscription to /// automatic cloud updates. /// </summary> public static ExternalEvent ToggleSubscription( // EventHandler<IdlingEventArgs> handler IExternalEventHandler handler) { if( Subscribed ) { Debug.Print( "Unsubscribing..." ); //_uiapp.Idling -= _handler; //_handler = null; _event.Dispose(); _event = null; _buttons[_subscribeButtonIndex].ItemText = _subscribe; _timer.Stop(); _timer.Report( "Subscription timing" ); _timer = null; Debug.Print( "Unsubscribed." ); } else { Debug.Print( "Subscribing..." ); //_uiapp.Idling += handler; //_handler = handler; _event = ExternalEvent.Create( handler ); _buttons[_subscribeButtonIndex].ItemText = _unsubscribe; _timer = new JtTimer( "Subscription" ); Debug.Print( "Subscribed." ); } return _event; }
/// <summary> /// Wait far a moment before requerying database. /// </summary> //static Stopwatch _stopwatch = null; void OnIdling( object sender, IdlingEventArgs ea) { using (JtTimer pt = new JtTimer("OnIdling")) { // Use with care! This loads the CPU: ea.SetRaiseWithoutDelay(); ++_counter; if (0 == (_counter % _update_interval)) { if (0 == (_counter % _message_interval)) { Util.Log(string.Format( "OnIdling called {0} times", _counter)); } // Have we waited long enough since the last attempt? //if( null == _stopwatch // || _stopwatch.ElapsedMilliseconds > 500 ) RoomEditorDb rdb = new RoomEditorDb(); //int n = rdb.LastSequenceNumber; if (rdb.LastSequenceNumberChanged( DbUpdater.LastSequence)) { UIApplication uiapp = sender as UIApplication; Document doc = uiapp.ActiveUIDocument.Document; Util.Log("furniture update begin"); //FilteredElementCollector rooms // = new FilteredElementCollector( doc ) // .OfClass( typeof( SpatialElement ) ) // .OfCategory( BuiltInCategory.OST_Rooms ); //IEnumerable<string> roomUniqueIds // = rooms.Select<Element, string>( // e => e.UniqueId ); //CouchDatabase db = rdb.Db; //ChangeOptions opt = new ChangeOptions(); //opt.IncludeDocs = true; //opt.Since = CmdUpdate.LastSequence; //opt.View = "roomedit/map_room_to_furniture"; //CouchChanges<DbFurniture> changes // = db.GetChanges<DbFurniture>( opt ); //CouchChangeResult<DbFurniture>[] results // = changes.Results; //DbUpdater updater = new DbUpdater( // doc, roomUniqueIds ); //foreach( CouchChangeResult<DbFurniture> result // in results ) //{ // updater.UpdateBimFurniture( result.Doc ); // CmdUpdate.LastSequence = result.Sequence; //} DbUpdater updater = new DbUpdater(uiapp); updater.UpdateBim(); Util.Log("furniture update end"); // _stopwatch = new Stopwatch(); // _stopwatch.Start(); //} //catch( Exception ex ) //{ // //uiapp.Application.WriteJournalComment // Debug.Print( // "Room Editor: an error occurred " // + "executing the OnIdling event:\r\n" // + ex.ToString() ); // Debug.WriteLine( ex ); //} } } } }
/// <summary> /// Repeatedly check database status and raise /// external event when updates are pending. /// Relinquish control and wait for timeout /// period between each attempt. Run in a /// separate thread. /// </summary> static void CheckForPendingDatabaseChanges() { while( null != App.Event ) { ++_nLoopCount; //Debug.Assert( null != _event, //"expected non-null external event" ); //if( null == _event ) //{ // break; //} if( App.Event.IsPending ) { Util.Log( string.Format( "CheckForPendingDatabaseChanges loop {0} - " + "database update event is pending", _nLoopCount ) ); } else { using( JtTimer pt = new JtTimer( "CheckForPendingDatabaseChanges" ) ) { ++_nCheckCount; Util.Log( string.Format( "CheckForPendingDatabaseChanges loop {0} - " + "check for changes {1}", _nLoopCount, _nCheckCount ) ); RoomEditorDb rdb = new RoomEditorDb(); if( rdb.LastSequenceNumberChanged( DbUpdater.LastSequence ) ) { App.Event.Raise(); ++_nUpdatesRequested; Util.Log( string.Format( "database update pending event raised {0} times", _nUpdatesRequested ) ); #region Obsolete attempts that failed // Move the mouse in case the user does // not. Otherwise, it may take a while // before Revit forwards the event Raise // to the event handler Execute method. // Just moving the mouse is not enough: //System.Drawing.Point p = Cursor.Position; //Cursor.Position = new System.Drawing // .Point( p.X + 1, p.Y ); //Cursor.Position = p; // This did not work either: //[DllImport( "user32.dll" )] //static extern IntPtr SetFocus( // IntPtr hwnd ); //IWin32Window revit_window // = new JtWindowHandle( // ComponentManager.ApplicationWindow ); //IntPtr hwnd = SetFocus( revit_window.Handle ); //IntPtr hwnd2 = SetFocus( hwnd ); //Debug.Print( "set to rvt {0} --> {1} --> {2}", // revit_window.Handle, hwnd, hwnd2 ); // Try SendKeys? #endregion // Obsolete attempts that failed // Set focus to Revit for a moment. // Otherwise, it may take a while before // Revit forwards the event Raise to the // event handler Execute method. IntPtr hBefore = GetForegroundWindow(); SetForegroundWindow( ComponentManager.ApplicationWindow ); SetForegroundWindow( hBefore ); } } } // Wait a moment and relinquish control before // next check for pending database updates. Thread.Sleep( _timeout ); } }
/// <summary> /// Apply all current cloud database /// changes to the BIM. /// </summary> public void UpdateBim() { Util.Log( "UpdateBim begin" ); using( JtTimer pt = new JtTimer( "UpdateBim" ) ) { Document doc = _uiapp.ActiveUIDocument.Document; // Retrieve all room unique ids in model: FilteredElementCollector rooms = new FilteredElementCollector( doc ) .OfClass( typeof( SpatialElement ) ) .OfCategory( BuiltInCategory.OST_Rooms ); IEnumerable<string> roomUniqueIds = rooms.Select<Element, string>( e => e.UniqueId ); // Convert to a dictionary for faster lookup: _roomUniqueIdDict = new Dictionary<string, int>( roomUniqueIds.Count() ); foreach( string s in roomUniqueIds ) { _roomUniqueIdDict.Add( s, 1 ); } //string ids = "?keys=[%22" + string.Join( // "%22,%22", roomUniqueIds ) + "%22]"; // Retrieve all furniture transformations // after the last sequence number: CouchDatabase db = new RoomEditorDb().Db; ChangeOptions opt = new ChangeOptions(); opt.IncludeDocs = true; opt.Since = LastSequence; opt.View = "roomedit/map_room_to_furniture"; // I tried to add a filter to this view, but // that is apparently not supported by the // CouchDB or DreamSeat GetChanges functionality. //+ ids; // failed attempt to filter view by room id keys // Specify filter function defined in // design document to get updates //opt.Filter = CouchChanges<DbFurniture> changes = db.GetChanges<DbFurniture>( opt ); CouchChangeResult<DbFurniture>[] results = changes.Results; foreach( CouchChangeResult<DbFurniture> result in results ) { UpdateBimFurniture( result.Doc ); LastSequence = result.Sequence; } } Util.Log( "UpdateBim end" ); }
/// <summary> /// Wait far a moment before requerying database. /// </summary> //static Stopwatch _stopwatch = null; void OnIdling( object sender, IdlingEventArgs ea ) { using( JtTimer pt = new JtTimer( "OnIdling" ) ) { // Use with care! This loads the CPU: ea.SetRaiseWithoutDelay(); ++_counter; if( 0 == ( _counter % _update_interval ) ) { if( 0 == ( _counter % _message_interval ) ) { Util.Log( string.Format( "OnIdling called {0} times", _counter ) ); } // Have we waited long enough since the last attempt? //if( null == _stopwatch // || _stopwatch.ElapsedMilliseconds > 500 ) RoomEditorDb rdb = new RoomEditorDb(); //int n = rdb.LastSequenceNumber; if( rdb.LastSequenceNumberChanged( DbUpdater.LastSequence ) ) { UIApplication uiapp = sender as UIApplication; Document doc = uiapp.ActiveUIDocument.Document; Util.Log( "furniture update begin" ); //FilteredElementCollector rooms // = new FilteredElementCollector( doc ) // .OfClass( typeof( SpatialElement ) ) // .OfCategory( BuiltInCategory.OST_Rooms ); //IEnumerable<string> roomUniqueIds // = rooms.Select<Element, string>( // e => e.UniqueId ); //CouchDatabase db = rdb.Db; //ChangeOptions opt = new ChangeOptions(); //opt.IncludeDocs = true; //opt.Since = CmdUpdate.LastSequence; //opt.View = "roomedit/map_room_to_furniture"; //CouchChanges<DbFurniture> changes // = db.GetChanges<DbFurniture>( opt ); //CouchChangeResult<DbFurniture>[] results // = changes.Results; //DbUpdater updater = new DbUpdater( // doc, roomUniqueIds ); //foreach( CouchChangeResult<DbFurniture> result // in results ) //{ // updater.UpdateBimFurniture( result.Doc ); // CmdUpdate.LastSequence = result.Sequence; //} DbUpdater updater = new DbUpdater( uiapp ); updater.UpdateBim(); Util.Log( "furniture update end" ); // _stopwatch = new Stopwatch(); // _stopwatch.Start(); //} //catch( Exception ex ) //{ // //uiapp.Application.WriteJournalComment // Debug.Print( // "Room Editor: an error occurred " // + "executing the OnIdling event:\r\n" // + ex.ToString() ); // Debug.WriteLine( ex ); //} } } } }