/// <summary> /// Determine and set the last sequence /// number after updating database. /// </summary> static public int SetLastSequence() { LastSequence = new RoomEditorDb() .LastSequenceNumber; Util.InfoMsg( string.Format( "Last sequence number set to {0}." + "\nChanges from now on will be applied.", LastSequence ) ); return LastSequence; }
/// <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 ); //} } } } }