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
938 lines
32 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#ifndef IDATAMODEL_H |
|
#define IDATAMODEL_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "tier1/interface.h" |
|
#include "tier1/utlvector.h" |
|
#include "tier1/utlsymbol.h" |
|
#include "appframework/IAppSystem.h" |
|
#include "datamodel/dmattributetypes.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Forward declarations: |
|
//----------------------------------------------------------------------------- |
|
class CDmAttribute; |
|
class CDmElement; |
|
class IDmeOperator; |
|
class IElementForKeyValueCallback; |
|
|
|
struct DmValueBase_t; |
|
class CUtlBuffer; |
|
class KeyValues; |
|
class CUtlSymbolTable; |
|
class CUtlCharConversion; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// data file format info |
|
//----------------------------------------------------------------------------- |
|
#define DMX_LEGACY_VERSION_STARTING_TOKEN "<!-- DMXVersion" |
|
#define DMX_LEGACY_VERSION_ENDING_TOKEN "-->" |
|
|
|
#define DMX_VERSION_STARTING_TOKEN "<!-- dmx" |
|
#define DMX_VERSION_ENDING_TOKEN "-->" |
|
|
|
#define GENERIC_DMX_FORMAT "dmx" |
|
|
|
|
|
enum |
|
{ |
|
DMX_MAX_FORMAT_NAME_MAX_LENGTH = 64, |
|
DMX_MAX_HEADER_LENGTH = 40 + 2 * DMX_MAX_FORMAT_NAME_MAX_LENGTH, |
|
}; |
|
|
|
struct DmxHeader_t |
|
{ |
|
char encodingName[ DMX_MAX_FORMAT_NAME_MAX_LENGTH ]; |
|
int nEncodingVersion; |
|
char formatName[ DMX_MAX_FORMAT_NAME_MAX_LENGTH ]; |
|
int nFormatVersion; |
|
|
|
DmxHeader_t() : nEncodingVersion( -1 ), nFormatVersion( -1 ) |
|
{ |
|
encodingName[ 0 ] = formatName[ 0 ] = '\0'; |
|
} |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// element framework phases |
|
//----------------------------------------------------------------------------- |
|
enum DmPhase_t |
|
{ |
|
PH_EDIT, |
|
PH_EDIT_APPLY, |
|
PH_EDIT_RESOLVE, |
|
PH_DEPENDENCY, |
|
PH_OPERATE, |
|
PH_OPERATE_RESOLVE, |
|
PH_OUTPUT, |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// file id - also used to refer to elements that don't have file associations |
|
//----------------------------------------------------------------------------- |
|
enum DmFileId_t |
|
{ |
|
DMFILEID_INVALID = 0xffffffff |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Handle to an CDmAttribute |
|
//----------------------------------------------------------------------------- |
|
enum DmAttributeHandle_t |
|
{ |
|
DMATTRIBUTE_HANDLE_INVALID = 0xffffffff |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Handle to an DmAttributeList_t |
|
//----------------------------------------------------------------------------- |
|
enum DmAttributeReferenceIterator_t |
|
{ |
|
DMATTRIBUTE_REFERENCE_ITERATOR_INVALID = 0 |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// element framework interface |
|
//----------------------------------------------------------------------------- |
|
abstract_class IDmElementFramework : public IAppSystem |
|
{ |
|
public: |
|
// Methods of IAppSystem |
|
virtual bool Connect( CreateInterfaceFn factory ) = 0; |
|
virtual void Disconnect() = 0; |
|
virtual void *QueryInterface( const char *pInterfaceName ) = 0; |
|
virtual InitReturnVal_t Init() = 0; |
|
virtual void Shutdown() = 0; |
|
|
|
virtual DmPhase_t GetPhase() = 0; |
|
|
|
virtual void SetOperators( const CUtlVector< IDmeOperator* > &operators ) = 0; |
|
|
|
virtual void BeginEdit() = 0; // ends in edit phase, forces apply/resolve if from edit phase |
|
virtual void Operate( bool bResolve ) = 0; // ends in output phase |
|
virtual void Resolve() = 0; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Used only by aplpications to hook in the element framework |
|
//----------------------------------------------------------------------------- |
|
#define VDMELEMENTFRAMEWORK_VERSION "VDmElementFrameworkVersion001" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Main interface |
|
//----------------------------------------------------------------------------- |
|
extern IDmElementFramework *g_pDmElementFramework; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// datamodel operator interface - for all elements that need to be sorted in the operator dependency graph |
|
//----------------------------------------------------------------------------- |
|
abstract_class IDmeOperator |
|
{ |
|
public: |
|
virtual bool IsDirty() = 0; // ie needs to operate |
|
virtual void Operate() = 0; |
|
|
|
virtual void GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs ) = 0; |
|
virtual void GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs ) = 0; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Class factory methods: |
|
//----------------------------------------------------------------------------- |
|
class IDmElementFactory |
|
{ |
|
public: |
|
// Creation, destruction |
|
virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id ) = 0; |
|
virtual void Destroy( DmElementHandle_t hElement ) = 0; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Various serialization methods can be installed into the data model factory |
|
//----------------------------------------------------------------------------- |
|
enum DmConflictResolution_t |
|
{ |
|
CR_DELETE_NEW, |
|
CR_DELETE_OLD, |
|
CR_COPY_NEW, |
|
CR_FORCE_COPY, |
|
}; |
|
|
|
// convert files to elements and back |
|
// current file encodings supported: binary, xml, xml_flat, keyvalues2, keyvalues2_flat, keyvalues (vmf/vmt/actbusy), text? (qc/obj) |
|
class IDmSerializer |
|
{ |
|
public: |
|
virtual const char *GetName() const = 0; |
|
virtual const char *GetDescription() const = 0; |
|
virtual bool IsBinaryFormat() const = 0; |
|
virtual bool StoresVersionInFile() const = 0; |
|
virtual int GetCurrentVersion() const = 0; |
|
|
|
// Write into the UtlBuffer, return true if successful |
|
// 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 |
|
virtual bool Serialize( CUtlBuffer &buf, CDmElement *pRoot ) = 0; |
|
|
|
// Read from the UtlBuffer, return true if successful, and return the read-in root in ppRoot. |
|
virtual bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, |
|
const char *pSourceFormatName, int nSourceFormatVersion, |
|
DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot ) = 0; |
|
}; |
|
|
|
// convert legacy elements to non-legacy elements |
|
// legacy formats include: sfm_vN, binary_vN, keyvalues2_v1, keyvalues2_flat_v1, xml, xml_flat |
|
// where N is a version number (1..9 for sfm, 1..2 for binary) |
|
class IDmLegacyUpdater |
|
{ |
|
public: |
|
virtual const char *GetName() const = 0; |
|
virtual bool IsLatestVersion() const = 0; |
|
|
|
// Updates ppRoot to first non-legacy generic dmx format, returns false if the conversion fails |
|
virtual bool Update( CDmElement **ppRoot ) = 0; |
|
}; |
|
|
|
// converts old elements to new elements |
|
// current formats include: sfm session, animset presets, particle definitions, exported maya character, etc. |
|
class IDmFormatUpdater |
|
{ |
|
public: |
|
virtual const char *GetName() const = 0; |
|
virtual const char *GetDescription() const = 0; |
|
virtual const char *GetExtension() const = 0; |
|
virtual int GetCurrentVersion() const = 0; |
|
virtual const char *GetDefaultEncoding() const = 0; |
|
|
|
// Converts pSourceRoot from nSourceVersion to the current version, returns false if the conversion fails |
|
virtual bool Update( CDmElement **pRoot, int nSourceVersion ) = 0; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Interface for callbacks to supply element types for specific keys inside keyvalues files |
|
//----------------------------------------------------------------------------- |
|
class IElementForKeyValueCallback |
|
{ |
|
public: |
|
virtual const char *GetElementForKeyValue( const char *pszKeyName, int iNestingLevel ) = 0; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// 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 |
|
// had some dynamically allocated data attached to a KV SetPtr object... |
|
//----------------------------------------------------------------------------- |
|
abstract_class IClipboardCleanup |
|
{ |
|
public: |
|
virtual void ReleaseClipboardData( CUtlVector< KeyValues * >& list ) = 0; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Can be installed to be called back when data changes |
|
//----------------------------------------------------------------------------- |
|
enum DmNotifySource_t |
|
{ |
|
// Sources |
|
NOTIFY_SOURCE_APPLICATION = 0, |
|
NOTIFY_SOURCE_UNDO, |
|
NOTIFY_SOURCE_FIRST_DME_CONTROL_SOURCE = 4, // Sources from dme_controls starts here |
|
NOTIFY_SOURCE_FIRST_APPLICATION_SOURCE = 8, // Sources from applications starts here |
|
}; |
|
|
|
enum DmNotifyFlags_t |
|
{ |
|
// Does this dirty the document? |
|
NOTIFY_SOURCE_BITS = 8, |
|
NOTIFY_SETDIRTYFLAG = (1<<NOTIFY_SOURCE_BITS), |
|
|
|
// Type of change (note NOTIFY_CHANGE_TOPOLOGICAL/NOTIFY_CHANGE_ATTRIBUTE_VALUE/NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE |
|
// are set by the Datamodel itself) |
|
NOTIFY_CHANGE_TOPOLOGICAL = (1<<(NOTIFY_SOURCE_BITS+4)), // Element created, destroyed, element attribute or element array attribute value changed |
|
NOTIFY_CHANGE_ATTRIBUTE_VALUE = (1<<(NOTIFY_SOURCE_BITS+5)), // Non-element attribute value changed |
|
NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE = (1<<(NOTIFY_SOURCE_BITS+6)), // Non-element array attribute added or removed |
|
NOTIFY_CHANGE_OTHER = (1<<(NOTIFY_SOURCE_BITS+7)), // Non attribute related change (a change in UI, for example) |
|
|
|
NOTIFY_CHANGE_MASK = ( NOTIFY_CHANGE_TOPOLOGICAL | NOTIFY_CHANGE_ATTRIBUTE_VALUE | NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE | NOTIFY_CHANGE_OTHER ), |
|
|
|
}; |
|
|
|
abstract_class IDmNotify |
|
{ |
|
public: |
|
// See DmNotifySource_t and DmNotifyFlags_t |
|
virtual void NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags ) = 0; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Helper for debugging undo system |
|
//----------------------------------------------------------------------------- |
|
struct UndoInfo_t |
|
{ |
|
bool terminator; |
|
const char *desc; |
|
const char *undo; |
|
const char *redo; |
|
int numoperations; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Interface for undo |
|
//----------------------------------------------------------------------------- |
|
abstract_class IUndoElement |
|
{ |
|
public: |
|
virtual void Undo() = 0; |
|
virtual void Redo() = 0; |
|
|
|
virtual const char *UndoDesc() const = 0; |
|
virtual const char *RedoDesc() const = 0; |
|
virtual const char *GetDesc() const = 0; |
|
virtual void Release() = 0; |
|
|
|
protected: |
|
virtual bool IsEndOfStream() const = 0; |
|
virtual void SetEndOfStream( bool end ) = 0; |
|
virtual ~IUndoElement() { } |
|
|
|
friend class CUndoManager; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// traversal depth for copy, search, and other element/attribute traversals |
|
//----------------------------------------------------------------------------- |
|
enum TraversalDepth_t |
|
{ |
|
TD_ALL, // traverse all attributes |
|
TD_DEEP, // traverse attributes with FATTRIB_NEVERCOPY clear |
|
TD_SHALLOW, // traverse attributes with FATTRIB_MUSTCOPY set |
|
TD_NONE, // don't traverse any attributes |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Main interface for creation of all IDmeElements: |
|
//----------------------------------------------------------------------------- |
|
class IDataModel : public IAppSystem |
|
{ |
|
public: |
|
// Installs factories used to instance elements |
|
virtual void AddElementFactory( const char *pElementTypeName, IDmElementFactory *pFactory ) = 0; |
|
|
|
// This factory will be used to instance all elements whose type name isn't found. |
|
virtual void SetDefaultElementFactory( IDmElementFactory *pFactory ) = 0; |
|
|
|
virtual int GetFirstFactory() const = 0; |
|
virtual int GetNextFactory( int index ) const = 0; |
|
virtual bool IsValidFactory( int index ) const = 0; |
|
virtual const char *GetFactoryName( int index ) const = 0; |
|
|
|
// create/destroy element methods - proxies to installed element factories |
|
virtual DmElementHandle_t CreateElement( UtlSymId_t typeSymbol, const char *pElementName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL ) = 0; |
|
virtual DmElementHandle_t CreateElement( const char *pTypeName, const char *pElementName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL ) = 0; |
|
virtual void DestroyElement( DmElementHandle_t hElement ) = 0; |
|
|
|
// element handle related methods |
|
virtual CDmElement* GetElement ( DmElementHandle_t hElement ) const = 0; |
|
virtual UtlSymId_t GetElementType ( DmElementHandle_t hElement ) const = 0; |
|
virtual const char* GetElementName ( DmElementHandle_t hElement ) const = 0; |
|
virtual const DmObjectId_t& GetElementId ( DmElementHandle_t hElement ) const = 0; |
|
|
|
virtual const char* GetAttributeNameForType( DmAttributeType_t attType ) const = 0; |
|
virtual DmAttributeType_t GetAttributeTypeForName( const char *name ) const = 0; |
|
|
|
// Adds various serializers and updaters |
|
virtual void AddSerializer( IDmSerializer *pSerializer ) = 0; |
|
virtual void AddLegacyUpdater( IDmLegacyUpdater *pUpdater ) = 0; |
|
virtual void AddFormatUpdater( IDmFormatUpdater *pUpdater ) = 0; |
|
|
|
// file format methods |
|
virtual const char* GetFormatExtension( const char *pFormatName ) = 0; |
|
virtual const char* GetFormatDescription( const char *pFormatName ) = 0; |
|
virtual int GetFormatCount() const = 0; |
|
virtual const char * GetFormatName( int i ) const = 0; |
|
virtual const char * GetDefaultEncoding( const char *pFormatName ) = 0; |
|
|
|
// file encoding methods |
|
virtual int GetEncodingCount() const = 0; |
|
virtual const char * GetEncodingName( int i ) const = 0; |
|
virtual bool IsEncodingBinary( const char *pEncodingName ) const = 0; |
|
virtual bool DoesEncodingStoreVersionInFile( const char *pEncodingName ) const = 0; |
|
|
|
// For serialization, set the delimiter rules |
|
// These methods are meant to be used by importer/exporters |
|
virtual void SetSerializationDelimiter( CUtlCharConversion *pConv ) = 0; |
|
virtual void SetSerializationArrayDelimiter( const char *pDelimiter ) = 0; |
|
|
|
// used to skip auto-creation of child elements during unserialization |
|
virtual bool IsUnserializing() = 0; |
|
|
|
// Serialization of a element tree into a utlbuffer |
|
virtual bool Serialize( CUtlBuffer &outBuf, const char *pEncodingName, const char *pFormatName, DmElementHandle_t hRoot ) = 0; |
|
|
|
// Unserializes, returns the root of the unserialized tree in hRoot |
|
// The file name passed in is simply for error messages and fileid creation |
|
virtual bool Unserialize( CUtlBuffer &inBuf, const char *pEncodingName, const char *pSourceFormatName, const char *pFormatHint, |
|
const char *pFileName, DmConflictResolution_t idConflictResolution, DmElementHandle_t &hRoot ) = 0; |
|
|
|
// converts from elements from old file formats to elements for the current file format |
|
virtual bool UpdateUnserializedElements( const char *pSourceFormatName, int nSourceFormatVersion, |
|
DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot ) = 0; |
|
|
|
// force creation of untyped elements, ignoring type |
|
virtual void OnlyCreateUntypedElements( bool bEnable ) = 0; |
|
|
|
// Finds a serializer by name |
|
virtual IDmSerializer* FindSerializer( const char *pEncodingName ) const = 0; |
|
virtual IDmLegacyUpdater* FindLegacyUpdater( const char *pLegacyFormatName ) const = 0; |
|
virtual IDmFormatUpdater* FindFormatUpdater( const char *pFormatName ) const = 0; |
|
|
|
// saves element tree to a file |
|
virtual bool SaveToFile( const char *pFileName, const char *pPathID, const char *pEncodingName, const char *pFormatName, CDmElement *pRoot ) = 0; |
|
|
|
// restores file into an element tree |
|
// NOTE: Format name is only used here for those formats which don't store |
|
// the format name in the file. Use NULL for those formats which store the |
|
// format name in the file. |
|
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; |
|
|
|
// Sets the name of the DME element to create in keyvalues serialization |
|
virtual void SetKeyValuesElementCallback( IElementForKeyValueCallback *pCallbackInterface ) = 0; |
|
virtual const char *GetKeyValuesElementName( const char *pszKeyName, int iNestingLevel ) = 0; |
|
|
|
// Global symbol table for the datamodel system |
|
virtual UtlSymId_t GetSymbol( const char *pString ) = 0; |
|
virtual const char * GetString( UtlSymId_t sym ) const = 0; |
|
|
|
// Returns the total number of elements allocated at the moment |
|
virtual int GetMaxNumberOfElements() = 0; |
|
virtual int GetElementsAllocatedSoFar() = 0; |
|
virtual int GetAllocatedAttributeCount() = 0; |
|
virtual int GetAllocatedElementCount() = 0; |
|
virtual DmElementHandle_t FirstAllocatedElement() = 0; |
|
virtual DmElementHandle_t NextAllocatedElement( DmElementHandle_t it ) = 0; |
|
|
|
// estimate memory usage |
|
virtual int EstimateMemoryUsage( DmElementHandle_t hElement, TraversalDepth_t depth ) = 0; |
|
|
|
// Undo/Redo support |
|
virtual void SetUndoEnabled( bool enable ) = 0; |
|
virtual bool IsUndoEnabled() const = 0; |
|
virtual bool UndoEnabledForElement( const CDmElement *pElement ) const = 0; |
|
virtual bool IsDirty() const = 0; |
|
virtual bool CanUndo() const = 0; |
|
virtual bool CanRedo() const = 0; |
|
// 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 |
|
virtual void StartUndo( char const *undodesc, char const *redodesc, int nChainingID = 0 ) = 0; |
|
virtual void FinishUndo() = 0; |
|
virtual void AbortUndoableOperation() = 0; // called instead of FinishUndo, essentially performs and Undo() and WipeRedo() if any undo items have been added to the stack |
|
virtual void ClearRedo() = 0; |
|
virtual const char *GetUndoDesc() = 0; |
|
virtual const char *GetRedoDesc() = 0; |
|
// From the UI, perform the Undo operation |
|
virtual void Undo() = 0; |
|
virtual void Redo() = 0; |
|
virtual void TraceUndo( bool state ) = 0; // if true, undo records spew as they are added |
|
|
|
// Wipes out all Undo data |
|
virtual void ClearUndo() = 0; |
|
|
|
virtual void GetUndoInfo( CUtlVector< UndoInfo_t >& list ) = 0; |
|
|
|
virtual void AddUndoElement( IUndoElement *pElement ) = 0; |
|
virtual UtlSymId_t GetUndoDescInternal( const char *context ) = 0; |
|
virtual UtlSymId_t GetRedoDescInternal( const char *context ) = 0; |
|
|
|
virtual void EmptyClipboard() = 0; |
|
virtual void SetClipboardData( CUtlVector< KeyValues * >& data, IClipboardCleanup *pfnOptionalCleanuFunction = 0 ) = 0; |
|
virtual void AddToClipboardData( KeyValues *add ) = 0; |
|
virtual void GetClipboardData( CUtlVector< KeyValues * >& data ) = 0; |
|
virtual bool HasClipboardData() const = 0; |
|
|
|
// Handles to attributes |
|
virtual CDmAttribute * GetAttribute( DmAttributeHandle_t h ) = 0; |
|
virtual bool IsAttributeHandleValid( DmAttributeHandle_t h ) const = 0; |
|
|
|
// file id reference methods |
|
virtual int NumFileIds() = 0; |
|
virtual DmFileId_t GetFileId( int i ) = 0; |
|
virtual DmFileId_t FindOrCreateFileId( const char *pFilename ) = 0; |
|
virtual void RemoveFileId( DmFileId_t fileid ) = 0; |
|
virtual DmFileId_t GetFileId( const char *pFilename ) = 0; |
|
virtual const char * GetFileName( DmFileId_t fileid ) = 0; |
|
virtual void SetFileName( DmFileId_t fileid, const char *pFileName ) = 0; |
|
virtual const char * GetFileFormat( DmFileId_t fileid ) = 0; |
|
virtual void SetFileFormat( DmFileId_t fileid, const char *pFormat ) = 0; |
|
virtual DmElementHandle_t GetFileRoot( DmFileId_t fileid ) = 0; |
|
virtual void SetFileRoot( DmFileId_t fileid, DmElementHandle_t hRoot ) = 0; |
|
virtual bool IsFileLoaded( DmFileId_t fileid ) = 0; |
|
virtual void MarkFileLoaded( DmFileId_t fileid ) = 0; |
|
virtual void UnloadFile( DmFileId_t fileid ) = 0; |
|
virtual int NumElementsInFile( DmFileId_t fileid ) = 0; |
|
|
|
virtual void DontAutoDelete( DmElementHandle_t hElement ) = 0; |
|
|
|
// handle validity methods - these shouldn't really be here, but the undo system needs them... |
|
virtual void MarkHandleInvalid( DmElementHandle_t hElement ) = 0; |
|
virtual void MarkHandleValid( DmElementHandle_t hElement ) = 0; |
|
|
|
virtual DmElementHandle_t FindElement( const DmObjectId_t &id ) = 0; |
|
|
|
virtual DmAttributeReferenceIterator_t FirstAttributeReferencingElement( DmElementHandle_t hElement ) = 0; |
|
virtual DmAttributeReferenceIterator_t NextAttributeReferencingElement( DmAttributeReferenceIterator_t hAttrIter ) = 0; |
|
virtual CDmAttribute * GetAttribute( DmAttributeReferenceIterator_t hAttrIter ) = 0; |
|
|
|
// Install, remove notify callbacks associated w/ undo contexts |
|
virtual bool InstallNotificationCallback( IDmNotify *pNotify ) = 0; |
|
virtual void RemoveNotificationCallback( IDmNotify *pNotify ) = 0; |
|
virtual bool IsSuppressingNotify( ) const = 0; |
|
virtual void SetSuppressingNotify( bool bSuppress ) = 0; |
|
virtual void PushNotificationScope( const char *pReason, int nNotifySource, int nNotifyFlags ) = 0; |
|
virtual void PopNotificationScope( bool bAbort = false ) = 0; |
|
virtual const char *GetUndoString( UtlSymId_t sym ) = 0; |
|
|
|
virtual bool HasElementFactory( const char *pElementType ) const = 0; |
|
|
|
// Call before you make any undo records |
|
virtual void SetUndoDepth( int nSize ) = 0; |
|
|
|
// Displats memory stats to the console |
|
virtual void DisplayMemoryStats() = 0; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Used only by applications to hook in the data model |
|
//----------------------------------------------------------------------------- |
|
#define VDATAMODEL_INTERFACE_VERSION "VDataModelVersion001" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Main interface accessor |
|
//----------------------------------------------------------------------------- |
|
extern IDataModel *g_pDataModel; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Allows clients to implement customized undo elements |
|
//----------------------------------------------------------------------------- |
|
class CUndoElement : public IUndoElement |
|
{ |
|
public: |
|
CUndoElement( const char *pDesc ) |
|
{ |
|
m_UndoDesc = g_pDataModel->GetUndoDescInternal( pDesc ); |
|
m_RedoDesc = g_pDataModel->GetRedoDescInternal( pDesc ); |
|
m_pDesc = pDesc; |
|
m_bEndOfStream = false; |
|
} |
|
|
|
virtual void Release() |
|
{ |
|
delete this; |
|
} |
|
|
|
virtual const char *UndoDesc() const |
|
{ |
|
return g_pDataModel->GetUndoString( m_UndoDesc ); |
|
} |
|
|
|
virtual const char *RedoDesc() const |
|
{ |
|
return g_pDataModel->GetUndoString( m_RedoDesc ); |
|
} |
|
|
|
virtual const char *GetDesc() const |
|
{ |
|
return m_pDesc; |
|
} |
|
|
|
protected: |
|
virtual bool IsEndOfStream() const |
|
{ |
|
return m_bEndOfStream; |
|
} |
|
|
|
virtual void SetEndOfStream( bool end ) |
|
{ |
|
m_bEndOfStream = end; |
|
} |
|
|
|
const char *m_pDesc; |
|
CUtlSymbol m_UndoDesc; |
|
CUtlSymbol m_RedoDesc; |
|
bool m_bEndOfStream; |
|
|
|
private: |
|
friend class CUndoManager; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Simple helper class |
|
//----------------------------------------------------------------------------- |
|
class CUndoScopeGuard |
|
{ |
|
public: |
|
explicit CUndoScopeGuard( const char *udesc, const char *rdesc = NULL ) |
|
{ |
|
m_bReleased = false; |
|
m_bNotify = false; |
|
m_pNotify = NULL; |
|
g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc ); |
|
} |
|
|
|
explicit CUndoScopeGuard( int nChainingID, char const *udesc ) |
|
{ |
|
m_bReleased = false; |
|
m_bNotify = false; |
|
m_pNotify = NULL; |
|
g_pDataModel->StartUndo( udesc, udesc, nChainingID ); |
|
} |
|
|
|
explicit CUndoScopeGuard( int nNotifySource, int nNotifyFlags, const char *udesc, const char *rdesc = NULL, int nChainingID = 0 ) |
|
{ |
|
m_bReleased = false; |
|
m_bNotify = true; |
|
m_pNotify = NULL; |
|
g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc, nChainingID ); |
|
g_pDataModel->PushNotificationScope( udesc, nNotifySource, nNotifyFlags ); |
|
} |
|
|
|
explicit CUndoScopeGuard( int nNotifySource, int nNotifyFlags, IDmNotify *pNotify, const char *udesc, const char *rdesc = NULL, int nChainingID = 0 ) |
|
{ |
|
m_bReleased = false; |
|
m_bNotify = true; |
|
m_pNotify = NULL; |
|
g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc, nChainingID ); |
|
if ( pNotify ) |
|
{ |
|
if ( g_pDataModel->InstallNotificationCallback( pNotify ) ) |
|
{ |
|
m_pNotify = pNotify; |
|
} |
|
} |
|
g_pDataModel->PushNotificationScope( udesc, nNotifySource, nNotifyFlags ); |
|
} |
|
|
|
~CUndoScopeGuard() |
|
{ |
|
Release(); |
|
} |
|
|
|
void Release() |
|
{ |
|
if ( !m_bReleased ) |
|
{ |
|
g_pDataModel->FinishUndo(); |
|
if ( m_bNotify ) |
|
{ |
|
g_pDataModel->PopNotificationScope( ); |
|
m_bNotify = false; |
|
} |
|
if ( m_pNotify ) |
|
{ |
|
g_pDataModel->RemoveNotificationCallback( m_pNotify ); |
|
m_pNotify = NULL; |
|
} |
|
m_bReleased = true; |
|
} |
|
} |
|
|
|
void Abort() |
|
{ |
|
if ( !m_bReleased ) |
|
{ |
|
g_pDataModel->AbortUndoableOperation(); |
|
if ( m_bNotify ) |
|
{ |
|
g_pDataModel->PopNotificationScope( true ); |
|
m_bNotify = false; |
|
} |
|
if ( m_pNotify ) |
|
{ |
|
g_pDataModel->RemoveNotificationCallback( m_pNotify ); |
|
m_pNotify = NULL; |
|
} |
|
m_bReleased = true; |
|
} |
|
} |
|
|
|
private: |
|
IDmNotify *m_pNotify; |
|
bool m_bReleased; |
|
bool m_bNotify; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Simple helper class to disable Undo/Redo operations when in scope |
|
//----------------------------------------------------------------------------- |
|
class CChangeUndoScopeGuard |
|
{ |
|
public: |
|
CChangeUndoScopeGuard( bool bNewState ) |
|
{ |
|
m_bReleased = false; |
|
m_bNotify = false; |
|
m_pNotify = NULL; |
|
m_bOldValue = g_pDataModel->IsUndoEnabled(); |
|
g_pDataModel->SetUndoEnabled( bNewState ); |
|
}; |
|
|
|
CChangeUndoScopeGuard( bool bNewState, const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) |
|
{ |
|
m_bReleased = false; |
|
m_bOldValue = g_pDataModel->IsUndoEnabled(); |
|
g_pDataModel->SetUndoEnabled( bNewState ); |
|
|
|
m_bNotify = true; |
|
m_pNotify = NULL; |
|
if ( pNotify ) |
|
{ |
|
if ( g_pDataModel->InstallNotificationCallback( pNotify ) ) |
|
{ |
|
m_pNotify = pNotify; |
|
} |
|
} |
|
g_pDataModel->PushNotificationScope( pDesc, nNotifySource, nNotifyFlags ); |
|
}; |
|
|
|
~CChangeUndoScopeGuard() |
|
{ |
|
Release(); |
|
} |
|
|
|
void Release() |
|
{ |
|
// Releases the guard... |
|
if ( !m_bReleased ) |
|
{ |
|
g_pDataModel->SetUndoEnabled( m_bOldValue ); |
|
m_bReleased = true; |
|
if ( m_bNotify ) |
|
{ |
|
g_pDataModel->PopNotificationScope( ); |
|
m_bNotify = false; |
|
} |
|
if ( m_pNotify ) |
|
{ |
|
g_pDataModel->RemoveNotificationCallback( m_pNotify ); |
|
m_pNotify = NULL; |
|
} |
|
} |
|
} |
|
|
|
private: |
|
IDmNotify *m_pNotify; |
|
bool m_bOldValue; |
|
bool m_bReleased; |
|
bool m_bNotify; |
|
}; |
|
|
|
class CDisableUndoScopeGuard : public CChangeUndoScopeGuard |
|
{ |
|
typedef CChangeUndoScopeGuard BaseClass; |
|
|
|
public: |
|
CDisableUndoScopeGuard() : BaseClass( false ) { } |
|
CDisableUndoScopeGuard( const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) : |
|
BaseClass( false, pDesc, nNotifySource, nNotifyFlags, pNotify ) {} |
|
}; |
|
|
|
class CEnableUndoScopeGuard : public CChangeUndoScopeGuard |
|
{ |
|
typedef CChangeUndoScopeGuard BaseClass; |
|
|
|
public: |
|
CEnableUndoScopeGuard( ) : BaseClass( true ) { } |
|
CEnableUndoScopeGuard( const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) : |
|
BaseClass( true, pDesc, nNotifySource, nNotifyFlags, pNotify ) {} |
|
}; |
|
|
|
|
|
#define DEFINE_SOURCE_UNDO_SCOPE_GUARD( _classnameprefix, _source ) \ |
|
class C ## _classnameprefix ## UndoScopeGuard : public CUndoScopeGuard \ |
|
{ \ |
|
typedef CUndoScopeGuard BaseClass; \ |
|
\ |
|
public: \ |
|
C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, const char *pUndoDesc, const char *pRedoDesc = NULL, int nChainingID = 0 ) : \ |
|
BaseClass( _source, nNotifyFlags, pUndoDesc, pRedoDesc, nChainingID ) \ |
|
{ \ |
|
} \ |
|
C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, IDmNotify *pNotify, const char *pUndoDesc, const char *pRedoDesc = NULL, int nChainingID = 0 ) : \ |
|
BaseClass( _source, nNotifyFlags, pNotify, pUndoDesc, pRedoDesc, nChainingID ) \ |
|
{ \ |
|
} \ |
|
C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, const char *pUndoDesc, int nChainingID ) : \ |
|
BaseClass( _source, nNotifyFlags, pUndoDesc, pUndoDesc, nChainingID ) \ |
|
{ \ |
|
} \ |
|
}; \ |
|
class C ## _classnameprefix ## DisableUndoScopeGuard : public CDisableUndoScopeGuard \ |
|
{ \ |
|
typedef CDisableUndoScopeGuard BaseClass; \ |
|
\ |
|
public: \ |
|
C ## _classnameprefix ## DisableUndoScopeGuard( const char *pDesc, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \ |
|
BaseClass( pDesc, _source, nNotifyFlags, pNotify ) \ |
|
{ \ |
|
} \ |
|
}; \ |
|
class C ## _classnameprefix ## EnableUndoScopeGuard : public CEnableUndoScopeGuard \ |
|
{ \ |
|
typedef CEnableUndoScopeGuard BaseClass; \ |
|
\ |
|
public: \ |
|
C ## _classnameprefix ## EnableUndoScopeGuard( const char *pDesc, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \ |
|
BaseClass( pDesc, _source, nNotifyFlags, pNotify ) \ |
|
{ \ |
|
} \ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Simple helper class to disable NotifyDataChanged from current scope |
|
//----------------------------------------------------------------------------- |
|
class CNotifyScopeGuard |
|
{ |
|
public: |
|
CNotifyScopeGuard( const char *pReason, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) |
|
{ |
|
m_bReleased = false; |
|
m_pNotify = NULL; |
|
g_pDataModel->PushNotificationScope( pReason, nNotifySource, nNotifyFlags ); |
|
if ( pNotify ) |
|
{ |
|
if ( g_pDataModel->InstallNotificationCallback( pNotify ) ) |
|
{ |
|
m_pNotify = pNotify; |
|
} |
|
} |
|
}; |
|
|
|
~CNotifyScopeGuard() |
|
{ |
|
Release(); |
|
} |
|
|
|
void Release() |
|
{ |
|
// Releases the guard... |
|
if ( !m_bReleased ) |
|
{ |
|
g_pDataModel->PopNotificationScope( ); |
|
if ( m_pNotify ) |
|
{ |
|
g_pDataModel->RemoveNotificationCallback( m_pNotify ); |
|
m_pNotify = NULL; |
|
} |
|
m_bReleased = true; |
|
} |
|
} |
|
|
|
private: |
|
CNotifyScopeGuard( const CNotifyScopeGuard& g ); |
|
|
|
private: |
|
IDmNotify *m_pNotify; |
|
bool m_bReleased; |
|
}; |
|
|
|
|
|
#define DEFINE_SOURCE_NOTIFY_SCOPE_GUARD( _classnameprefix, _source ) \ |
|
class C ## _classnameprefix ## NotifyScopeGuard : public CNotifyScopeGuard \ |
|
{ \ |
|
typedef CNotifyScopeGuard BaseClass; \ |
|
\ |
|
public: \ |
|
C ## _classnameprefix ## NotifyScopeGuard( const char *pReason, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \ |
|
BaseClass( pReason, _source, nNotifyFlags, pNotify )\ |
|
{ \ |
|
} \ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Simple helper class to disable notifications when in scope |
|
//----------------------------------------------------------------------------- |
|
class CChangeNotifyScopeGuard |
|
{ |
|
public: |
|
CChangeNotifyScopeGuard( bool bNewState ) |
|
{ |
|
m_bReleased = false; |
|
m_bOldValue = g_pDataModel->IsSuppressingNotify(); |
|
g_pDataModel->SetSuppressingNotify( bNewState ); |
|
}; |
|
|
|
~CChangeNotifyScopeGuard() |
|
{ |
|
Release(); |
|
} |
|
|
|
void Release() |
|
{ |
|
// Releases the guard... |
|
if ( !m_bReleased ) |
|
{ |
|
g_pDataModel->SetSuppressingNotify( m_bOldValue ); |
|
m_bReleased = true; |
|
} |
|
} |
|
|
|
private: |
|
bool m_bOldValue; |
|
bool m_bReleased; |
|
}; |
|
|
|
class CDisableNotifyScopeGuard : public CChangeNotifyScopeGuard |
|
{ |
|
typedef CChangeNotifyScopeGuard BaseClass; |
|
|
|
public: |
|
CDisableNotifyScopeGuard() : BaseClass( true ) { } |
|
|
|
private: |
|
CDisableNotifyScopeGuard( const CDisableNotifyScopeGuard& g ); |
|
}; |
|
|
|
class CEnableNotifyScopeGuard : public CChangeNotifyScopeGuard |
|
{ |
|
typedef CChangeNotifyScopeGuard BaseClass; |
|
|
|
public: |
|
CEnableNotifyScopeGuard( ) : BaseClass( false ) { } |
|
|
|
private: |
|
CEnableNotifyScopeGuard( const CEnableNotifyScopeGuard& g ); |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Standard undo/notify guards for the application |
|
//----------------------------------------------------------------------------- |
|
DEFINE_SOURCE_UNDO_SCOPE_GUARD( App, NOTIFY_SOURCE_APPLICATION ); |
|
DEFINE_SOURCE_NOTIFY_SCOPE_GUARD( App, NOTIFY_SOURCE_APPLICATION ); |
|
|
|
|
|
|
|
#endif // IDATAMODEL_H
|
|
|