diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /tools/pet/petdoc.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'tools/pet/petdoc.cpp')
| -rw-r--r-- | tools/pet/petdoc.cpp | 536 |
1 files changed, 536 insertions, 0 deletions
diff --git a/tools/pet/petdoc.cpp b/tools/pet/petdoc.cpp new file mode 100644 index 0000000..707a77a --- /dev/null +++ b/tools/pet/petdoc.cpp @@ -0,0 +1,536 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "petdoc.h" +#include "tier1/KeyValues.h" +#include "tier1/utlbuffer.h" +#include "toolutils/enginetools_int.h" +#include "filesystem.h" +#include "pettool.h" +#include "toolframework/ienginetool.h" +#include "movieobjects/dmeparticlesystemdefinition.h" +#include "datamodel/idatamodel.h" +#include "toolutils/attributeelementchoicelist.h" +#include "particlesystemdefinitionbrowser.h" +#include "vgui_controls/messagebox.h" +#include "particles/particles.h" +#include "particlesystempropertiescontainer.h" +#include "dme_controls/particlesystempanel.h" +#include "dme_controls/dmecontrols.h" + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CPetDoc::CPetDoc( IPetDocCallback *pCallback ) : m_pCallback( pCallback ) +{ + m_hRoot = NULL; + m_pFileName[0] = 0; + m_bDirty = false; + g_pDataModel->InstallNotificationCallback( this ); + SetElementPropertiesChoices( this ); +} + +CPetDoc::~CPetDoc() +{ + if ( m_hRoot.Get() ) + { + g_pDataModel->RemoveFileId( m_hRoot->GetFileId() ); + m_hRoot = NULL; + } + g_pDataModel->RemoveNotificationCallback( this ); + SetElementPropertiesChoices( NULL ); +} + + +//----------------------------------------------------------------------------- +// Inherited from INotifyUI +//----------------------------------------------------------------------------- +void CPetDoc::NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags ) +{ + OnDataChanged( pReason, nNotifySource, nNotifyFlags ); +} + + +bool CPetDoc::GetIntChoiceList( const char *pChoiceListType, CDmElement *pElement, + const char *pAttributeName, bool bArrayElement, IntChoiceList_t &list ) +{ + if ( !Q_stricmp( pChoiceListType, "particlefield" ) ) + { + for ( int i = 0; i < MAX_PARTICLE_ATTRIBUTES; ++i ) + { + const char *pName = g_pParticleSystemMgr->GetParticleFieldName( i ); + if ( pName ) + { + int j = list.AddToTail(); + list[j].m_nValue = i; + list[j].m_pChoiceString = pName; + } + } + return true; + } + + if ( !Q_stricmp( pChoiceListType, "particlefield_scalar" ) ) + { + for ( int i = 0; i < MAX_PARTICLE_ATTRIBUTES; ++i ) + { + if ( ( ATTRIBUTES_WHICH_ARE_VEC3S_MASK & ( 1 << i ) ) != 0 ) + continue; + + const char *pName = g_pParticleSystemMgr->GetParticleFieldName( i ); + if ( pName ) + { + int j = list.AddToTail(); + list[j].m_nValue = i; + list[j].m_pChoiceString = pName; + } + } + return true; + } + + if ( !Q_stricmp( pChoiceListType, "particlefield_vector" ) ) + { + for ( int i = 0; i < MAX_PARTICLE_ATTRIBUTES; ++i ) + { + if ( ( ATTRIBUTES_WHICH_ARE_VEC3S_MASK & ( 1 << i ) ) == 0 ) + continue; + + const char *pName = g_pParticleSystemMgr->GetParticleFieldName( i ); + if ( pName ) + { + int j = list.AddToTail(); + list[j].m_nValue = i; + list[j].m_pChoiceString = pName; + } + } + return true; + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Gets the file name +//----------------------------------------------------------------------------- +const char *CPetDoc::GetFileName() +{ + return m_pFileName; +} + +void CPetDoc::SetFileName( const char *pFileName ) +{ + Q_strncpy( m_pFileName, pFileName, sizeof( m_pFileName ) ); + Q_FixSlashes( m_pFileName ); + SetDirty( true ); +} + +//----------------------------------------------------------------------------- +// Dirty bits +//----------------------------------------------------------------------------- +void CPetDoc::SetDirty( bool bDirty ) +{ + m_bDirty = bDirty; +} + +bool CPetDoc::IsDirty() const +{ + return m_bDirty; +} + + +//----------------------------------------------------------------------------- +// Creates the root element +//----------------------------------------------------------------------------- +bool CPetDoc::CreateRootElement() +{ + Assert( !m_hRoot.Get() ); + + DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( GetFileName() ); + + // Create the main element + m_hRoot = g_pDataModel->CreateElement( "DmElement", GetFileName(), fileid ); + if ( m_hRoot == DMELEMENT_HANDLE_INVALID ) + return false; + + g_pDataModel->SetFileRoot( fileid, m_hRoot ); + + // We need to create an element array attribute storing particle system definitions + m_hRoot->AddAttribute( "particleSystemDefinitions", AT_ELEMENT_ARRAY ); + return true; +} + + +//----------------------------------------------------------------------------- +// Creates a new document +//----------------------------------------------------------------------------- +void CPetDoc::CreateNew() +{ + Assert( !m_hRoot.Get() ); + + // This is not undoable + CDisableUndoScopeGuard guard; + + Q_strncpy( m_pFileName, "untitled", sizeof( m_pFileName ) ); + + // Create the main element + if ( !CreateRootElement() ) + return; + + SetDirty( false ); +} + + +//----------------------------------------------------------------------------- +// Saves/loads from file +//----------------------------------------------------------------------------- +bool CPetDoc::LoadFromFile( const char *pFileName ) +{ + Assert( !m_hRoot.Get() ); + + CAppDisableUndoScopeGuard guard( "CPetDoc::LoadFromFile", NOTIFY_CHANGE_OTHER ); + SetDirty( false ); + + if ( !pFileName[0] ) + return false; + + Q_strncpy( m_pFileName, pFileName, sizeof( m_pFileName ) ); + + CDmElement *pRoot = NULL; + DmFileId_t fileid = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pRoot, CR_DELETE_OLD ); + + if ( fileid == DMFILEID_INVALID ) + { + m_pFileName[0] = 0; + return false; + } + + m_hRoot = pRoot; + + SetDirty( false ); + return true; +} + +void CPetDoc::SaveToFile( ) +{ + if ( m_hRoot.Get() && m_pFileName && m_pFileName[0] ) + { + g_pDataModel->SaveToFile( m_pFileName, NULL, "binary", PET_FILE_FORMAT, m_hRoot ); + } + + SetDirty( false ); +} + + +//----------------------------------------------------------------------------- +// Returns the root object +//----------------------------------------------------------------------------- +CDmElement *CPetDoc::GetRootObject() +{ + return m_hRoot; +} + + +//----------------------------------------------------------------------------- +// Returns the root object fileid +//----------------------------------------------------------------------------- +DmFileId_t CPetDoc::GetFileId() +{ + return m_hRoot.Get() ? m_hRoot->GetFileId() : DMFILEID_INVALID; +} + + +//----------------------------------------------------------------------------- +// Returns the particle system definition list +//----------------------------------------------------------------------------- +CDmAttribute *CPetDoc::GetParticleSystemDefinitionList() +{ + CDmrElementArray<> array( m_hRoot, "particleSystemDefinitions" ); + return array.GetAttribute(); +} + + +void CPetDoc::AddNewParticleSystemDefinition( CDmeParticleSystemDefinition *pNew, CUndoScopeGuard &Guard ) +{ + CDmrParticleSystemList particleSystemList( GetParticleSystemDefinitionList() ); + + particleSystemList.AddToTail( pNew ); + Guard.Release(); + + // Force a resolve to get the particle created + g_pDmElementFramework->Operate( true ); + g_pDmElementFramework->BeginEdit(); + + UpdateParticleDefinition( pNew ); +} + +//----------------------------------------------------------------------------- +// Adds a new particle system definition +//----------------------------------------------------------------------------- +CDmeParticleSystemDefinition* CPetDoc::AddNewParticleSystemDefinition( const char *pName ) +{ + if ( !pName || !pName[0] ) + { + pName = "New Particle System"; + } + + CDmeParticleSystemDefinition *pParticleSystem; + { + CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Add Particle System", "Add Particle System" ); + + pParticleSystem = CreateElement<CDmeParticleSystemDefinition>( pName, GetFileId() ); + AddNewParticleSystemDefinition( pParticleSystem, guard ); + } + + return pParticleSystem; +} + + +//----------------------------------------------------------------------------- +// Refresh all particle definitions +//----------------------------------------------------------------------------- +void CPetDoc::UpdateAllParticleSystems( ) +{ + // Force a resolve to get the particle created + g_pDmElementFramework->Operate( true ); + g_pDmElementFramework->BeginEdit(); + + CDmrParticleSystemList particleSystemList( GetParticleSystemDefinitionList() ); + int nCount = particleSystemList.Count(); + for ( int i = 0; i < nCount; ++i ) + { + UpdateParticleDefinition( particleSystemList[i] ); + } +} + + +//----------------------------------------------------------------------------- +// Deletes a particle system definition +//----------------------------------------------------------------------------- +void CPetDoc::DeleteParticleSystemDefinition( CDmeParticleSystemDefinition *pParticleSystem ) +{ + if ( !pParticleSystem ) + return; + + CDmrParticleSystemList particleSystemList( GetParticleSystemDefinitionList() ); + int nCount = particleSystemList.Count(); + for ( int i = 0; i < nCount; ++i ) + { + if ( pParticleSystem == particleSystemList[i] ) + { + CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Delete Particle System", "Delete Particle System" ); + particleSystemList.FastRemove( i ); + break; + } + } + + // Find all CDmeParticleChilds referring to this function + CUtlVector< CDmeParticleChild* > children; + FindAncestorsReferencingElement( pParticleSystem, children ); + int nChildCount = children.Count(); + for ( int i = 0; i < nChildCount; ++i ) + { + CDmeParticleChild *pChildReference = children[i]; + CDmeParticleSystemDefinition *pParent = FindReferringElement<CDmeParticleSystemDefinition>( pChildReference, "children" ); + if ( !pParent ) + continue; + + pParent->RemoveFunction( FUNCTION_CHILDREN, pChildReference ); + DestroyElement( pChildReference, TD_NONE ); + } + + DestroyElement( pParticleSystem, TD_DEEP ); +} + + +CDmeParticleSystemDefinition *CPetDoc::FindParticleSystemDefinition( const char *pName ) +{ + CDmrParticleSystemList particleSystemList( GetParticleSystemDefinitionList() ); + int nCount = particleSystemList.Count(); + for ( int i = 0; i < nCount; ++i ) + { + CDmeParticleSystemDefinition* pParticleSystem = particleSystemList[i]; + if ( !Q_stricmp( pName, pParticleSystem->GetName() ) ) + return pParticleSystem; + } + return NULL; +} + + +//----------------------------------------------------------------------------- +// Deletes a particle system definition +//----------------------------------------------------------------------------- +void CPetDoc::ReplaceParticleSystemDefinition( CDmeParticleSystemDefinition *pParticleSystem ) +{ + if ( !pParticleSystem ) + return; + + CDmrParticleSystemList particleSystemList( GetParticleSystemDefinitionList() ); + int nCount = particleSystemList.Count(); + int nFoundIndex = -1; + for ( int i = 0; i < nCount; ++i ) + { + if ( !particleSystemList[i] ) + continue; + + if ( !Q_stricmp( particleSystemList[i]->GetName(), pParticleSystem->GetName() ) ) + { + nFoundIndex = i; + break; + } + } + + if ( nFoundIndex < 0 ) + { + CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Replace Particle System", "Replace Particle System" ); + CDmrParticleSystemList particleSystemList( GetParticleSystemDefinitionList() ); + pParticleSystem->SetFileId( m_hRoot->GetFileId(), TD_ALL ); + particleSystemList.AddToTail( pParticleSystem ); + return; + } + + CDmeParticleSystemDefinition *pOldParticleSystem = particleSystemList[nFoundIndex]; + + // This can happen if we unserialized w/ replace + if ( pOldParticleSystem == pParticleSystem ) + return; + + CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Replace Particle System", "Replace Particle System" ); + + particleSystemList.Set( nFoundIndex, pParticleSystem ); + pParticleSystem->SetFileId( m_hRoot->GetFileId(), TD_ALL ); + + // Find all CDmeParticleChilds referring to this function + CUtlVector< CDmeParticleChild* > children; + FindAncestorsReferencingElement( pOldParticleSystem, children ); + int nChildCount = children.Count(); + for ( int i = 0; i < nChildCount; ++i ) + { + CDmeParticleChild *pChildReference = children[i]; + pChildReference->m_Child = pParticleSystem; + } + + DestroyElement( pOldParticleSystem, TD_SHALLOW ); +} + + +//----------------------------------------------------------------------------- +// Does a particle system exist already? +//----------------------------------------------------------------------------- +bool CPetDoc::IsParticleSystemDefined( const char *pName ) +{ + return FindParticleSystemDefinition( pName ) != NULL; +} + + +//----------------------------------------------------------------------------- +// Updates a specific particle defintion +//----------------------------------------------------------------------------- +void CPetDoc::UpdateParticleDefinition( CDmeParticleSystemDefinition *pDef ) +{ + if ( !pDef ) + return; + + CUtlBuffer buf; + g_pDataModel->Serialize( buf, "binary", PET_FILE_FORMAT, pDef->GetHandle() ); + + // Tell the game about the new definitions + if ( clienttools ) + { + clienttools->ReloadParticleDefintions( GetFileName(), buf.Base(), buf.TellMaxPut() ); + } + if ( servertools ) + { + servertools->ReloadParticleDefintions( GetFileName(), buf.Base(), buf.TellMaxPut() ); + } + + // Let the other tools know + KeyValues *pMessage = new KeyValues( "ParticleSystemUpdated" ); + pMessage->SetPtr( "definitionBits", buf.Base() ); + pMessage->SetInt( "definitionSize", buf.TellMaxPut() ); + g_pPetTool->PostMessageToAllTools( pMessage ); + pMessage->deleteThis(); +} + + +//----------------------------------------------------------------------------- +// Populate string choice lists +//----------------------------------------------------------------------------- +bool CPetDoc::GetStringChoiceList( const char *pChoiceListType, CDmElement *pElement, + const char *pAttributeName, bool bArrayElement, StringChoiceList_t &list ) +{ + if ( !Q_stricmp( pChoiceListType, "particleSystemDefinitions" ) ) + { + CDmrParticleSystemList particleSystemList( GetParticleSystemDefinitionList() ); + + StringChoice_t sChoice; + sChoice.m_pValue = ""; + sChoice.m_pChoiceString = ""; + list.AddToTail( sChoice ); + + int nCount = particleSystemList.Count(); + for ( int i = 0; i < nCount; ++i ) + { + CDmeParticleSystemDefinition *pParticleSystem = particleSystemList[ i ]; + + StringChoice_t sChoice; + sChoice.m_pValue = pParticleSystem->GetName(); + sChoice.m_pChoiceString = pParticleSystem->GetName(); + list.AddToTail( sChoice ); + } + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Populate element choice lists +//----------------------------------------------------------------------------- +bool CPetDoc::GetElementChoiceList( const char *pChoiceListType, CDmElement *pElement, + const char *pAttributeName, bool bArrayElement, ElementChoiceList_t &list ) +{ + if ( !Q_stricmp( pChoiceListType, "allelements" ) ) + { + AddElementsRecursively( m_hRoot, list ); + return true; + } + + if ( !Q_stricmp( pChoiceListType, "particleSystemDefinitions" ) ) + { + CDmrParticleSystemList particleSystemList( GetParticleSystemDefinitionList() ); + + int nCount = particleSystemList.Count(); + for ( int i = 0; i < nCount; ++i ) + { + CDmeParticleSystemDefinition *pParticleSystem = particleSystemList[ i ]; + ElementChoice_t sChoice; + sChoice.m_pValue = pParticleSystem; + sChoice.m_pChoiceString = pParticleSystem->GetName(); + list.AddToTail( sChoice ); + } + return ( nCount > 0 ); + } + + // by default, try to treat the choice list type as a Dme element type + AddElementsRecursively( m_hRoot, list, pChoiceListType ); + + return list.Count() > 0; +} + + +//----------------------------------------------------------------------------- +// Called when data changes +//----------------------------------------------------------------------------- +void CPetDoc::OnDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags ) +{ + SetDirty( nNotifyFlags & NOTIFY_SETDIRTYFLAG ? true : false ); + m_pCallback->OnDocChanged( pReason, nNotifySource, nNotifyFlags ); +} + + |