Classes | Public Member Functions

ReferenceSaveManager Class Reference

This reference page is linked to from the following overview topics: Major New Features, Guidelines for Changing the Reference Structure.


Search for all occurrences

Detailed Description

Used to specify and enumerate the save reference hierarchy, if different from the normal reference hierarchy.

A ReferenceMaker can add, remove, or replace the contents of its "reference slots" in the context of scene files saves. The primary use of this ability is to support Save To Previous, particularly when converting a plugin from ParamBlock to ParamBlock2. When performing a Save to Previous, instead of storing the ParamBlock2 instance, the plugin needs to store a ParamBlock instance. At the beginning of a scene file save, the virtual ReferenceMaker::SpecifySaveReferences() method is called. If a plugin needs to store an alternative reference hierarchy, the plugin would specify the changes from the normal reference hierarchy using the supplied ReferenceSaveManager. See ReferenceMaker::SpecifySaveReferences for an example implementation.

If an Add or Replace reference slot operation is performed, and a non-NULL ReferenceTarget is supplied, the ReferenceSaveManager will hold a reference to the ReferenceTarget. This reference will be dropped at the end of the scene file save.

The Add/Remove/Replace reference slot operation calls register actions with the ReferenceSaveManager, and these actions are processed in the ReferenceMaker::SpecifySaveReferences() implementation. Invalid reference slot indices will not be detected until the ReferenceMaker::SpecifySaveReferences() implementation is executed, and will result in return value of false from that implementation.

If a plugin needs to access the save reference hierarchy, it would do so through the ReferenceSaveManager. The most common case of this would be in a SaveEnum(). For example:

    void Scene::SaveEnum(SaveEnumProc& sep, BOOL isNodeCall) {
        if (sep.terminate(this))
            return;

        if(GetCustAttribContainer())
            GetCustAttribContainer()->SaveEnum(sep);

        ReferenceSaveManager& referenceSaveManager = GetReferenceSaveManager();
        DbgAssert(referenceSaveManager.ReadyForSave());
        int numSaveRefs = referenceSaveManager.NumRefs();
        for (int i=0; i < numSaveRefs; i++) 
        {   
            ReferenceTarget* refTarg = referenceSaveManager.GetReference(i);
            if (refTarg)
                refTarg->SaveEnum(sep, (i == SCENE_REF_ROOTNODE) ? TRUE : FALSE);
        }

        int numSaveIndirectRefs = referenceSaveManager->NumIndirectRefs();
        for (int j=0; j < numSaveIndirectRefs; j++)
        {
            ReferenceTarget* refTarg = referenceSaveManager->GetIndirectReference(j);
            if (refTarg)
                refTarg->SaveEnum(sep);
        }

        sep.proc(this); // process bottom up in ref hierarchy
    }

If the ReferenceSaveManager is used to enumerate the save reference hierarchy before it has been prepared by a call to ReferenceMaker::SpecifySaveReferences(), the normal reference hierarchy will be exposed. That is, ReferenceSaveManager::NumRefs() will be routed to ReferenceMaker::NumRefs(), ReferenceSaveManager::GetReference() will be routed to ReferenceMaker::GetReference(), etc.

This interface is implemented by 3ds Max. Plug-ins do not need to implement it.

See also:
Interface::EnumAuxFiles, ReferenceMaker::SpecifySaveReferences, ReferenceMaker::EnumAuxFiles

#include <ReferenceSaveManager.h>

Inheritance diagram for ReferenceSaveManager:
Inheritance graph
[legend]

List of all members.

Classes

class   PostSave
  Used to tear down a save reference hierarchy. More...
class   PreSave
  Used to prepare a save reference hierarchy. More...

Public Member Functions

virtual int  NumRefs ()=0
  Returns the number of direct references in the save reference hierarchy.
virtual ReferenceTarget GetReference (int i, bool usePersistenceTests=true)=0
  Returns the i'th direct reference in the save reference hierarchy.
virtual bool  IsRealDependency (ReferenceTarget *theRef)=0
  Returns whether this is a "real" (strong) dependency or not.
virtual bool  ShouldPersistWeakReference (ReferenceTarget *theRef)=0
  Returns whether a weak reference is to be persisted on a partial load or save.
virtual int  NumIndirectRefs ()=0
  Returns the number of indirect references in the save reference hierarchy.
virtual ReferenceTarget GetIndirectReference (int i, bool usePersistenceTests=true)=0
  Returns the i'th indirect reference in the save reference hierarchy.
virtual bool  ShouldPersistIndirectReference (ReferenceTarget *theRef)=0
  Returns whether the indirect reference is to be persisted on a partial load or save.
virtual void  AddReferenceSlot (int insertAt, ReferenceTarget *theRef)=0
  Adds a reference slot to the save reference hierarchy.
virtual void  ReplaceReferenceSlot (int which, ReferenceTarget *theRef)=0
  Replaces the contents of a reference slot in the save reference hierarchy.
virtual void  RemoveReferenceSlot (int which)=0
  Removes a reference slot from the save reference hierarchy.
virtual void  AddIndirectReferenceSlot (int insertAt, ReferenceTarget *theRef)=0
  Adds an indirect reference slot to the save reference hierarchy.
virtual void  ReplaceIndirectReferenceSlot (int which, ReferenceTarget *theRef)=0
  Replaces the contents of an indirect reference slot in the save reference hierarchy.
virtual void  RemoveIndirectReferenceSlot (int which)=0
  Removes an indirect reference slot from the save reference hierarchy.
virtual void  SetReplacementReferenceTarget (ReferenceTarget *theRef)=0
  Specifies a ReferenceTarget that is to be saved instead of the ReferenceTarget represented by this instance of ReferenceSaveManager.
virtual bool  ReplacementReferenceTargetSpecified () const =0
  Returns whether a replacement ReferenceTarget was specified.
virtual ReferenceTarget GetReplacementReferenceTarget ()=0
  Returns the ReferenceTarget that is to be saved instead of the ReferenceTarget represented by this instance of the ReferenceSaveManager.
virtual bool  ReadyForSave () const =0
  Detect whether SpecifySaveReferences() was called on the ReferenceMaker.
virtual void  Clear ()=0
  Clears the save reference hierarchy.
virtual  ~ReferenceSaveManager ()
  Required virtual dtor.

Constructor & Destructor Documentation

virtual ~ReferenceSaveManager ( ) [inline, virtual]

Required virtual dtor.

{}

Member Function Documentation

virtual int NumRefs ( ) [pure virtual]

Returns the number of direct references in the save reference hierarchy.

The number of direct references in the save reference hierarchy is based on the number of references held by the ReferenceMaker and the Add/Remove reference slot operations. If no Add/Remove reference slot operations were performed, or if the save reference hierarchy has not been prepared, the value returned is the result from ReferenceMaker::NumRefs().

Returns:
Returns the number of direct references in the save reference hierarchy.
virtual ReferenceTarget* GetReference ( int  i,
bool  usePersistenceTests = true 
) [pure virtual]

Returns the i'th direct reference in the save reference hierarchy.

Returns the i'th direct reference in the save reference hierarchy. If no Add/Remove/Replace reference slot operations was performed on the slot, or if the save reference hierarchy has not been prepared, the value returned is the result from ReferenceMaker::GetReference using the appropriate index value. The index value may be different than 'i' if Add/Remove reference slot operations were performed.

Parameters:
i Which direct reference in the save reference hierarchy to return
usePersistenceTests If true, a NULL value will be returned if the reference does not pass the persistence tests. A reference is persistent if ReferenceMaker::IsRealDependency or ReferenceMaker::ShouldPersistWeakRef returns true for the reference, or if the reference was specified using AddReferenceSlot or ReplaceReferenceSlot. Note that even if a reference is not persistent for a given ReferenceMaker, it may be persistent on another ReferenceMaker, and thus would be saved to the scene file. The behavior of the 3ds Max scene file load is that if the ReferenceTarget is loaded, it is set as a reference to all ReferenceMakers that held a reference to it, regardless of whether it was considered persistent on that ReferenceMakers or not. In most cases, and particularly in SaveEnum and EnumAuxFiles implementations, usePersistenceTests would be true - you only want to enumerate references that are guaranteed to be saved. If for some reason you want to look at all references, including those not guaranteed to be saved, then usePersistenceTests would be false. You can perform additional tests on the references using IsRealDependency and ShouldPersistWeakReference to see whether the reference would be persistent.
Returns:
Returns the i'th direct reference in the save reference hierarchy.
virtual bool IsRealDependency ( ReferenceTarget theRef ) [pure virtual]

Returns whether this is a "real" (strong) dependency or not.

Returns true if the reference is considered a strong dependency. If the reference was specified by a Add/Replace operation, it is considered a strong dependency. Otherwise, the call is passed to ReferenceMaker::IsRealDependency, and its value is returned.

Parameters:
theRef A pointer to the reference target.
Returns:
true if the reference dependency is "real". Otherwise it returns false.
virtual bool ShouldPersistWeakReference ( ReferenceTarget theRef ) [pure virtual]

Returns whether a weak reference is to be persisted on a partial load or save.

Returns true if the reference should be persisted if it is not a strong dependency. The call is passed to ReferenceMaker::ShouldPersistWeakRef, and its value is returned.

Parameters:
theRef A pointer to the reference target.
Returns:
Whether to force the load/save of the weak reference if this reference maker is saved.
virtual int NumIndirectRefs ( ) [pure virtual]

Returns the number of indirect references in the save reference hierarchy.

The number of indirect references in the save reference hierarchy is based on the number of indirect references held by the ReferenceMaker and the Add/Remove indirect reference slot operations. If no Add/Remove indirect reference slot operations were performed, or if the save reference hierarchy has not been prepared, the value returned is the result from IIndirectReferenceMaker::NumIndirectRefs().

Returns:
Returns the number of direct references in the save reference hierarchy.
virtual ReferenceTarget* GetIndirectReference ( int  i,
bool  usePersistenceTests = true 
) [pure virtual]

Returns the i'th indirect reference in the save reference hierarchy.

Returns the i'th indirect reference in the save reference hierarchy. If no Add/Remove/Replace indirect reference slot operations was performed on the slot, or if the save reference hierarchy has not been prepared, the value returned is the result from IIndirectReferenceMaker::GetIndirectReference using the appropriate index value. The index value may be different than 'i' if Add/Remove indirect reference slot operations were performed.

Parameters:
i Which indirect reference in the save reference hierarchy to return
usePersistenceTests If true, a NULL value will be returned if the reference does not pass the persistence tests. A reference is persistent if IIndirectReferenceMaker::ShouldPersistIndirectRef returns true for the reference, or if the reference was specified using AddIndirectReferenceSlot or RemoveIndirectReferenceSlot. Note that even if a reference is not persistent for a given ReferenceMaker, it may be persistent on another ReferenceMaker, and thus would be saved to the scene file. The behavior of the 3ds Max scene file load is that if the ReferenceTarget is loaded, it is set as a reference to all ReferenceMakers that held a reference to it, regardless of whether it was considered persistent on that ReferenceMakers or not. In most cases, and particularly in SaveEnum and EnumAuxFiles implementations, usePersistenceTests would be true - you only want to enumerate references that are guaranteed to be saved. If for some reason you want to look at all references, including those not guaranteed to be saved, then usePersistenceTests would be false. You can perform additional tests on the references using ShouldPersistIndirectReference to see whether the reference would be persistent.
Returns:
Returns the i'th indirect reference in the save reference hierarchy.
virtual bool ShouldPersistIndirectReference ( ReferenceTarget theRef ) [pure virtual]

Returns whether the indirect reference is to be persisted on a partial load or save.

Returns true if the indirect reference is to be persisted on a partial load or save. If the indirect reference was specified by a Add/Replace operation, it should be persisted and the method will return true. Otherwise, the call is passed to IIndirectReferenceMaker::ShouldPersistIndirectRef, and it's value is returned.

Parameters:
theRef - A pointer to the reference target.
Returns:
Whether to force the load/save of the indirect reference if this reference maker is saved.
virtual void AddReferenceSlot ( int  insertAt,
ReferenceTarget theRef 
) [pure virtual]

Adds a reference slot to the save reference hierarchy.

Inserts a reference slot at the specified index value. A GetReference call on that slot will return the specified ReferenceTarget. The ReferenceSaveManager will hold a reference to the specified ReferenceTarget until the end of the save operation.

Parameters:
insertAt The index to insert a reference slot at.
theRef The reference to store in the reference slot.
virtual void ReplaceReferenceSlot ( int  which,
ReferenceTarget theRef 
) [pure virtual]

Replaces the contents of a reference slot in the save reference hierarchy.

Specifies the ReferenceTarget value to return for a GetReference call on that slot. The ReferenceSaveManager will hold a reference to the specified ReferenceTarget until the end of the save operation.

Parameters:
which The index of the reference slot.
theRef The reference to store in the reference slot.
virtual void RemoveReferenceSlot ( int  which ) [pure virtual]

