Undo Resetting Array Values

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/01/2012 at 13:53, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R13 
Platform:   Windows  ;   Mac OSX  ; 
Language(s) :     C++  ;

---------
A GeDynamicArray of vectors is a member variable in my EffectorData class.

Most or all of the stored vectors are reset to their saved values each time an Undo action is peformed.

NodeData::CopyTo() is being called for each Undo and the array is being copied correctly to the cloned render document. Read() and Write() are implemented.

  
Bool GapEffector::CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, COPYFLAGS flags, AliasTrans *trn)   
{   
     GapEffector* base = (GapEffector* )dest; if(!base) return FALSE;        
     base->datArr = datArr;   
        
     return TRUE;   
}   

The problem doesn't occur if the array is stored in a static or global variable. Another option is needed as I don't want separate plugin instances accessing the same array.

Any help would be much appreciated.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2012 at 06:01, xxxxxxxx wrote:

You're not actually creating a new instance of the GeDynamicArray.  You are simply pointing the destination at the source one.  You need to allocate a new GeDynamicArray and copy/clone the data from source to destination.  The '=' operator has this information:

_ Note: You need to increase the size manually using SetCount(). You also need to copy all elements from the array._

Either use this constructor (which may copy the data (??)) :

base->datArr = GeDynamicArray(datArr);

or use something like MergeIn().

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/01/2012 at 23:52, xxxxxxxx wrote:

Thanks for the suggestions Robert.

Unfortunately using the constructor in that way generates compile errors and the problem still exists with MergeIn().

I also tried this based on your old HyperFile post but the cache array is still being cleared.

  
     if(cacheArr)   
     {   
          base->cacheArr = GeAllocType(Vector, cnt); if(!base->cacheArr) return FALSE;   
          CopyMem(cacheArr, base->cacheArr, sizeof(Vector) * cnt);   
    }        

I've tried using a SceneHook to send a MSG_DOCUMENTINFO_TYPE_UNDO message to the effector so that I can manually cache and restore the array. This isn't possible as Undo clears the array before the message is sent.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 22/01/2012 at 07:53, xxxxxxxx wrote:

You are declaring the member variable like this (IvyRoot is a class that I use) :

GeDynamicArray<IvyRoot*>    roots;

Then allocating (gNew or ::Alloc() or GeAlloc()) each element of the array and pushing it:

IvyRoot*    newRoot =        gNew IvyRoot;
 if (!newRoot)                return FALSE;
// - copy values from source element to destination element
// - Push into GeDynamicArray
roots.Push(newRoot);

Note that you MUST allocate the objects stored in the GeDynamicArray.

I think that you must then recreate the elements on the source and Push() them onto the destination array in CopyTo().  Note that CopyTo() works in both directions - when storing an undo and actually undoing.  When you store an undo (doc->AddUndo(UNDOTYPE_DELETE) for instance), CopyTo() copies the object (source->destination) into the undo stack.  When an undo is undone, the copy is copied back using CopyTo() from the undo stack (still source->destination).

Hope that clarifies the use of GeDynamicArray, CopyTo() and undo a bit.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 24/01/2012 at 03:38, xxxxxxxx wrote:

I'm afraid I can't get this to work but the clarification on the workings of CopyTo() and Undo is definitely useful. I'll keep exploring and post any reults.

Thanks again for your help.