diff --git a/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp b/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp index d934ed81..6581052d 100644 --- a/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp +++ b/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp @@ -385,7 +385,7 @@ bool plNCAgeJoiner::MsgReceive (plMessage * msg) { } else if (unsigned ageVaultId = NetCommGetAge()->ageVaultId) { // Download the age vault - VaultDownload( + VaultDownloadNoCallbacks( L"AgeJoin", ageVaultId, AgeVaultDownloadCallback, diff --git a/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp b/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp index 3ebb2dc0..342897b7 100644 --- a/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp +++ b/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp @@ -318,7 +318,7 @@ static void INetCliAuthSetPlayerRequestCallback ( else { s_needAvatarLoad = true; - VaultDownload( + VaultDownloadNoCallbacks( L"SetActivePlayer", s_player->playerInt, PlayerInitCallback, @@ -374,7 +374,7 @@ static void INetCliAuthLoginSetPlayerRequestCallback ( msg->Send(); } else { - VaultDownload( + VaultDownloadNoCallbacks( L"SetActivePlayer", s_player->playerInt, LoginPlayerInitCallback, diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index bbb4e014..66a91d4b 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -181,8 +181,24 @@ struct VaultDownloadTrans { unsigned vaultId; ENetError result; - VaultDownloadTrans (); - + VaultDownloadTrans() + : callback(), cbParam(), progressCallback(), cbProgressParam(), + nodeCount(), nodesLeft(), vaultId(), result(kNetSuccess) + { + } + + VaultDownloadTrans(const wchar_t* _tag, FVaultDownloadCallback _callback, + void* _cbParam, FVaultProgressCallback _progressCallback, + void* _cbProgressParam, unsigned _vaultId) + : callback(_callback), cbParam(_cbParam), progressCallback(_progressCallback), + cbProgressParam(_cbProgressParam), nodeCount(), nodesLeft(), + vaultId(_vaultId), result(kNetSuccess) + { + StrCopy(tag, _tag, arrsize(tag)); + } + + virtual ~VaultDownloadTrans() { } + static void VaultNodeFetched ( ENetError result, void * param, @@ -196,6 +212,28 @@ struct VaultDownloadTrans { ); }; + +struct VaultDownloadNoCallbacksTrans : VaultDownloadTrans { + VaultDownloadNoCallbacksTrans() + : VaultDownloadTrans() + { + VaultSuppressCallbacks(); + } + + VaultDownloadNoCallbacksTrans(const wchar_t* _tag, FVaultDownloadCallback _callback, + void* _cbParam, FVaultProgressCallback _progressCallback, + void* _cbProgressParam, unsigned _vaultId) + : VaultDownloadTrans(_tag, _callback, _cbParam, _progressCallback, _cbProgressParam, _vaultId) + { + VaultSuppressCallbacks(); + } + + ~VaultDownloadNoCallbacksTrans() + { + VaultEnableCallbacks(); + } +}; + struct VaultAgeInitTrans { FVaultInitAgeCallback callback; void * cbState; @@ -262,6 +300,8 @@ static HASHTABLEDECL( static bool s_processPlayerInbox = false; +static long s_suppressCallbacks = 0; + /***************************************************************************** * * Local functions @@ -303,8 +343,10 @@ static void VaultNodeAddedDownloadCallback(ENetError result, void * param) { VaultProcessUnvisitNote(childLink->node); } - for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->AddedChildNode(parentLink->node, childLink->node); + if (s_suppressCallbacks == 0) { + for (IVaultCallback* cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) + cb->cb->AddedChildNode(parentLink->node, childLink->node); + } } } @@ -377,9 +419,11 @@ static void BuildNodeTree ( parentNode->state->children.Add(childLink); if (notifyNow || childNode->nodeType != 0) { - // We made a new link, so make the callbacks - for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->AddedChildNode(parentNode, childNode); + if (s_suppressCallbacks == 0) { + // We made a new link, so make the callbacks + for (IVaultCallback* cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) + cb->cb->AddedChildNode(parentNode, childNode); + } } else { INotifyAfterDownload* notify = NEWZERO(INotifyAfterDownload)(parentNode->nodeId, childNode->nodeId); @@ -543,6 +587,10 @@ static void ChangedVaultNodeFetched ( RelVaultNodeLink* savedLink = s_nodes.Find(node->nodeId); + // Yeah, we are purposefully allowing this global callback to go out, + // even if callback suppression has been enabled. The intent behind + // that is to suppress spurious callbacks, but node changes are + // probably not spurious. if (savedLink) { for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) cb->cb->ChangedNode(savedLink->node); @@ -638,7 +686,7 @@ static void VaultNodeAdded ( RelVaultNodeLink* parentLink = s_nodes.Find(parentId); RelVaultNodeLink* childLink = s_nodes.Find(childId); - if (childLink->node->nodeType != 0) { + if (childLink->node->nodeType != 0 && s_suppressCallbacks == 0) { for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) cb->cb->AddedChildNode(parentLink->node, childLink->node); } @@ -660,7 +708,7 @@ static void VaultNodeRemoved ( if (!childLink) break; - if (parentLink->node->IsParentOf(childId, 1)) { + if (parentLink->node->IsParentOf(childId, 1) && s_suppressCallbacks == 0) { // We have the relationship, so make the callbacks for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) cb->cb->RemovingChildNode(parentLink->node, childLink->node); @@ -831,11 +879,6 @@ void VaultFindNodeTrans::VaultNodeFound ( * ***/ -//============================================================================ -VaultDownloadTrans::VaultDownloadTrans () { - ASSERT(!nodeCount); // must be alloced with -} - //============================================================================ void VaultDownloadTrans::VaultNodeFetched ( ENetError result, @@ -1047,8 +1090,10 @@ void IRelVaultNode::UnlinkFromRelatives () { next = parents.Next(link); // We have the relationship, so make the callbacks - for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->RemovingChildNode(link->node, this->node); + if (s_suppressCallbacks == 0) { + for (IVaultCallback* cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) + cb->cb->RemovingChildNode(link->node, this->node); + } link->node->state->Unlink(node); } @@ -1478,6 +1523,16 @@ void VaultUnregisterCallback (VaultCallback * cb) { cb->internal = nil; } +//============================================================================ +void VaultSuppressCallbacks() { + AtomicAdd(&s_suppressCallbacks, 1); +} + +//============================================================================ +void VaultEnableCallbacks() { + long prevValue = AtomicAdd(&s_suppressCallbacks, -1); + hsAssert(prevValue > 0, "Hmm... A negative vault callback suppression count?"); +} /***************************************************************************** * @@ -1772,8 +1827,10 @@ void VaultRemoveChildNode ( if (parentLink->node->IsParentOf(childId, 1)) { // We have the relationship, so make the callbacks - for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->RemovingChildNode(parentLink->node, childLink->node); + if (s_suppressCallbacks == 0) { + for (IVaultCallback* cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) + cb->cb->RemovingChildNode(parentLink->node, childLink->node); + } } parentLink->node->state->Unlink(childLink->node); @@ -4945,13 +5002,27 @@ void VaultDownload ( FVaultProgressCallback progressCallback, void * cbProgressParam ) { - VaultDownloadTrans * trans = NEWZERO(VaultDownloadTrans); - StrCopy(trans->tag, tag, arrsize(trans->tag)); - trans->callback = callback; - trans->cbParam = cbParam; - trans->progressCallback = progressCallback; - trans->cbProgressParam = cbProgressParam; - trans->vaultId = vaultId; + VaultDownloadTrans * trans = new VaultDownloadTrans(tag, callback, cbParam, + progressCallback, cbProgressParam, vaultId); + + NetCliAuthVaultFetchNodeRefs( + vaultId, + VaultDownloadTrans::VaultNodeRefsFetched, + trans + ); +} + +//============================================================================ +void VaultDownloadNoCallbacks ( + const wchar tag[], + unsigned vaultId, + FVaultDownloadCallback callback, + void* cbParam, + FVaultProgressCallback progressCallback, + void* cbProgressParam +) { + VaultDownloadNoCallbacksTrans* trans = new VaultDownloadNoCallbacksTrans(tag, callback, + cbParam, progressCallback, cbProgressParam, vaultId); NetCliAuthVaultFetchNodeRefs( vaultId, @@ -5001,6 +5072,8 @@ void VaultDownloadAndWait ( //============================================================================ void VaultCull (unsigned vaultId) { + VaultCallbackSuppressor suppress; + // Remove the node from the global table if (RelVaultNodeLink * link = s_nodes.Find(vaultId)) { LogMsg(kLogDebug, L"Vault: Culling node %u", link->node->nodeId); diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.h b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.h index 39bd0aa0..ba38536f 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.h +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.h @@ -82,6 +82,18 @@ struct VaultCallback { void VaultRegisterCallback (VaultCallback * cb); void VaultUnregisterCallback (VaultCallback * cb); +void VaultSuppressCallbacks(); +void VaultEnableCallbacks(); + +class VaultCallbackSuppressor +{ + VaultCallbackSuppressor(const VaultCallbackSuppressor&) { } + VaultCallbackSuppressor(VaultCallbackSuppressor&&) { } + +public: + VaultCallbackSuppressor() { VaultSuppressCallbacks(); } + ~VaultCallbackSuppressor() { VaultEnableCallbacks(); } +}; /***************************************************************************** * @@ -476,6 +488,14 @@ void VaultDownload ( FVaultProgressCallback progressCallback, void * cbProgressParam ); +void VaultDownloadNoCallbacks( + const wchar tag[], + unsigned vaultId, + FVaultDownloadCallback callback, + void* cbParam, + FVaultProgressCallback progressCallback, + void* cbProgressParam +); void VaultDownloadAndWait ( const wchar tag[], unsigned vaultId,