vtkSMCollaborationManager.cxx 15.1 KB
Newer Older
1 2 3
/*=========================================================================

  Program:   ParaView
4
  Module:    vtkSMCollaborationManager.cxx
5 6 7 8 9 10 11 12 13 14

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
15
#include "vtkSMCollaborationManager.h"
16 17

#include "vtkObjectFactory.h"
18
#include "vtkPVMultiClientsInformation.h"
19
#include "vtkPVServerInformation.h"
20 21
#include "vtkProcessModule.h"
#include "vtkReservedRemoteObjectIds.h"
22 23
#include "vtkSMMessage.h"
#include "vtkSMSession.h"
24
#include "vtkSMSessionClient.h"
25

26
#include "vtkSMProxy.h"
27
#include "vtkSMProxyLocator.h"
28

29 30
#include <map>
#include <string>
31
#include <vector>
32 33 34 35 36 37 38

//****************************************************************************
//                              Internal class
//****************************************************************************
class vtkSMCollaborationManager::vtkInternal
{
public:
39
  vtkInternal(vtkSMCollaborationManager* m)
Kitware Robot's avatar
Kitware Robot committed
40
  {
41 42
    this->Manager = m;
    this->ObserverTag = 0;
43
    this->Me = 0;
44
    this->UserToFollow = 0;
45 46
    this->DisableFurtherConnections = false;
    this->ConnectID = 0;
47
    this->Clear();
Kitware Robot's avatar
Kitware Robot committed
48
  }
49 50

  ~vtkInternal()
Kitware Robot's avatar
Kitware Robot committed
51
  {
52
    this->Clear();
Kitware Robot's avatar
Kitware Robot committed
53 54
    if (this->Manager && this->Manager->GetSession() && this->ObserverTag != 0)
    {
55 56 57
      this->Manager->GetSession()->RemoveObserver(this->ObserverTag);
      this->ObserverTag = 0;
    }
Kitware Robot's avatar
Kitware Robot committed
58
  }
59 60

  void Init()
Kitware Robot's avatar
Kitware Robot committed
61
  {
62 63 64
    // Check our current user Id and store it
    this->Me = this->Manager->GetSession()->GetServerInformation()->GetClientId();
    this->ObserverTag =
Kitware Robot's avatar
Kitware Robot committed
65 66 67
      this->Manager->GetSession()->AddObserver(vtkPVSessionBase::ProcessingRemoteEnd, this,
        &vtkSMCollaborationManager::vtkInternal::StopProcessingRemoteNotificationCallback);
  }
68

Kitware Robot's avatar
Kitware Robot committed
69
  const char* GetUserName(int userId) { return this->UserNames[userId].c_str(); }
70 71

  bool UpdateMaster(int newMaster)
Kitware Robot's avatar
Kitware Robot committed
72 73
  {
    if (this->Master != newMaster)
74 75
    {
      this->Master = newMaster;
76 77

      // If no user to follow yet, then we follow master...
Kitware Robot's avatar
Kitware Robot committed
78
      this->UpdateState((this->UserToFollow == 0) ? newMaster : this->UserToFollow);
79
      this->Manager->InvokeEvent(
Kitware Robot's avatar
Kitware Robot committed
80
        (unsigned long)vtkSMCollaborationManager::UpdateMasterUser, (void*)&newMaster);
81 82
      return true;
    }
Kitware Robot's avatar
Kitware Robot committed
83 84
    return false;
  }
85 86

  bool UpdateUserName(int userId, const char* userName)
Kitware Robot's avatar
Kitware Robot committed
87 88
  {
    if (userName)
89
    {
Kitware Robot's avatar
Kitware Robot committed
90
      if (this->UserNames[userId] != userName)
91 92
      {
        this->UserNames[userId] = userName;
93
        this->UpdateState(this->UserToFollow);
94
        this->Manager->InvokeEvent(
Kitware Robot's avatar
Kitware Robot committed
95
          (unsigned long)vtkSMCollaborationManager::UpdateUserName, (void*)&userId);
96 97
        return true;
      }
Kitware Robot's avatar
Kitware Robot committed
98
    }
99
    else
Kitware Robot's avatar
Kitware Robot committed
100
    {
101
      this->UserNames.erase(userId);
102
      this->UpdateState(this->UserToFollow);
103
    }
Kitware Robot's avatar
Kitware Robot committed
104 105
    return false;
  }
106

107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
  bool SetDisableFurtherConnections(bool disable)
  {
    if (disable != this->DisableFurtherConnections)
    {
      this->DisableFurtherConnections = disable;
      this->UpdateState(this->UserToFollow == 0 ? this->Master : this->UserToFollow);
      return true;
    }
    return false;
  }

  bool UpdateConnectID(int connectID)
  {
    if (this->ConnectID != connectID)
    {
      this->ConnectID = connectID;
      this->UpdateState(this->UserToFollow == 0 ? this->Master : this->UserToFollow);
      return true;
    }
    return false;
  }

129
  void Clear()
Kitware Robot's avatar
Kitware Robot committed
130
  {
131 132 133
    this->UserNames.clear();
    this->Users.clear();
    this->Master = 0;
134 135
    this->ConnectID = 0;
    this->DisableFurtherConnections = false;
136
    this->State.Clear();
137
    this->PendingCameraUpdate.Clear();
138
    this->LocalCameraStateCache.clear();
Kitware Robot's avatar
Kitware Robot committed
139
  }
140

141
  void UpdateState(int followCamUserId)
Kitware Robot's avatar
Kitware Robot committed
142
  {
143
    this->UserToFollow = followCamUserId;
144
    this->State.ClearExtension(ClientsInformation::user);
145
    size_t size = this->Users.size();
Kitware Robot's avatar
Kitware Robot committed
146 147 148
    for (size_t i = 0; i < size; ++i)
    {
      ClientsInformation_ClientInfo* user = this->State.AddExtension(ClientsInformation::user);
149 150
      user->set_user(this->Users[i]);
      user->set_name(this->GetUserName(this->Users[i]));
Kitware Robot's avatar
Kitware Robot committed
151 152
      if (this->Users[i] == this->Master)
      {
153
        user->set_is_master(true);
Kitware Robot's avatar
Kitware Robot committed
154 155 156
      }
      if (this->Users[i] == followCamUserId)
      {
157
        user->set_follow_cam(true);
158
      }
159 160
      user->set_disable_further_connections(this->DisableFurtherConnections);
      user->set_connect_id(this->ConnectID);
161
    }
Kitware Robot's avatar
Kitware Robot committed
162
  }
163 164

  bool LoadState(const vtkSMMessage* msg)
Kitware Robot's avatar
Kitware Robot committed
165
  {
166 167 168 169
    int size = msg->ExtensionSize(ClientsInformation::user);
    bool foundChanges = (size != static_cast<int>(this->Users.size()));
    // Update User list first
    this->Users.clear();
Kitware Robot's avatar
Kitware Robot committed
170 171 172
    for (int i = 0; i < size; ++i)
    {
      const ClientsInformation_ClientInfo* user = &msg->GetExtension(ClientsInformation::user, i);
173 174
      int id = user->user();
      this->Users.push_back(id);
Kitware Robot's avatar
Kitware Robot committed
175
    }
176 177

    // Update user name/master info
178
    int newFollow = 0;
Kitware Robot's avatar
Kitware Robot committed
179 180 181
    for (int i = 0; i < size; ++i)
    {
      const ClientsInformation_ClientInfo* user = &msg->GetExtension(ClientsInformation::user, i);
182 183
      int id = user->user();
      foundChanges = this->UpdateUserName(id, user->name().c_str()) || foundChanges;
Kitware Robot's avatar
Kitware Robot committed
184 185
      if (user->is_master())
      {
186
        foundChanges = this->UpdateMaster(id) || foundChanges;
Kitware Robot's avatar
Kitware Robot committed
187
      }
188 189 190
      foundChanges =
        this->SetDisableFurtherConnections(user->disable_further_connections()) || foundChanges;
      foundChanges = this->UpdateConnectID(user->connect_id()) || foundChanges;
191

Kitware Robot's avatar
Kitware Robot committed
192 193
      if (user->follow_cam())
      {
194
        // Invoke event...
195
        newFollow = id;
196
        this->Manager->InvokeEvent(
Kitware Robot's avatar
Kitware Robot committed
197
          (unsigned long)vtkSMCollaborationManager::FollowUserCamera, (void*)&id);
198
      }
Kitware Robot's avatar
Kitware Robot committed
199 200 201
    }
    if (newFollow)
    {
202
      this->UserToFollow = newFollow;
Kitware Robot's avatar
Kitware Robot committed
203
    }
204

205
    return foundChanges || newFollow;
Kitware Robot's avatar
Kitware Robot committed
206
  }
207

208 209 210 211
  // Return the camera update message user origin otherwise
  // if not a camera update message we return -1;
  int StoreCameraByUser(const vtkSMMessage* msg)
  {
Kitware Robot's avatar
Kitware Robot committed
212 213
    if (msg->HasExtension(DefinitionHeader::client_class) &&
      msg->GetExtension(DefinitionHeader::client_class) == "vtkSMCameraProxy")
214
    {
Kitware Robot's avatar
Kitware Robot committed
215 216 217
      int currentUserId = static_cast<int>(msg->client_id());
      this->LocalCameraStateCache[currentUserId].CopyFrom(*msg);
      return currentUserId;
218
    }
Kitware Robot's avatar
Kitware Robot committed
219
    return -1;
220 221 222
  }

  void UpdateCamera(const vtkSMMessage* msg)
Kitware Robot's avatar
Kitware Robot committed
223
  {
224 225 226 227 228 229 230
    vtkTypeUInt32 cameraId = msg->global_id();
    vtkSMProxyLocator* locator = this->Manager->GetSession()->GetProxyLocator();
    vtkSMProxy* proxy = locator->LocateProxy(cameraId);

    // As camera do not synch its properties while IsProcessingRemoteNotification
    // there is no point of updating it when we are in that case.
    // So we just push back that request to later...
Kitware Robot's avatar
Kitware Robot committed
231 232
    if (proxy && !proxy->GetSession()->IsProcessingRemoteNotification())
    {
233 234 235 236 237 238 239 240
      // Update Proxy
      proxy->EnableLocalPushOnly();
      proxy->LoadState(msg, locator);
      proxy->UpdateVTKObjects();
      proxy->DisableLocalPushOnly();

      // Fire event so the Qt layer could trigger a render
      this->Manager->InvokeEvent(vtkSMCollaborationManager::CameraChanged);
Kitware Robot's avatar
Kitware Robot committed
241 242 243
    }
    else if (proxy->GetSession()->IsProcessingRemoteNotification())
    {
244
      this->PendingCameraUpdate.CopyFrom(*msg);
245
    }
Kitware Robot's avatar
Kitware Robot committed
246
  }
247 248

  void StopProcessingRemoteNotificationCallback(vtkObject*, unsigned long, void*)
Kitware Robot's avatar
Kitware Robot committed
249 250
  {
    if (this->PendingCameraUpdate.has_global_id())
251
    {
252 253
      this->UpdateCamera(&this->PendingCameraUpdate);
      this->PendingCameraUpdate.Clear();
254
    }
Kitware Robot's avatar
Kitware Robot committed
255
  }
256

257
  vtkWeakPointer<vtkSMCollaborationManager> Manager;
Kitware Robot's avatar
Kitware Robot committed
258 259 260 261 262
  std::map<int, std::string> UserNames;
  std::vector<int> Users;
  int Me;
  int UserToFollow;
  int Master;
263
  int ConnectID;
Kitware Robot's avatar
Kitware Robot committed
264 265 266 267
  vtkSMMessage State;
  vtkSMMessage PendingCameraUpdate;
  std::map<int, vtkSMMessage> LocalCameraStateCache;
  unsigned long ObserverTag;
268
  bool DisableFurtherConnections;
269 270
};
//****************************************************************************
271
vtkStandardNewMacro(vtkSMCollaborationManager);
272
//----------------------------------------------------------------------------
273
vtkTypeUInt32 vtkSMCollaborationManager::GetReservedGlobalID()
274 275 276 277
{
  return vtkReservedRemoteObjectIds::RESERVED_COLLABORATION_COMMUNICATOR_ID;
}
//----------------------------------------------------------------------------
278
vtkSMCollaborationManager::vtkSMCollaborationManager()
279
{
280
  this->SetLocation(vtkPVSession::DATA_SERVER_ROOT);
281
  this->Internal = new vtkInternal(this);
282
  this->SetGlobalID(vtkSMCollaborationManager::GetReservedGlobalID());
283 284 285
}

//----------------------------------------------------------------------------
286
vtkSMCollaborationManager::~vtkSMCollaborationManager()
287
{
288 289
  delete this->Internal;
  this->Internal = NULL;
290 291 292
}

//----------------------------------------------------------------------------
293
void vtkSMCollaborationManager::PrintSelf(ostream& os, vtkIndent indent)
294 295 296 297
{
  this->Superclass::PrintSelf(os, indent);
}
//---------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
298 299
void vtkSMCollaborationManager::LoadState(
  const vtkSMMessage* msg, vtkSMProxyLocator* vtkNotUsed(locator))
300
{
301 302
  // Check if it's a local state or if it's a state that use the
  // CollaborationManager as communication channel accros clients
Kitware Robot's avatar
Kitware Robot committed
303 304
  if (msg->ExtensionSize(ClientsInformation::user) > 0)
  {
305
    // For me
Kitware Robot's avatar
Kitware Robot committed
306 307
    if (this->Internal->LoadState(msg))
    {
308 309
      this->InvokeEvent(UpdateUserList);
    }
Kitware Robot's avatar
Kitware Robot committed
310
  }
311
  else
Kitware Robot's avatar
Kitware Robot committed
312
  {
313
    // Handle camera synchro
Kitware Robot's avatar
Kitware Robot committed
314 315 316
    if (this->Internal->UserToFollow == this->Internal->StoreCameraByUser(msg) &&
      this->Internal->UserToFollow != -1)
    {
317
      this->Internal->UpdateCamera(msg);
Kitware Robot's avatar
Kitware Robot committed
318
    }
319

320 321 322 323
    // For Observers
    vtkSMMessage* msgCopy = new vtkSMMessage();
    msgCopy->CopyFrom(*msg);
    this->InvokeEvent(CollaborationNotification, msgCopy);
Kitware Robot's avatar
Kitware Robot committed
324
  }
325
}
326

327 328 329 330 331 332 333 334 335 336 337 338 339 340
//----------------------------------------------------------------------------
void vtkSMCollaborationManager::DisableFurtherConnections(bool disable)
{
  this->Internal->SetDisableFurtherConnections(disable);
  this->UpdateUserInformations();
}

//-----------------------------------------------------------------------------
void vtkSMCollaborationManager::SetConnectID(int connectID)
{
  this->Internal->UpdateConnectID(connectID);
  this->UpdateUserInformations();
}

341
//----------------------------------------------------------------------------
342
vtkTypeUInt32 vtkSMCollaborationManager::GetGlobalID()
343
{
Kitware Robot's avatar
Kitware Robot committed
344 345
  if (!this->HasGlobalID())
  {
346
    this->SetGlobalID(vtkSMCollaborationManager::GetReservedGlobalID());
Kitware Robot's avatar
Kitware Robot committed
347
  }
348 349
  return this->Superclass::GetGlobalID();
}
350 351 352 353 354 355

//----------------------------------------------------------------------------
void vtkSMCollaborationManager::SendToOtherClients(vtkSMMessage* msg)
{
  this->PushState(msg);
}
356 357 358
//----------------------------------------------------------------------------
void vtkSMCollaborationManager::PromoteToMaster(int clientId)
{
359 360
  this->Internal->UpdateMaster(clientId);
  this->UpdateUserInformations();
361
}
362
//----------------------------------------------------------------------------
363 364 365 366 367
int vtkSMCollaborationManager::GetFollowedUser()
{
  return this->Internal->UserToFollow;
}
//----------------------------------------------------------------------------
368 369
void vtkSMCollaborationManager::FollowUser(int clientId)
{
Kitware Robot's avatar
Kitware Robot committed
370 371
  if (this->Internal->UserToFollow == clientId)
  {
372
    return;
Kitware Robot's avatar
Kitware Robot committed
373
  }
374

Kitware Robot's avatar
Kitware Robot committed
375 376
  if (this->IsMaster())
  {
377 378
    this->Internal->UpdateState(clientId);
    this->UpdateUserInformations();
Kitware Robot's avatar
Kitware Robot committed
379
  }
380
  else // Follow someone else on my own
Kitware Robot's avatar
Kitware Robot committed
381 382 383
  {
    this->Internal->UserToFollow = clientId;
  }
384

385
  // Update the camera
Kitware Robot's avatar
Kitware Robot committed
386 387 388 389
  if (clientId != -1 &&
    this->Internal->LocalCameraStateCache.find(clientId) !=
      this->Internal->LocalCameraStateCache.end())
  {
390
    this->Internal->UpdateCamera(&this->Internal->LocalCameraStateCache[clientId]);
Kitware Robot's avatar
Kitware Robot committed
391
  }
392
}
393 394 395 396

//----------------------------------------------------------------------------
bool vtkSMCollaborationManager::IsMaster()
{
397
  return (this->Internal->Me == this->Internal->Master);
398 399 400 401 402
}

//----------------------------------------------------------------------------
int vtkSMCollaborationManager::GetMasterId()
{
403 404
  return this->Internal->Master;
}
405 406 407 408 409 410 411

//----------------------------------------------------------------------------
bool vtkSMCollaborationManager::GetDisableFurtherConnections()
{
  return this->Internal->DisableFurtherConnections;
}

412 413 414 415 416 417 418 419 420 421 422
//----------------------------------------------------------------------------
int vtkSMCollaborationManager::GetUserId()
{
  return this->Internal->Me;
}
//----------------------------------------------------------------------------
int vtkSMCollaborationManager::GetUserId(int index)
{
  return this->Internal->Users[index];
}
//----------------------------------------------------------------------------
Sebastien Jourdain's avatar
Sebastien Jourdain committed
423
const char* vtkSMCollaborationManager::GetUserLabel(int userID)
424 425 426 427
{
  return this->Internal->GetUserName(userID);
}
//----------------------------------------------------------------------------
Sebastien Jourdain's avatar
Sebastien Jourdain committed
428
void vtkSMCollaborationManager::SetUserLabel(const char* userName)
429
{
Sebastien Jourdain's avatar
Sebastien Jourdain committed
430
  this->SetUserLabel(this->Internal->Me, userName);
431 432 433
}

//----------------------------------------------------------------------------
Sebastien Jourdain's avatar
Sebastien Jourdain committed
434
void vtkSMCollaborationManager::SetUserLabel(int userId, const char* userName)
435
{
Kitware Robot's avatar
Kitware Robot committed
436 437
  if (this->Internal->UpdateUserName(userId, userName))
  {
438
    this->UpdateUserInformations();
Kitware Robot's avatar
Kitware Robot committed
439
  }
440 441 442
}

//----------------------------------------------------------------------------
443
int vtkSMCollaborationManager::GetNumberOfConnectedClients()
444
{
445
  return static_cast<int>(this->Internal->Users.size());
446 447 448 449 450 451 452 453 454 455
}

//----------------------------------------------------------------------------
const vtkSMMessage* vtkSMCollaborationManager::GetFullState()
{
  this->Internal->State.set_location(vtkPVSession::DATA_SERVER_ROOT);
  this->Internal->State.set_global_id(vtkSMCollaborationManager::GetReservedGlobalID());
  this->Internal->State.SetExtension(DefinitionHeader::client_class, "vtkSMCollaborationManager");
  this->Internal->State.SetExtension(DefinitionHeader::server_class, "vtkSICollaborationManager");

Kitware Robot's avatar
Kitware Robot committed
456
  return &this->Internal->State;
457 458 459 460 461 462 463 464 465
}
//----------------------------------------------------------------------------
void vtkSMCollaborationManager::UpdateUserInformations()
{
  // Make sure to add declaration to state message
  this->GetFullState();
  this->PushState(&this->Internal->State);

  // If we are the only client fetch the data of ourself
Kitware Robot's avatar
Kitware Robot committed
466 467
  if (this->GetNumberOfConnectedClients() == 0)
  {
468 469 470 471
    vtkSMMessage msg;
    msg.CopyFrom(*this->GetFullState());
    this->PullState(&msg);
    this->LoadState(&msg, NULL);
Kitware Robot's avatar
Kitware Robot committed
472
  }
473
}
474 475 476 477 478 479 480 481 482 483 484 485 486 487

//----------------------------------------------------------------------------
int vtkSMCollaborationManager::GetServerConnectID()
{
  return this->Internal->ConnectID;
}

//----------------------------------------------------------------------------
int vtkSMCollaborationManager::GetConnectID()
{
  vtkSMSessionClient* session = vtkSMSessionClient::SafeDownCast(this->GetSession());
  return session ? session->GetConnectID() : -1;
}

488 489 490 491
//----------------------------------------------------------------------------
void vtkSMCollaborationManager::SetSession(vtkSMSession* session)
{
  this->Superclass::SetSession(session);
492
  this->Internal->Init();
493
}