Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

938 lines
32 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef IDATAMODEL_H
  7. #define IDATAMODEL_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "tier1/interface.h"
  12. #include "tier1/utlvector.h"
  13. #include "tier1/utlsymbol.h"
  14. #include "appframework/IAppSystem.h"
  15. #include "datamodel/dmattributetypes.h"
  16. //-----------------------------------------------------------------------------
  17. // Forward declarations:
  18. //-----------------------------------------------------------------------------
  19. class CDmAttribute;
  20. class CDmElement;
  21. class IDmeOperator;
  22. class IElementForKeyValueCallback;
  23. struct DmValueBase_t;
  24. class CUtlBuffer;
  25. class KeyValues;
  26. class CUtlSymbolTable;
  27. class CUtlCharConversion;
  28. //-----------------------------------------------------------------------------
  29. // data file format info
  30. //-----------------------------------------------------------------------------
  31. #define DMX_LEGACY_VERSION_STARTING_TOKEN "<!-- DMXVersion"
  32. #define DMX_LEGACY_VERSION_ENDING_TOKEN "-->"
  33. #define DMX_VERSION_STARTING_TOKEN "<!-- dmx"
  34. #define DMX_VERSION_ENDING_TOKEN "-->"
  35. #define GENERIC_DMX_FORMAT "dmx"
  36. enum
  37. {
  38. DMX_MAX_FORMAT_NAME_MAX_LENGTH = 64,
  39. DMX_MAX_HEADER_LENGTH = 40 + 2 * DMX_MAX_FORMAT_NAME_MAX_LENGTH,
  40. };
  41. struct DmxHeader_t
  42. {
  43. char encodingName[ DMX_MAX_FORMAT_NAME_MAX_LENGTH ];
  44. int nEncodingVersion;
  45. char formatName[ DMX_MAX_FORMAT_NAME_MAX_LENGTH ];
  46. int nFormatVersion;
  47. DmxHeader_t() : nEncodingVersion( -1 ), nFormatVersion( -1 )
  48. {
  49. encodingName[ 0 ] = formatName[ 0 ] = '\0';
  50. }
  51. };
  52. //-----------------------------------------------------------------------------
  53. // element framework phases
  54. //-----------------------------------------------------------------------------
  55. enum DmPhase_t
  56. {
  57. PH_EDIT,
  58. PH_EDIT_APPLY,
  59. PH_EDIT_RESOLVE,
  60. PH_DEPENDENCY,
  61. PH_OPERATE,
  62. PH_OPERATE_RESOLVE,
  63. PH_OUTPUT,
  64. };
  65. //-----------------------------------------------------------------------------
  66. // file id - also used to refer to elements that don't have file associations
  67. //-----------------------------------------------------------------------------
  68. enum DmFileId_t
  69. {
  70. DMFILEID_INVALID = 0xffffffff
  71. };
  72. //-----------------------------------------------------------------------------
  73. // Handle to an CDmAttribute
  74. //-----------------------------------------------------------------------------
  75. enum DmAttributeHandle_t
  76. {
  77. DMATTRIBUTE_HANDLE_INVALID = 0xffffffff
  78. };
  79. //-----------------------------------------------------------------------------
  80. // Handle to an DmAttributeList_t
  81. //-----------------------------------------------------------------------------
  82. enum DmAttributeReferenceIterator_t
  83. {
  84. DMATTRIBUTE_REFERENCE_ITERATOR_INVALID = 0
  85. };
  86. //-----------------------------------------------------------------------------
  87. // element framework interface
  88. //-----------------------------------------------------------------------------
  89. abstract_class IDmElementFramework : public IAppSystem
  90. {
  91. public:
  92. // Methods of IAppSystem
  93. virtual bool Connect( CreateInterfaceFn factory ) = 0;
  94. virtual void Disconnect() = 0;
  95. virtual void *QueryInterface( const char *pInterfaceName ) = 0;
  96. virtual InitReturnVal_t Init() = 0;
  97. virtual void Shutdown() = 0;
  98. virtual DmPhase_t GetPhase() = 0;
  99. virtual void SetOperators( const CUtlVector< IDmeOperator* > &operators ) = 0;
  100. virtual void BeginEdit() = 0; // ends in edit phase, forces apply/resolve if from edit phase
  101. virtual void Operate( bool bResolve ) = 0; // ends in output phase
  102. virtual void Resolve() = 0;
  103. };
  104. //-----------------------------------------------------------------------------
  105. // Used only by aplpications to hook in the element framework
  106. //-----------------------------------------------------------------------------
  107. #define VDMELEMENTFRAMEWORK_VERSION "VDmElementFrameworkVersion001"
  108. //-----------------------------------------------------------------------------
  109. // Main interface
  110. //-----------------------------------------------------------------------------
  111. extern IDmElementFramework *g_pDmElementFramework;
  112. //-----------------------------------------------------------------------------
  113. // datamodel operator interface - for all elements that need to be sorted in the operator dependency graph
  114. //-----------------------------------------------------------------------------
  115. abstract_class IDmeOperator
  116. {
  117. public:
  118. virtual bool IsDirty() = 0; // ie needs to operate
  119. virtual void Operate() = 0;
  120. virtual void GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs ) = 0;
  121. virtual void GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs ) = 0;
  122. };
  123. //-----------------------------------------------------------------------------
  124. // Class factory methods:
  125. //-----------------------------------------------------------------------------
  126. class IDmElementFactory
  127. {
  128. public:
  129. // Creation, destruction
  130. virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id ) = 0;
  131. virtual void Destroy( DmElementHandle_t hElement ) = 0;
  132. };
  133. //-----------------------------------------------------------------------------
  134. // Various serialization methods can be installed into the data model factory
  135. //-----------------------------------------------------------------------------
  136. enum DmConflictResolution_t
  137. {
  138. CR_DELETE_NEW,
  139. CR_DELETE_OLD,
  140. CR_COPY_NEW,
  141. CR_FORCE_COPY,
  142. };
  143. // convert files to elements and back
  144. // current file encodings supported: binary, xml, xml_flat, keyvalues2, keyvalues2_flat, keyvalues (vmf/vmt/actbusy), text? (qc/obj)
  145. class IDmSerializer
  146. {
  147. public:
  148. virtual const char *GetName() const = 0;
  149. virtual const char *GetDescription() const = 0;
  150. virtual bool IsBinaryFormat() const = 0;
  151. virtual bool StoresVersionInFile() const = 0;
  152. virtual int GetCurrentVersion() const = 0;
  153. // Write into the UtlBuffer, return true if successful
  154. // if we decide to implement non-identity conversions between formats on write, then the source and dest format will need to be passed in here
  155. virtual bool Serialize( CUtlBuffer &buf, CDmElement *pRoot ) = 0;
  156. // Read from the UtlBuffer, return true if successful, and return the read-in root in ppRoot.
  157. virtual bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion,
  158. const char *pSourceFormatName, int nSourceFormatVersion,
  159. DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot ) = 0;
  160. };
  161. // convert legacy elements to non-legacy elements
  162. // legacy formats include: sfm_vN, binary_vN, keyvalues2_v1, keyvalues2_flat_v1, xml, xml_flat
  163. // where N is a version number (1..9 for sfm, 1..2 for binary)
  164. class IDmLegacyUpdater
  165. {
  166. public:
  167. virtual const char *GetName() const = 0;
  168. virtual bool IsLatestVersion() const = 0;
  169. // Updates ppRoot to first non-legacy generic dmx format, returns false if the conversion fails
  170. virtual bool Update( CDmElement **ppRoot ) = 0;
  171. };
  172. // converts old elements to new elements
  173. // current formats include: sfm session, animset presets, particle definitions, exported maya character, etc.
  174. class IDmFormatUpdater
  175. {
  176. public:
  177. virtual const char *GetName() const = 0;
  178. virtual const char *GetDescription() const = 0;
  179. virtual const char *GetExtension() const = 0;
  180. virtual int GetCurrentVersion() const = 0;
  181. virtual const char *GetDefaultEncoding() const = 0;
  182. // Converts pSourceRoot from nSourceVersion to the current version, returns false if the conversion fails
  183. virtual bool Update( CDmElement **pRoot, int nSourceVersion ) = 0;
  184. };
  185. //-----------------------------------------------------------------------------
  186. // Interface for callbacks to supply element types for specific keys inside keyvalues files
  187. //-----------------------------------------------------------------------------
  188. class IElementForKeyValueCallback
  189. {
  190. public:
  191. virtual const char *GetElementForKeyValue( const char *pszKeyName, int iNestingLevel ) = 0;
  192. };
  193. //-----------------------------------------------------------------------------
  194. // Purpose: Optional helper passed in with clipboard data which is called when it's time to clean up the clipboard data in case the application
  195. // had some dynamically allocated data attached to a KV SetPtr object...
  196. //-----------------------------------------------------------------------------
  197. abstract_class IClipboardCleanup
  198. {
  199. public:
  200. virtual void ReleaseClipboardData( CUtlVector< KeyValues * >& list ) = 0;
  201. };
  202. //-----------------------------------------------------------------------------
  203. // Purpose: Can be installed to be called back when data changes
  204. //-----------------------------------------------------------------------------
  205. enum DmNotifySource_t
  206. {
  207. // Sources
  208. NOTIFY_SOURCE_APPLICATION = 0,
  209. NOTIFY_SOURCE_UNDO,
  210. NOTIFY_SOURCE_FIRST_DME_CONTROL_SOURCE = 4, // Sources from dme_controls starts here
  211. NOTIFY_SOURCE_FIRST_APPLICATION_SOURCE = 8, // Sources from applications starts here
  212. };
  213. enum DmNotifyFlags_t
  214. {
  215. // Does this dirty the document?
  216. NOTIFY_SOURCE_BITS = 8,
  217. NOTIFY_SETDIRTYFLAG = (1<<NOTIFY_SOURCE_BITS),
  218. // Type of change (note NOTIFY_CHANGE_TOPOLOGICAL/NOTIFY_CHANGE_ATTRIBUTE_VALUE/NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE
  219. // are set by the Datamodel itself)
  220. NOTIFY_CHANGE_TOPOLOGICAL = (1<<(NOTIFY_SOURCE_BITS+4)), // Element created, destroyed, element attribute or element array attribute value changed
  221. NOTIFY_CHANGE_ATTRIBUTE_VALUE = (1<<(NOTIFY_SOURCE_BITS+5)), // Non-element attribute value changed
  222. NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE = (1<<(NOTIFY_SOURCE_BITS+6)), // Non-element array attribute added or removed
  223. NOTIFY_CHANGE_OTHER = (1<<(NOTIFY_SOURCE_BITS+7)), // Non attribute related change (a change in UI, for example)
  224. NOTIFY_CHANGE_MASK = ( NOTIFY_CHANGE_TOPOLOGICAL | NOTIFY_CHANGE_ATTRIBUTE_VALUE | NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE | NOTIFY_CHANGE_OTHER ),
  225. };
  226. abstract_class IDmNotify
  227. {
  228. public:
  229. // See DmNotifySource_t and DmNotifyFlags_t
  230. virtual void NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags ) = 0;
  231. };
  232. //-----------------------------------------------------------------------------
  233. // Purpose: Helper for debugging undo system
  234. //-----------------------------------------------------------------------------
  235. struct UndoInfo_t
  236. {
  237. bool terminator;
  238. const char *desc;
  239. const char *undo;
  240. const char *redo;
  241. int numoperations;
  242. };
  243. //-----------------------------------------------------------------------------
  244. // Interface for undo
  245. //-----------------------------------------------------------------------------
  246. abstract_class IUndoElement
  247. {
  248. public:
  249. virtual void Undo() = 0;
  250. virtual void Redo() = 0;
  251. virtual const char *UndoDesc() const = 0;
  252. virtual const char *RedoDesc() const = 0;
  253. virtual const char *GetDesc() const = 0;
  254. virtual void Release() = 0;
  255. protected:
  256. virtual bool IsEndOfStream() const = 0;
  257. virtual void SetEndOfStream( bool end ) = 0;
  258. virtual ~IUndoElement() { }
  259. friend class CUndoManager;
  260. };
  261. //-----------------------------------------------------------------------------
  262. // traversal depth for copy, search, and other element/attribute traversals
  263. //-----------------------------------------------------------------------------
  264. enum TraversalDepth_t
  265. {
  266. TD_ALL, // traverse all attributes
  267. TD_DEEP, // traverse attributes with FATTRIB_NEVERCOPY clear
  268. TD_SHALLOW, // traverse attributes with FATTRIB_MUSTCOPY set
  269. TD_NONE, // don't traverse any attributes
  270. };
  271. //-----------------------------------------------------------------------------
  272. // Main interface for creation of all IDmeElements:
  273. //-----------------------------------------------------------------------------
  274. class IDataModel : public IAppSystem
  275. {
  276. public:
  277. // Installs factories used to instance elements
  278. virtual void AddElementFactory( const char *pElementTypeName, IDmElementFactory *pFactory ) = 0;
  279. // This factory will be used to instance all elements whose type name isn't found.
  280. virtual void SetDefaultElementFactory( IDmElementFactory *pFactory ) = 0;
  281. virtual int GetFirstFactory() const = 0;
  282. virtual int GetNextFactory( int index ) const = 0;
  283. virtual bool IsValidFactory( int index ) const = 0;
  284. virtual const char *GetFactoryName( int index ) const = 0;
  285. // create/destroy element methods - proxies to installed element factories
  286. virtual DmElementHandle_t CreateElement( UtlSymId_t typeSymbol, const char *pElementName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL ) = 0;
  287. virtual DmElementHandle_t CreateElement( const char *pTypeName, const char *pElementName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL ) = 0;
  288. virtual void DestroyElement( DmElementHandle_t hElement ) = 0;
  289. // element handle related methods
  290. virtual CDmElement* GetElement ( DmElementHandle_t hElement ) const = 0;
  291. virtual UtlSymId_t GetElementType ( DmElementHandle_t hElement ) const = 0;
  292. virtual const char* GetElementName ( DmElementHandle_t hElement ) const = 0;
  293. virtual const DmObjectId_t& GetElementId ( DmElementHandle_t hElement ) const = 0;
  294. virtual const char* GetAttributeNameForType( DmAttributeType_t attType ) const = 0;
  295. virtual DmAttributeType_t GetAttributeTypeForName( const char *name ) const = 0;
  296. // Adds various serializers and updaters
  297. virtual void AddSerializer( IDmSerializer *pSerializer ) = 0;
  298. virtual void AddLegacyUpdater( IDmLegacyUpdater *pUpdater ) = 0;
  299. virtual void AddFormatUpdater( IDmFormatUpdater *pUpdater ) = 0;
  300. // file format methods
  301. virtual const char* GetFormatExtension( const char *pFormatName ) = 0;
  302. virtual const char* GetFormatDescription( const char *pFormatName ) = 0;
  303. virtual int GetFormatCount() const = 0;
  304. virtual const char * GetFormatName( int i ) const = 0;
  305. virtual const char * GetDefaultEncoding( const char *pFormatName ) = 0;
  306. // file encoding methods
  307. virtual int GetEncodingCount() const = 0;
  308. virtual const char * GetEncodingName( int i ) const = 0;
  309. virtual bool IsEncodingBinary( const char *pEncodingName ) const = 0;
  310. virtual bool DoesEncodingStoreVersionInFile( const char *pEncodingName ) const = 0;
  311. // For serialization, set the delimiter rules
  312. // These methods are meant to be used by importer/exporters
  313. virtual void SetSerializationDelimiter( CUtlCharConversion *pConv ) = 0;
  314. virtual void SetSerializationArrayDelimiter( const char *pDelimiter ) = 0;
  315. // used to skip auto-creation of child elements during unserialization
  316. virtual bool IsUnserializing() = 0;
  317. // Serialization of a element tree into a utlbuffer
  318. virtual bool Serialize( CUtlBuffer &outBuf, const char *pEncodingName, const char *pFormatName, DmElementHandle_t hRoot ) = 0;
  319. // Unserializes, returns the root of the unserialized tree in hRoot
  320. // The file name passed in is simply for error messages and fileid creation
  321. virtual bool Unserialize( CUtlBuffer &inBuf, const char *pEncodingName, const char *pSourceFormatName, const char *pFormatHint,
  322. const char *pFileName, DmConflictResolution_t idConflictResolution, DmElementHandle_t &hRoot ) = 0;
  323. // converts from elements from old file formats to elements for the current file format
  324. virtual bool UpdateUnserializedElements( const char *pSourceFormatName, int nSourceFormatVersion,
  325. DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot ) = 0;
  326. // force creation of untyped elements, ignoring type
  327. virtual void OnlyCreateUntypedElements( bool bEnable ) = 0;
  328. // Finds a serializer by name
  329. virtual IDmSerializer* FindSerializer( const char *pEncodingName ) const = 0;
  330. virtual IDmLegacyUpdater* FindLegacyUpdater( const char *pLegacyFormatName ) const = 0;
  331. virtual IDmFormatUpdater* FindFormatUpdater( const char *pFormatName ) const = 0;
  332. // saves element tree to a file
  333. virtual bool SaveToFile( const char *pFileName, const char *pPathID, const char *pEncodingName, const char *pFormatName, CDmElement *pRoot ) = 0;
  334. // restores file into an element tree
  335. // NOTE: Format name is only used here for those formats which don't store
  336. // the format name in the file. Use NULL for those formats which store the
  337. // format name in the file.
  338. virtual DmFileId_t RestoreFromFile( const char *pFileName, const char *pPathID, const char *pFormatHint, CDmElement **ppRoot, DmConflictResolution_t idConflictResolution = CR_DELETE_NEW, DmxHeader_t *pHeaderOut = NULL ) = 0;
  339. // Sets the name of the DME element to create in keyvalues serialization
  340. virtual void SetKeyValuesElementCallback( IElementForKeyValueCallback *pCallbackInterface ) = 0;
  341. virtual const char *GetKeyValuesElementName( const char *pszKeyName, int iNestingLevel ) = 0;
  342. // Global symbol table for the datamodel system
  343. virtual UtlSymId_t GetSymbol( const char *pString ) = 0;
  344. virtual const char * GetString( UtlSymId_t sym ) const = 0;
  345. // Returns the total number of elements allocated at the moment
  346. virtual int GetMaxNumberOfElements() = 0;
  347. virtual int GetElementsAllocatedSoFar() = 0;
  348. virtual int GetAllocatedAttributeCount() = 0;
  349. virtual int GetAllocatedElementCount() = 0;
  350. virtual DmElementHandle_t FirstAllocatedElement() = 0;
  351. virtual DmElementHandle_t NextAllocatedElement( DmElementHandle_t it ) = 0;
  352. // estimate memory usage
  353. virtual int EstimateMemoryUsage( DmElementHandle_t hElement, TraversalDepth_t depth ) = 0;
  354. // Undo/Redo support
  355. virtual void SetUndoEnabled( bool enable ) = 0;
  356. virtual bool IsUndoEnabled() const = 0;
  357. virtual bool UndoEnabledForElement( const CDmElement *pElement ) const = 0;
  358. virtual bool IsDirty() const = 0;
  359. virtual bool CanUndo() const = 0;
  360. virtual bool CanRedo() const = 0;
  361. // If chaining ID is != 0 and the next StartUndo uses the same ID, then the operations will be chained together into a single undo operation
  362. virtual void StartUndo( char const *undodesc, char const *redodesc, int nChainingID = 0 ) = 0;
  363. virtual void FinishUndo() = 0;
  364. virtual void AbortUndoableOperation() = 0; // called instead of FinishUndo, essentially performs and Undo() and WipeRedo() if any undo items have been added to the stack
  365. virtual void ClearRedo() = 0;
  366. virtual const char *GetUndoDesc() = 0;
  367. virtual const char *GetRedoDesc() = 0;
  368. // From the UI, perform the Undo operation
  369. virtual void Undo() = 0;
  370. virtual void Redo() = 0;
  371. virtual void TraceUndo( bool state ) = 0; // if true, undo records spew as they are added
  372. // Wipes out all Undo data
  373. virtual void ClearUndo() = 0;
  374. virtual void GetUndoInfo( CUtlVector< UndoInfo_t >& list ) = 0;
  375. virtual void AddUndoElement( IUndoElement *pElement ) = 0;
  376. virtual UtlSymId_t GetUndoDescInternal( const char *context ) = 0;
  377. virtual UtlSymId_t GetRedoDescInternal( const char *context ) = 0;
  378. virtual void EmptyClipboard() = 0;
  379. virtual void SetClipboardData( CUtlVector< KeyValues * >& data, IClipboardCleanup *pfnOptionalCleanuFunction = 0 ) = 0;
  380. virtual void AddToClipboardData( KeyValues *add ) = 0;
  381. virtual void GetClipboardData( CUtlVector< KeyValues * >& data ) = 0;
  382. virtual bool HasClipboardData() const = 0;
  383. // Handles to attributes
  384. virtual CDmAttribute * GetAttribute( DmAttributeHandle_t h ) = 0;
  385. virtual bool IsAttributeHandleValid( DmAttributeHandle_t h ) const = 0;
  386. // file id reference methods
  387. virtual int NumFileIds() = 0;
  388. virtual DmFileId_t GetFileId( int i ) = 0;
  389. virtual DmFileId_t FindOrCreateFileId( const char *pFilename ) = 0;
  390. virtual void RemoveFileId( DmFileId_t fileid ) = 0;
  391. virtual DmFileId_t GetFileId( const char *pFilename ) = 0;
  392. virtual const char * GetFileName( DmFileId_t fileid ) = 0;
  393. virtual void SetFileName( DmFileId_t fileid, const char *pFileName ) = 0;
  394. virtual const char * GetFileFormat( DmFileId_t fileid ) = 0;
  395. virtual void SetFileFormat( DmFileId_t fileid, const char *pFormat ) = 0;
  396. virtual DmElementHandle_t GetFileRoot( DmFileId_t fileid ) = 0;
  397. virtual void SetFileRoot( DmFileId_t fileid, DmElementHandle_t hRoot ) = 0;
  398. virtual bool IsFileLoaded( DmFileId_t fileid ) = 0;
  399. virtual void MarkFileLoaded( DmFileId_t fileid ) = 0;
  400. virtual void UnloadFile( DmFileId_t fileid ) = 0;
  401. virtual int NumElementsInFile( DmFileId_t fileid ) = 0;
  402. virtual void DontAutoDelete( DmElementHandle_t hElement ) = 0;
  403. // handle validity methods - these shouldn't really be here, but the undo system needs them...
  404. virtual void MarkHandleInvalid( DmElementHandle_t hElement ) = 0;
  405. virtual void MarkHandleValid( DmElementHandle_t hElement ) = 0;
  406. virtual DmElementHandle_t FindElement( const DmObjectId_t &id ) = 0;
  407. virtual DmAttributeReferenceIterator_t FirstAttributeReferencingElement( DmElementHandle_t hElement ) = 0;
  408. virtual DmAttributeReferenceIterator_t NextAttributeReferencingElement( DmAttributeReferenceIterator_t hAttrIter ) = 0;
  409. virtual CDmAttribute * GetAttribute( DmAttributeReferenceIterator_t hAttrIter ) = 0;
  410. // Install, remove notify callbacks associated w/ undo contexts
  411. virtual bool InstallNotificationCallback( IDmNotify *pNotify ) = 0;
  412. virtual void RemoveNotificationCallback( IDmNotify *pNotify ) = 0;
  413. virtual bool IsSuppressingNotify( ) const = 0;
  414. virtual void SetSuppressingNotify( bool bSuppress ) = 0;
  415. virtual void PushNotificationScope( const char *pReason, int nNotifySource, int nNotifyFlags ) = 0;
  416. virtual void PopNotificationScope( bool bAbort = false ) = 0;
  417. virtual const char *GetUndoString( UtlSymId_t sym ) = 0;
  418. virtual bool HasElementFactory( const char *pElementType ) const = 0;
  419. // Call before you make any undo records
  420. virtual void SetUndoDepth( int nSize ) = 0;
  421. // Displats memory stats to the console
  422. virtual void DisplayMemoryStats() = 0;
  423. };
  424. //-----------------------------------------------------------------------------
  425. // Used only by applications to hook in the data model
  426. //-----------------------------------------------------------------------------
  427. #define VDATAMODEL_INTERFACE_VERSION "VDataModelVersion001"
  428. //-----------------------------------------------------------------------------
  429. // Main interface accessor
  430. //-----------------------------------------------------------------------------
  431. extern IDataModel *g_pDataModel;
  432. //-----------------------------------------------------------------------------
  433. // Allows clients to implement customized undo elements
  434. //-----------------------------------------------------------------------------
  435. class CUndoElement : public IUndoElement
  436. {
  437. public:
  438. CUndoElement( const char *pDesc )
  439. {
  440. m_UndoDesc = g_pDataModel->GetUndoDescInternal( pDesc );
  441. m_RedoDesc = g_pDataModel->GetRedoDescInternal( pDesc );
  442. m_pDesc = pDesc;
  443. m_bEndOfStream = false;
  444. }
  445. virtual void Release()
  446. {
  447. delete this;
  448. }
  449. virtual const char *UndoDesc() const
  450. {
  451. return g_pDataModel->GetUndoString( m_UndoDesc );
  452. }
  453. virtual const char *RedoDesc() const
  454. {
  455. return g_pDataModel->GetUndoString( m_RedoDesc );
  456. }
  457. virtual const char *GetDesc() const
  458. {
  459. return m_pDesc;
  460. }
  461. protected:
  462. virtual bool IsEndOfStream() const
  463. {
  464. return m_bEndOfStream;
  465. }
  466. virtual void SetEndOfStream( bool end )
  467. {
  468. m_bEndOfStream = end;
  469. }
  470. const char *m_pDesc;
  471. CUtlSymbol m_UndoDesc;
  472. CUtlSymbol m_RedoDesc;
  473. bool m_bEndOfStream;
  474. private:
  475. friend class CUndoManager;
  476. };
  477. //-----------------------------------------------------------------------------
  478. // Purpose: Simple helper class
  479. //-----------------------------------------------------------------------------
  480. class CUndoScopeGuard
  481. {
  482. public:
  483. explicit CUndoScopeGuard( const char *udesc, const char *rdesc = NULL )
  484. {
  485. m_bReleased = false;
  486. m_bNotify = false;
  487. m_pNotify = NULL;
  488. g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc );
  489. }
  490. explicit CUndoScopeGuard( int nChainingID, char const *udesc )
  491. {
  492. m_bReleased = false;
  493. m_bNotify = false;
  494. m_pNotify = NULL;
  495. g_pDataModel->StartUndo( udesc, udesc, nChainingID );
  496. }
  497. explicit CUndoScopeGuard( int nNotifySource, int nNotifyFlags, const char *udesc, const char *rdesc = NULL, int nChainingID = 0 )
  498. {
  499. m_bReleased = false;
  500. m_bNotify = true;
  501. m_pNotify = NULL;
  502. g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc, nChainingID );
  503. g_pDataModel->PushNotificationScope( udesc, nNotifySource, nNotifyFlags );
  504. }
  505. explicit CUndoScopeGuard( int nNotifySource, int nNotifyFlags, IDmNotify *pNotify, const char *udesc, const char *rdesc = NULL, int nChainingID = 0 )
  506. {
  507. m_bReleased = false;
  508. m_bNotify = true;
  509. m_pNotify = NULL;
  510. g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc, nChainingID );
  511. if ( pNotify )
  512. {
  513. if ( g_pDataModel->InstallNotificationCallback( pNotify ) )
  514. {
  515. m_pNotify = pNotify;
  516. }
  517. }
  518. g_pDataModel->PushNotificationScope( udesc, nNotifySource, nNotifyFlags );
  519. }
  520. ~CUndoScopeGuard()
  521. {
  522. Release();
  523. }
  524. void Release()
  525. {
  526. if ( !m_bReleased )
  527. {
  528. g_pDataModel->FinishUndo();
  529. if ( m_bNotify )
  530. {
  531. g_pDataModel->PopNotificationScope( );
  532. m_bNotify = false;
  533. }
  534. if ( m_pNotify )
  535. {
  536. g_pDataModel->RemoveNotificationCallback( m_pNotify );
  537. m_pNotify = NULL;
  538. }
  539. m_bReleased = true;
  540. }
  541. }
  542. void Abort()
  543. {
  544. if ( !m_bReleased )
  545. {
  546. g_pDataModel->AbortUndoableOperation();
  547. if ( m_bNotify )
  548. {
  549. g_pDataModel->PopNotificationScope( true );
  550. m_bNotify = false;
  551. }
  552. if ( m_pNotify )
  553. {
  554. g_pDataModel->RemoveNotificationCallback( m_pNotify );
  555. m_pNotify = NULL;
  556. }
  557. m_bReleased = true;
  558. }
  559. }
  560. private:
  561. IDmNotify *m_pNotify;
  562. bool m_bReleased;
  563. bool m_bNotify;
  564. };
  565. //-----------------------------------------------------------------------------
  566. // Purpose: Simple helper class to disable Undo/Redo operations when in scope
  567. //-----------------------------------------------------------------------------
  568. class CChangeUndoScopeGuard
  569. {
  570. public:
  571. CChangeUndoScopeGuard( bool bNewState )
  572. {
  573. m_bReleased = false;
  574. m_bNotify = false;
  575. m_pNotify = NULL;
  576. m_bOldValue = g_pDataModel->IsUndoEnabled();
  577. g_pDataModel->SetUndoEnabled( bNewState );
  578. };
  579. CChangeUndoScopeGuard( bool bNewState, const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL )
  580. {
  581. m_bReleased = false;
  582. m_bOldValue = g_pDataModel->IsUndoEnabled();
  583. g_pDataModel->SetUndoEnabled( bNewState );
  584. m_bNotify = true;
  585. m_pNotify = NULL;
  586. if ( pNotify )
  587. {
  588. if ( g_pDataModel->InstallNotificationCallback( pNotify ) )
  589. {
  590. m_pNotify = pNotify;
  591. }
  592. }
  593. g_pDataModel->PushNotificationScope( pDesc, nNotifySource, nNotifyFlags );
  594. };
  595. ~CChangeUndoScopeGuard()
  596. {
  597. Release();
  598. }
  599. void Release()
  600. {
  601. // Releases the guard...
  602. if ( !m_bReleased )
  603. {
  604. g_pDataModel->SetUndoEnabled( m_bOldValue );
  605. m_bReleased = true;
  606. if ( m_bNotify )
  607. {
  608. g_pDataModel->PopNotificationScope( );
  609. m_bNotify = false;
  610. }
  611. if ( m_pNotify )
  612. {
  613. g_pDataModel->RemoveNotificationCallback( m_pNotify );
  614. m_pNotify = NULL;
  615. }
  616. }
  617. }
  618. private:
  619. IDmNotify *m_pNotify;
  620. bool m_bOldValue;
  621. bool m_bReleased;
  622. bool m_bNotify;
  623. };
  624. class CDisableUndoScopeGuard : public CChangeUndoScopeGuard
  625. {
  626. typedef CChangeUndoScopeGuard BaseClass;
  627. public:
  628. CDisableUndoScopeGuard() : BaseClass( false ) { }
  629. CDisableUndoScopeGuard( const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) :
  630. BaseClass( false, pDesc, nNotifySource, nNotifyFlags, pNotify ) {}
  631. };
  632. class CEnableUndoScopeGuard : public CChangeUndoScopeGuard
  633. {
  634. typedef CChangeUndoScopeGuard BaseClass;
  635. public:
  636. CEnableUndoScopeGuard( ) : BaseClass( true ) { }
  637. CEnableUndoScopeGuard( const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) :
  638. BaseClass( true, pDesc, nNotifySource, nNotifyFlags, pNotify ) {}
  639. };
  640. #define DEFINE_SOURCE_UNDO_SCOPE_GUARD( _classnameprefix, _source ) \
  641. class C ## _classnameprefix ## UndoScopeGuard : public CUndoScopeGuard \
  642. { \
  643. typedef CUndoScopeGuard BaseClass; \
  644. \
  645. public: \
  646. C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, const char *pUndoDesc, const char *pRedoDesc = NULL, int nChainingID = 0 ) : \
  647. BaseClass( _source, nNotifyFlags, pUndoDesc, pRedoDesc, nChainingID ) \
  648. { \
  649. } \
  650. C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, IDmNotify *pNotify, const char *pUndoDesc, const char *pRedoDesc = NULL, int nChainingID = 0 ) : \
  651. BaseClass( _source, nNotifyFlags, pNotify, pUndoDesc, pRedoDesc, nChainingID ) \
  652. { \
  653. } \
  654. C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, const char *pUndoDesc, int nChainingID ) : \
  655. BaseClass( _source, nNotifyFlags, pUndoDesc, pUndoDesc, nChainingID ) \
  656. { \
  657. } \
  658. }; \
  659. class C ## _classnameprefix ## DisableUndoScopeGuard : public CDisableUndoScopeGuard \
  660. { \
  661. typedef CDisableUndoScopeGuard BaseClass; \
  662. \
  663. public: \
  664. C ## _classnameprefix ## DisableUndoScopeGuard( const char *pDesc, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \
  665. BaseClass( pDesc, _source, nNotifyFlags, pNotify ) \
  666. { \
  667. } \
  668. }; \
  669. class C ## _classnameprefix ## EnableUndoScopeGuard : public CEnableUndoScopeGuard \
  670. { \
  671. typedef CEnableUndoScopeGuard BaseClass; \
  672. \
  673. public: \
  674. C ## _classnameprefix ## EnableUndoScopeGuard( const char *pDesc, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \
  675. BaseClass( pDesc, _source, nNotifyFlags, pNotify ) \
  676. { \
  677. } \
  678. }
  679. //-----------------------------------------------------------------------------
  680. // Purpose: Simple helper class to disable NotifyDataChanged from current scope
  681. //-----------------------------------------------------------------------------
  682. class CNotifyScopeGuard
  683. {
  684. public:
  685. CNotifyScopeGuard( const char *pReason, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL )
  686. {
  687. m_bReleased = false;
  688. m_pNotify = NULL;
  689. g_pDataModel->PushNotificationScope( pReason, nNotifySource, nNotifyFlags );
  690. if ( pNotify )
  691. {
  692. if ( g_pDataModel->InstallNotificationCallback( pNotify ) )
  693. {
  694. m_pNotify = pNotify;
  695. }
  696. }
  697. };
  698. ~CNotifyScopeGuard()
  699. {
  700. Release();
  701. }
  702. void Release()
  703. {
  704. // Releases the guard...
  705. if ( !m_bReleased )
  706. {
  707. g_pDataModel->PopNotificationScope( );
  708. if ( m_pNotify )
  709. {
  710. g_pDataModel->RemoveNotificationCallback( m_pNotify );
  711. m_pNotify = NULL;
  712. }
  713. m_bReleased = true;
  714. }
  715. }
  716. private:
  717. CNotifyScopeGuard( const CNotifyScopeGuard& g );
  718. private:
  719. IDmNotify *m_pNotify;
  720. bool m_bReleased;
  721. };
  722. #define DEFINE_SOURCE_NOTIFY_SCOPE_GUARD( _classnameprefix, _source ) \
  723. class C ## _classnameprefix ## NotifyScopeGuard : public CNotifyScopeGuard \
  724. { \
  725. typedef CNotifyScopeGuard BaseClass; \
  726. \
  727. public: \
  728. C ## _classnameprefix ## NotifyScopeGuard( const char *pReason, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \
  729. BaseClass( pReason, _source, nNotifyFlags, pNotify )\
  730. { \
  731. } \
  732. }
  733. //-----------------------------------------------------------------------------
  734. // Purpose: Simple helper class to disable notifications when in scope
  735. //-----------------------------------------------------------------------------
  736. class CChangeNotifyScopeGuard
  737. {
  738. public:
  739. CChangeNotifyScopeGuard( bool bNewState )
  740. {
  741. m_bReleased = false;
  742. m_bOldValue = g_pDataModel->IsSuppressingNotify();
  743. g_pDataModel->SetSuppressingNotify( bNewState );
  744. };
  745. ~CChangeNotifyScopeGuard()
  746. {
  747. Release();
  748. }
  749. void Release()
  750. {
  751. // Releases the guard...
  752. if ( !m_bReleased )
  753. {
  754. g_pDataModel->SetSuppressingNotify( m_bOldValue );
  755. m_bReleased = true;
  756. }
  757. }
  758. private:
  759. bool m_bOldValue;
  760. bool m_bReleased;
  761. };
  762. class CDisableNotifyScopeGuard : public CChangeNotifyScopeGuard
  763. {
  764. typedef CChangeNotifyScopeGuard BaseClass;
  765. public:
  766. CDisableNotifyScopeGuard() : BaseClass( true ) { }
  767. private:
  768. CDisableNotifyScopeGuard( const CDisableNotifyScopeGuard& g );
  769. };
  770. class CEnableNotifyScopeGuard : public CChangeNotifyScopeGuard
  771. {
  772. typedef CChangeNotifyScopeGuard BaseClass;
  773. public:
  774. CEnableNotifyScopeGuard( ) : BaseClass( false ) { }
  775. private:
  776. CEnableNotifyScopeGuard( const CEnableNotifyScopeGuard& g );
  777. };
  778. //-----------------------------------------------------------------------------
  779. // Standard undo/notify guards for the application
  780. //-----------------------------------------------------------------------------
  781. DEFINE_SOURCE_UNDO_SCOPE_GUARD( App, NOTIFY_SOURCE_APPLICATION );
  782. DEFINE_SOURCE_NOTIFY_SCOPE_GUARD( App, NOTIFY_SOURCE_APPLICATION );
  783. #endif // IDATAMODEL_H