Commit b4191454 authored by Sebastien Jourdain's avatar Sebastien Jourdain

Fix some undo/redo issues

parent bae30ff4
......@@ -85,7 +85,6 @@ int vtkUndoSet::GetNumberOfElements()
int vtkUndoSet::Redo()
{
int max = this->Collection->GetNumberOfItems();
cout << "Going to redo " << max << " actions" << endl;
for (int cc=0; cc <max; cc++)
{
vtkUndoElement* elem = vtkUndoElement::SafeDownCast(
......
......@@ -52,7 +52,7 @@ void vtkPMObject::Initialize(vtkSMSessionCore* session)
}
//----------------------------------------------------------------------------
vtkPMObject* vtkPMObject::GetPMObject(vtkTypeUInt32 globalid)
vtkPMObject* vtkPMObject::GetPMObject(vtkTypeUInt32 globalid) const
{
if (this->SessionCore)
{
......
......@@ -68,7 +68,7 @@ public:
// Description:
// Convenience method to obtain a vtkPMObject subclass given its global id.
vtkPMObject* GetPMObject(vtkTypeUInt32 globalid);
vtkPMObject* GetPMObject(vtkTypeUInt32 globalid) const;
// Description:
// Convenience method to obtain a vtkSMRemoteObject subclass given its
......
......@@ -17,12 +17,14 @@
#include "vtkClientServerStream.h"
#include "vtkObjectFactory.h"
#include "vtkPMProxy.h"
#include "vtkPMObject.h"
#include "vtkPVXMLElement.h"
#include "vtkSMMessage.h"
#include "vtkSMRemoteObject.h"
#include <assert.h>
#include <vtkstd/set>
#include <vtkSmartPointer.h>
//****************************************************************************/
// Internal Classes and typedefs
......@@ -30,6 +32,11 @@
class vtkPMProxyProperty::InternalCache
{
public:
InternalCache(vtkPMProxyProperty* parent)
{
this->Parent = parent;
}
//--------------------------------------------------------------------------
void SetVariant(const Variant *variant)
{
......@@ -37,6 +44,7 @@ public:
for (int cc=0; cc < variant->proxy_global_id_size(); cc++)
{
this->VariantSet.insert( variant->proxy_global_id(cc) );
this->Dependancy.push_back(this->Parent->GetPMObject(variant->proxy_global_id(cc)));
}
}
......@@ -78,20 +86,24 @@ public:
//--------------------------------------------------------------------------
void UpdateRegisteredProxy()
{
this->Dependancy.erase(this->Dependancy.begin(), this->Dependancy.begin() += this->RegisteredProxy.size());
this->RegisteredProxy = VariantSet;
this->VariantSet.clear();
}
//--------------------------------------------------------------------------
private:
vtkstd::set<vtkTypeUInt32> RegisteredProxy;
vtkstd::set<vtkTypeUInt32> VariantSet;
vtkstd::vector<vtkSmartPointer<vtkPMObject> > Dependancy;
vtkPMProxyProperty* Parent;
};
//****************************************************************************/
vtkStandardNewMacro(vtkPMProxyProperty);
//----------------------------------------------------------------------------
vtkPMProxyProperty::vtkPMProxyProperty()
{
this->Cache = new InternalCache();
this->Cache = new InternalCache(this);
this->CleanCommand = 0;
this->RemoveCommand = 0;
this->ArgumentType = VTK;
......
......@@ -20,8 +20,16 @@
#include "vtkSMMessage.h"
#include "vtkSMProxy.h"
#include "vtkSMProxyLocator.h"
#include "vtkSMProxyManager.h"
#include "vtkSMSession.h"
#include <vtkstd/algorithm>
#include <vtkstd/map>
#include <vtkstd/set>
#include <vtkstd/vector>
#include <vtkstd/iterator>
#include <assert.h>
vtkStandardNewMacro(vtkSMInputProperty);
......@@ -64,8 +72,68 @@ void vtkSMInputProperty::WriteTo(vtkSMMessage* message)
//---------------------------------------------------------------------------
void vtkSMInputProperty::ReadFrom(const vtkSMMessage* message, int message_offset)
{
(void) message;
(void) message_offset;
// FIXME this method is REALLY close to its superclass: Please keep them in sync
const ProxyState_Property *prop = &message->GetExtension(ProxyState::property, message_offset);
if(strcmp(prop->name().c_str(), this->GetXMLName()) == 0)
{
const Variant *value = &prop->value();
assert(value->proxy_global_id_size() == value->port_number_size());
int nbProxies = value->proxy_global_id_size();
vtkstd::set<vtkTypeUInt32> newProxyIdList;
vtkstd::set<vtkTypeUInt32>::const_iterator proxyIdIter;
vtkstd::map<vtkTypeUInt32,int> proxyIdPortMap;
// Fill indexed proxy id list
for(int i=0;i<nbProxies;i++)
{
proxyIdPortMap[value->proxy_global_id(i)] = value->port_number(i);
newProxyIdList.insert(value->proxy_global_id(i));
}
// Deal with existing proxy
for(unsigned int i=0;i<this->GetNumberOfProxies();i++)
{
vtkSMProxy *proxy = this->GetProxy(i);
vtkTypeUInt32 id = proxy->GetGlobalID();
if((proxyIdIter=newProxyIdList.find(id)) == newProxyIdList.end())
{
// Not find => Need to be removed
this->RemoveProxy(proxy, false); // FIXME do we need to tag proxy as modified ?
}
else
{
// Already there, no need to add it twice
newProxyIdList.erase(proxyIdIter);
}
}
// Managed real new proxy
for(proxyIdIter=newProxyIdList.begin();
proxyIdIter != newProxyIdList.end();
proxyIdIter++)
{
// Get the proxy from proxy manager
vtkSMProxyManager* pxm = vtkSMProxyManager::GetProxyManager();
vtkSMProxy* proxy = vtkSMProxy::SafeDownCast(
pxm->GetSession()->GetRemoteObject(*proxyIdIter));
if(proxy)
{
this->AddInputConnection(proxy, proxyIdPortMap[*proxyIdIter],false); // FIXME do we need to tag proxy as modified ?
}
else
{
// Recreate the proxy as it used to be
proxy = vtkSMProxy::SafeDownCast(
pxm->GetSession()->ReNewRemoteObject(*proxyIdIter));
this->AddInputConnection(proxy, proxyIdPortMap[*proxyIdIter], true);
}
}
}
else
{
vtkWarningMacro("Invalid offset property");
}
this->Modified();
}
//---------------------------------------------------------------------------
......
......@@ -243,7 +243,6 @@ struct vtkSMProxyManagerInternals
{
// Fill equivalent temporary data structure
vtkstd::set<vtkSMProxyManagerEntry> newStateContent;
vtkstd::vector<vtkTypeUInt32> proxyToReset;
int max = newState->ExtensionSize(ProxyManagerState::registered_proxy);
for(int cc=0; cc < max; cc++)
{
......@@ -255,10 +254,9 @@ struct vtkSMProxyManagerInternals
if(!proxy)
{
proxyToReset.push_back(reg.global_id());
vtkSMProxy *proxy =
vtkSMProxy::SafeDownCast(
this->ProxyManager->GetSession()->ReNewRemoteObject(reg.global_id(),false));
this->ProxyManager->GetSession()->ReNewRemoteObject(reg.global_id()));
if(proxy)
{
newStateContent.insert(vtkSMProxyManagerEntry(reg.group().c_str(), reg.name().c_str(), proxy));
......@@ -275,12 +273,6 @@ struct vtkSMProxyManagerInternals
}
}
// Reset freshly created proxy
for(unsigned int cc=0; cc < proxyToReset.size(); cc++)
{
this->ProxyManager->GetSession()->ResetRemoteObject(proxyToReset[cc]);
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// FIXME there might be a better way to do that
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......
......@@ -366,66 +366,66 @@ void vtkSMProxyProperty::WriteTo(vtkSMMessage* message)
//---------------------------------------------------------------------------
void vtkSMProxyProperty::ReadFrom(const vtkSMMessage* message, int message_offset)
{
bool found = false;
for(int i=0;i<message->ExtensionSize(ProxyState::property);++i)
{
const ProxyState_Property *prop = &message->GetExtension(ProxyState::property, i);
if(strcmp(prop->name().c_str(), this->GetXMLName()) == 0)
// FIXME this method is REALLY close to its vtkSMInputProperty subClass
// Please keep them in sync
const ProxyState_Property *prop = &message->GetExtension(ProxyState::property, message_offset);
if(strcmp(prop->name().c_str(), this->GetXMLName()) == 0)
{
const Variant *value = &prop->value();
int nbProxies = value->proxy_global_id_size();
vtkstd::set<vtkTypeUInt32> newProxyIdList;
vtkstd::set<vtkTypeUInt32>::const_iterator proxyIdIter;
// Fill indexed proxy id list
for(int i=0;i<nbProxies;i++)
{
const Variant *value = &prop->value();
int nbProxies = value->proxy_global_id_size();
vtkstd::set<vtkTypeUInt32> newProxyIdList;
vtkstd::set<vtkTypeUInt32>::const_iterator proxyIdIter;
newProxyIdList.insert(value->proxy_global_id(i));
}
// Fill indexed proxy id list
for(int i=0;i<nbProxies;i++)
// Deal with existing proxy
for(unsigned int i=0;i<this->GetNumberOfProxies();i++)
{
vtkSMProxy *proxy = this->GetProxy(i);
vtkTypeUInt32 id = proxy->GetGlobalID();
if((proxyIdIter=newProxyIdList.find(id)) == newProxyIdList.end())
{
newProxyIdList.insert(value->proxy_global_id(i));
// Not find => Need to be removed
this->RemoveProxy(proxy, false); // FIXME do we need to tag proxy as modified ?
}
// Deal with existing proxy
for(unsigned int i=0;i<this->GetNumberOfProxies();i++)
else
{
vtkSMProxy *proxy = this->GetProxy(i);
vtkTypeUInt32 id = proxy->GetGlobalID();
if((proxyIdIter=newProxyIdList.find(id)) == newProxyIdList.end())
{
// Not find => Need to be removed
this->RemoveProxy(proxy, false); // FIXME do we need to tag proxy as modified ?
}
else
{
// Already there, no need to add it twice
newProxyIdList.erase(proxyIdIter);
}
// Already there, no need to add it twice
newProxyIdList.erase(proxyIdIter);
}
}
// Managed real new proxy
for(proxyIdIter=newProxyIdList.begin();
proxyIdIter != newProxyIdList.end();
proxyIdIter++)
// Managed real new proxy
for( proxyIdIter=newProxyIdList.begin();
proxyIdIter != newProxyIdList.end();
proxyIdIter++)
{
// Get the proxy from proxy manager
vtkSMProxyManager* pxm = vtkSMProxyManager::GetProxyManager();
vtkSMProxy* proxy = vtkSMProxy::SafeDownCast(
pxm->GetSession()->GetRemoteObject(*proxyIdIter));
if(proxy)
{
// Get the proxy from proxy manager
vtkSMProxyManager* pxm = vtkSMProxyManager::GetProxyManager();
vtkSMProxy* proxy = vtkSMProxy::SafeDownCast(
pxm->GetSession()->GetRemoteObject(*proxyIdIter));
this->AddProxy(proxy, false); // FIXME do we need to tag proxy as modified ?
}
// Found the property, so exit the loop
found = true;
break;
else
{
// Recreate the proxy as it used to be
proxy = vtkSMProxy::SafeDownCast(
pxm->GetSession()->ReNewRemoteObject(*proxyIdIter));
this->AddProxy(proxy, true);
}
}
}
if(!found)
{
cout << "Not found " << this->GetXMLName() << endl;
// FIXME do nothing or throw exception ==================================================================================
}
else
{
this->Modified();
vtkWarningMacro("Invalid offset property");
}
this->Modified();
}
//---------------------------------------------------------------------------
......
......@@ -67,14 +67,9 @@ public:
return result;
}
void FillWithLastState( vtkTypeUInt32 globalId, vtkSMMessage* stateToFill,
bool keepProperties)
void FillWithLastState( vtkTypeUInt32 globalId, vtkSMMessage* stateToFill )
{
stateToFill->CopyFrom(this->StateMap[globalId]);
if(!keepProperties)
{
stateToFill->ClearExtension(ProxyState::property);
}
}
private:
......@@ -430,36 +425,17 @@ vtkIdType vtkSMSession::ReverseConnectToRemote(
//----------------------------------------------------------------------------
// Warning: It is at the responsability at the caller to delete the proxy
// once that one has been registered somewhere. The result can be NULL
// if the RemoteObject can be finf by GetRemoteObject
vtkSMRemoteObject* vtkSMSession::ReNewRemoteObject( vtkTypeUInt32 globalId,
bool withPreviousState )
// if the RemoteObject can be find by GetRemoteObject
vtkSMRemoteObject* vtkSMSession::ReNewRemoteObject( vtkTypeUInt32 globalId )
{
cout << "ReviveRemoteObject: " << globalId << endl;
vtkSMRemoteObject* remoteObject = this->GetRemoteObject(globalId);
if(this->StateManagement && !remoteObject)
{
vtkSMMessage proxyState;
this->Internals->FillWithLastState(globalId, &proxyState, withPreviousState);
this->Internals->FillWithLastState(globalId, &proxyState);
vtkSMProxyManager* pxm = vtkSMProxyManager::GetProxyManager();
remoteObject = pxm->NewProxy(&proxyState);
return remoteObject;
}
return NULL;
}
//----------------------------------------------------------------------------
void vtkSMSession::ResetRemoteObject(vtkTypeUInt32 globalId)
{
cout << "ResetRemoteObject: " << globalId << endl;
vtkSMRemoteObject* remoteObject = this->GetRemoteObject(globalId);
if(this->StateManagement && remoteObject)
{
vtkSMMessage proxyState;
this->Internals->FillWithLastState(globalId, &proxyState, true);
remoteObject->LoadState(&proxyState);
}
else
{
vtkWarningMacro("Try to reset a RemoteObject that does not exist. (id: "
<< globalId << ")");
}
}
......@@ -205,22 +205,7 @@ public:
// - This only work if StateManagement is set to true.
// - It is at the responsability at the caller to delete the proxy
// once that one has been registered somewhere.
// - Bringing back a proxy with its later state can be dangerous if
// that one refere some other Proxy that may not be available yet.
// For that reason, we allow to Reset that RemoteObject to that later
// state later on with the ResetRemoteObject method.
virtual vtkSMRemoteObject* ReNewRemoteObject( vtkTypeUInt32 globalId,
bool withPreviousState);
// Description:
// Reset the values of the RemoteObject to its previously pushed state.
//
// WARNING:
// - This only work if StateManagement is set to true.
// - Bringing back a proxy with its later state can be dangerous if
// that one refere some other Proxy that may not be available yet.
// For that reason, we allow to Reset that RemoteObject to that later
// state later on with the ResetRemoteObject method.
virtual void ResetRemoteObject(vtkTypeUInt32 globalId);
virtual vtkSMRemoteObject* ReNewRemoteObject( vtkTypeUInt32 globalId );
//BTX
protected:
......
......@@ -81,7 +81,11 @@ public:
PMObjectMapType::iterator iter = this->PMObjectMap.find(globalUniqueId);
if (iter != this->PMObjectMap.end())
{
this->PMObjectMap.erase(iter);
if(iter->second)
{
iter->second->Delete();
}
// this->PMObjectMap.erase(iter); // Before weak pointer
}
}
//---------------------------------------------------------------------------
......@@ -143,7 +147,7 @@ public:
}
}
//---------------------------------------------------------------------------
typedef vtkstd::map<vtkTypeUInt32, vtkSmartPointer<vtkPMObject> >
typedef vtkstd::map<vtkTypeUInt32, vtkWeakPointer<vtkPMObject> >
PMObjectMapType;
typedef vtkstd::map<vtkTypeUInt32, vtkWeakPointer<vtkSMRemoteObject> >
RemoteObjectMapType;
......@@ -292,8 +296,8 @@ void vtkSMSessionCore::PushStateInternal(vtkSMMessage* message)
}
// Create the corresponding PM object.
vtkstd::string classname = message->GetExtension(DefinitionHeader::server_class);
vtkSmartPointer<vtkObject> object;
object.TakeReference(vtkInstantiator::CreateInstance(classname.c_str()));
vtkObject* object;
object = vtkInstantiator::CreateInstance(classname.c_str());
if (!object)
{
vtkErrorMacro("Failed to instantiate " << classname.c_str());
......@@ -308,7 +312,7 @@ void vtkSMSessionCore::PushStateInternal(vtkSMMessage* message)
}
obj->SetGlobalID(globalId);
obj->Initialize(this);
this->Internals->PMObjectMap[globalId] = obj;
this->Internals->PMObjectMap[globalId] = obj; // WeakPointer map
LOG (
<< "----------------------------------------------------------------\n"
......
......@@ -88,7 +88,6 @@ void vtkSMUndoStackBuilder::PushToStack()
return; // Only push the whole set when the first begin/end has been reached
}
cout << "====> Push stack " << this->UndoSet->GetNumberOfElements() << endl;
if (this->UndoSet->GetNumberOfElements() > 0 && this->UndoStack)
{
this->UndoStack->Push( (this->Label? this->Label : "Changes"),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment