Counter Strike : Global Offensive Source Code
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.

942 lines
33 KiB

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