UndoCommandPtr Selection::AddItems(const OS_ObjectDumbPtr &items, const SelectionChangingSignature::Delegate& emitterChanging, const SelectionChangedSignature::Delegate& emitterChanged) { if ( items.Empty() ) { return NULL; } EDITOR_SCENE_SCOPE_TIMER( ("") ); SimpleTimer timer; std::vector<Reflect::Object*> added; OS_ObjectDumbPtr temp = m_Items; OS_ObjectDumbPtr::Iterator itr = items.Begin(); OS_ObjectDumbPtr::Iterator end = items.End(); for ( ; itr != end; ++itr ) { if ( temp.Append(*itr) ) { added.push_back(*itr); } } UndoCommandPtr command; if ( !temp.Empty() ) { SelectionChangingArgs args ( temp ); m_SelectionChanging.RaiseWithEmitter( args, emitterChanging ); if ( !args.m_Veto ) { command = new SelectionChangeCommand( this ); std::vector<Reflect::Object*>::iterator itr = added.begin(); std::vector<Reflect::Object*>::iterator end = added.end(); for ( ; itr != end; ++itr ) { SceneNode *pSceneNode = Reflect::SafeCast<SceneNode>(*itr); if (pSceneNode) { pSceneNode->SetSelected(true); } } m_Items = temp; m_SelectionChanged.RaiseWithEmitter(m_Items, emitterChanged); } } Log::Profile( TXT( "Selection AddItems took %fms\n" ), timer.Elapsed()); return command; }
void Selection::Refresh() { EDITOR_SCENE_SCOPE_TIMER( ("") ); SimpleTimer timer; m_SelectionChanging.Raise(m_Items); // do nothing m_SelectionChanged.Raise(m_Items); Log::Profile( TXT( "Selection Refresh took %fms\n" ), timer.Elapsed()); }
void CreateTool::CreateMultipleObjects( bool stamp ) { HELIUM_EDITOR_SCENE_SCOPE_TIMER( "Place Multiple Instances At Location" ); if ( m_InstanceRadius <= 0.0f ) { return; } if ( m_InstanceOffsets.empty() || m_InstanceUpdateOffsets ) { m_InstanceOffsets.clear(); SetupInstanceOffsets( m_InstanceRadius, m_InstanceOffsets ); m_InstanceUpdateOffsets = false; } float32_t maxTime = 100.0f; SimpleTimer instanceTimer; Vector3 instanceNormalOffset = m_InstanceNormal.Normalize() * 2.0f * s_PaintRadius; while ( m_InstanceOffsets.size() && ( stamp || ( instanceTimer.Elapsed() < maxTime ) ) ) { V_Vector3::iterator itr = m_InstanceOffsets.begin(); Matrix4 instanceTransform; instanceTransform.t = Vector4( *itr ); instanceTransform *= Matrix4( AngleAxis::Rotation( Editor::SideVector, m_InstanceNormal ) ); instanceTransform.t += Vector4( m_InstanceTranslation ); Vector3 point = Vector3( instanceTransform.t.x, instanceTransform.t.y, instanceTransform.t.z ); LinePickVisitor pick( m_Scene->GetViewport()->GetCamera(), Line( point + instanceNormalOffset, point - instanceNormalOffset ) ); Vector3 instanceTranslation; Vector3 instanceNormal; if ( DetermineTranslationAndNormal( pick, instanceTranslation, instanceNormal ) ) { point = Vector3( instanceTranslation.x - m_InstanceTranslation.x, instanceTranslation.y - m_InstanceTranslation.y, instanceTranslation.z - m_InstanceTranslation.z ); if ( point.Length() <= s_PaintRadius ) { CreateSingleObject( instanceTranslation, instanceNormal, true ); } } m_InstanceOffsets.erase( itr ); } }
UndoCommandPtr Selection::Clear(const SelectionChangingSignature::Delegate& emitterChanging, const SelectionChangedSignature::Delegate& emitterChanged) { if (m_Items.Empty()) { return NULL; } EDITOR_SCENE_SCOPE_TIMER( ("") ); SimpleTimer timer; UndoCommandPtr command; OS_ObjectDumbPtr empty; SelectionChangingArgs args ( empty ); m_SelectionChanging.RaiseWithEmitter( args, emitterChanging ); if ( !args.m_Veto ) { command = new SelectionChangeCommand( this ); OS_ObjectDumbPtr::Iterator itr = m_Items.Begin(); OS_ObjectDumbPtr::Iterator end = m_Items.End(); for ( ; itr != end; ++itr ) { SceneNode *pSceneNode = Reflect::SafeCast<SceneNode>(*itr); if (pSceneNode) { pSceneNode->SetSelected(false); } } m_Items.Clear(); m_SelectionChanged.RaiseWithEmitter(m_Items, emitterChanged); } Log::Profile( TXT( "Selection Clear took %fms\n" ), timer.Elapsed()); return command; }
void Tracker::TrackEverything() { HELIUM_ASSERT( m_Project ); m_StopTracking = false; m_InitialIndexingCompleted = false; m_IndexingFailed = false; #pragma TODO("Create default tables/migrate db") std::set< Helium::Path > assetFiles; while ( !m_StopTracking ) { Log::Print( m_InitialIndexingCompleted ? Log::Levels::Verbose : Log::Levels::Default, m_InitialIndexingCompleted ? TXT("Tracker: Looking for new or updated files...\n") : TXT("Tracker: Finding asset files...\n" )); // find all the files in the project { SimpleTimer timer; Helium::Directory directory( m_Project->a_Path.Get().Directory() ); directory.GetFiles( assetFiles, true ); Log::Print( m_InitialIndexingCompleted ? Log::Levels::Verbose : Log::Levels::Default, TXT("Tracker: File reslover database lookup took %.2fms\n"), timer.Elapsed() ); } // for each file m_CurrentProgress = 0; m_Total = (uint32_t)assetFiles.size(); SimpleTimer timer; Log::Print( m_InitialIndexingCompleted ? Log::Levels::Verbose : Log::Levels::Default, TXT("Tracker: Scanning %d asset file(s) for changes...\n"), (uint32_t)assetFiles.size() ); for( std::set< Helium::Path >::const_iterator assetFileItr = assetFiles.begin(), assetFileItrEnd = assetFiles.end(); !m_StopTracking && assetFileItr != assetFileItrEnd; ++assetFileItr ) { Log::Listener listener ( ~Log::Streams::Error ); ++m_CurrentProgress; // see if the file has changed // insert/update the file: path, timestamp, etc... const Helium::Path& assetFilePath = (*assetFileItr); #pragma TODO( "Make a configurable list of places to ignore" ) // skip files in the meta directory if ( assetFilePath.IsUnder( m_Project->a_Path.Get().Directory() + TXT( ".Helium/" ) ) ) { continue; } // start transaction #pragma TODO("Start transaction") try { #pragma TODO("Select tracked from from db, delete db obj if the real file has changed more recently") if ( WildcardMatch( TXT( "Helium*" ), assetFilePath.Extension().c_str() ) ) { #ifdef ASSET_REFACTOR const Asset::AssetClassPtr assetClass = Asset::AssetClass::LoadAssetClass( assetFilePath ); if ( assetClass.ReferencesObject() ) { // get file's properties Helium::SearchableProperties fileProperties; assetClass->GatherSearchableProperties( &fileProperties ); for( std::multimap< tstring, tstring >::const_iterator filePropertiesItr = fileProperties.GetStringProperties().begin(), filePropertiesItrEnd = fileProperties.GetStringProperties().end(); filePropertiesItr != filePropertiesItrEnd; ++filePropertiesItr ) { //TrackedProperty TrackedProperty prop( *m_TrackerDB ); prop.mName = filePropertiesItr->first; prop.update(); assetTrackedFile.properties().link( prop, filePropertiesItr->second ); } // get file's dependencies std::set< Helium::Path > fileReferences; assetClass->GetFileReferences( fileReferences ); for( std::set< Helium::Path >::const_iterator fileRefsItr = fileReferences.begin(), fileRefsItrEnd = fileReferences.end(); fileRefsItr != fileRefsItrEnd; ++fileRefsItr ) { // see if the file has changed const Helium::Path& fileRefPath = (*fileRefsItr); TrackedFile fileRefTrackedFile( *m_TrackerDB ); fileRefTrackedFile.mPath = fileRefPath.Get(); fileRefTrackedFile.update(); assetTrackedFile.fileReferences().link( fileRefTrackedFile ); } } #endif } #pragma TODO("Clear broken flag in the tracked file object") } catch ( const Helium::Exception& e ) { Log::Error( TXT( "Exception in Tracker thread: %s" ), e.What() ); #pragma TODO("Set the broken flag in the tracked file object") } catch ( ... ) { Log::Error( TXT( "Unknown exception in Tracker thread." ) ); #pragma TODO("Rollback transaction") // the consequences could never be the same here, rethrow throw; } #pragma TODO("Update and commit object state") #if 0 // update LastModified assetTrackedFile.mPath = assetFilePath.GetRelativePath( m_Project->a_Path.Get() ).Get(); assetTrackedFile.mSize = (int32_t) assetFilePath.Size(); assetTrackedFile.mLastModified = litesql::DateTime( assetFilePath.ModifiedTime() ); assetTrackedFile.mToolsVersion = HELIUM_VERSION_NUMBER; assetTrackedFile.update(); // commit transaction m_TrackerDB->commit(); #endif } if ( m_StopTracking ) { uint32_t percentComplete = (uint32_t)(((float32_t)m_CurrentProgress/(float32_t)m_Total) * 100); Log::Print( m_InitialIndexingCompleted ? Log::Levels::Verbose : Log::Levels::Default, TXT("Tracker: Indexing (%d%% complete) pre-empted after %.2fm\n"), percentComplete, timer.Elapsed() / 1000.f / 60.f ); } else if ( !m_InitialIndexingCompleted ) { m_InitialIndexingCompleted = true; Log::Print( TXT("Tracker: Initial indexing completed in %.2fm\n"), timer.Elapsed() / 1000.f / 60.f ); } else { Log::Print( Log::Levels::Verbose, TXT("Tracker: Indexing updated in %.2fm\n") , timer.Elapsed() / 1000.f / 60.f ); } m_Total = 0; m_CurrentProgress = 0; //////////////////////////////// // Recurse if ( !m_StopTracking ) { // Sleep between runs and yield to other threads // The complex loop is to prevent Editor from hanging on exit (max hang will be "increments" seconds) SleepBetweenTracking( &m_StopTracking ); } } }