Removes a reference slot from the save reference hierarchy.

Deletes a reference slot at the specified index value.

Parameters:
which The index of the reference slot to delete
virtual void AddIndirectReferenceSlot ( int  insertAt,
ReferenceTarget theRef 
) [pure virtual]

Adds an indirect reference slot to the save reference hierarchy.

Inserts an indirect reference slot at the specified index value. A GetIndirectReference call on that slot will return the specified ReferenceTarget. The ReferenceSaveManager will hold a reference to the specified ReferenceTarget until the end of the save operation.

Parameters:
insertAt The index to insert a indirect reference slot at.
theRef The reference to store in the indirect reference slot.
virtual void ReplaceIndirectReferenceSlot ( int  which,
ReferenceTarget theRef 
) [pure virtual]

Replaces the contents of an indirect reference slot in the save reference hierarchy.

Specifies the ReferenceTarget value to return for a GetIndirectReference call on that slot. The ReferenceSaveManager will hold a reference to the specified ReferenceTarget until the end of the save operation.

Parameters:
which The index of the indirect reference slot.
theRef The reference to store in the indirect reference slot.
virtual void RemoveIndirectReferenceSlot ( int  which ) [pure virtual]

Removes an indirect reference slot from the save reference hierarchy.

Deletes an indirect reference slot at the specified index value.

Parameters:
which The index of the indirect reference slot to delete
virtual void SetReplacementReferenceTarget ( ReferenceTarget theRef ) [pure virtual]

Specifies a ReferenceTarget that is to be saved instead of the ReferenceTarget represented by this instance of ReferenceSaveManager.

In some cases, instead of storing the current ReferenceTarget, you want another ReferenceTarget to be stored. An example of this is when doing a Save To Previous, and the previous version of 3ds Max expects a ReferenceTarget of a different class. In this case, the ReferenceTarget represented by this instance of ReferenceSaveManager would implement the SpecifySaveReferences method, and in that implementation create an instance of the old class, configure that instance as needed, and then specify to save that instance using this method. The ReferenceSaveManager will hold a reference to the specified ReferenceTarget until the end of the save operation. The replacement ReferenceTarget specified by the most-derived class is used as the replacement ReferenceTarget. A reference will be held to all replacement ReferenceTargets specified, and those references will be dropped at the end of the file save. If this method is called, the ReferenceTarget represented by this instance of ReferenceSaveManager will not be saved. While calls to the various direct/indirect reference methods in this class are still valid, they have no affect on what is saved since they operate on the ReferenceTarget represented by this instance of ReferenceSaveManager.

Parameters:
[in] theRef The replacement reference to store to the scene file. A NULL value is a valid replacement reference pointer.

The following is an example usage, where all Marble instance are replaced with Checker instances /code bool Marble::SpecifySaveReferences(ReferenceSaveManager& referenceSaveManager) { ReferenceTarget* newRef = (ReferenceTarget*)GetCOREInterface()->CreateInstance(TEXMAP_CLASS_ID, Class_ID(CHECKER_CLASS_ID,0)); referenceSaveManager.SetReplacementReferenceTarget(newRef); return Tex3D::SpecifySaveReferences(referenceSaveManager); } /endcode

virtual bool ReplacementReferenceTargetSpecified ( ) const [pure virtual]

Returns whether a replacement ReferenceTarget was specified.

Returns:
Returns true if SetReplacementReferenceTarget() was called.
virtual ReferenceTarget* GetReplacementReferenceTarget ( ) [pure virtual]

Returns the ReferenceTarget that is to be saved instead of the ReferenceTarget represented by this instance of the ReferenceSaveManager.

This method should not be called unless ReplacementReferenceTargetSpecified() returns true since this method will return NULL if SetReplacementReferenceTarget has not been called.

Returns:
Returns the replacement ReferenceTarget.
virtual bool ReadyForSave ( ) const [pure virtual]

Detect whether SpecifySaveReferences() was called on the ReferenceMaker.

Before the save reference hierarchy can be accessed, SpecifySaveReferences() needs to be called on the ReferenceMaker to prepare the save reference hierarchy.

Returns:
Returns true if SpecifySaveReferences() was called on the ReferenceMaker.
virtual void Clear ( ) [pure virtual]

Clears the save reference hierarchy.

Clears the save reference hierarchy, dropping references to any ReferenceTargets specified by Add/Replace direct/indirect reference slot operations.


ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager
ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager ReferenceSaveManager