CloudClient.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file CloudClient.h
  11. /// \brief Queries CloudMemoryServer to download data that other clients have uploaded
  12. ///
  13. #include "NativeFeatureIncludes.h"
  14. #if _RAKNET_SUPPORT_CloudClient==1
  15. #ifndef __CLOUD_CLIENT_H
  16. #define __CLOUD_CLIENT_H
  17. #include "PluginInterface2.h"
  18. #include "CloudCommon.h"
  19. #include "RakMemoryOverride.h"
  20. #include "DS_Hash.h"
  21. namespace RakNet
  22. {
  23. /// Forward declarations
  24. class RakPeerInterface;
  25. class CloudClientCallback;
  26. /// \defgroup CLOUD_GROUP CloudComputing
  27. /// \brief Contains the CloudClient and CloudServer plugins
  28. /// \details The CloudServer plugins operates on requests from the CloudClient plugin. The servers are in a fully connected mesh topology, which the clients are connected to any server. Clients can interact with each other by posting and subscribing to memory updates, without being directly connected or even knowing about each other.
  29. /// \ingroup PLUGINS_GROUP
  30. /// \brief Performs Post() and Get() operations on CloudMemoryServer
  31. /// \details A CloudClient is a computer connected to one or more servers in a cloud configuration. Operations by one CloudClient can be received and subscribed to by other instances of CloudClient, without those clients being connected, even on different servers.
  32. /// \ingroup CLOUD_GROUP
  33. class RAK_DLL_EXPORT CloudClient : public PluginInterface2
  34. {
  35. public:
  36. // GetInstance() and DestroyInstance(instance*)
  37. STATIC_FACTORY_DECLARATIONS(CloudClient)
  38. CloudClient();
  39. virtual ~CloudClient();
  40. /// \brief Set the default callbacks for OnGetReponse(), OnSubscriptionNotification(), and OnSubscriptionDataDeleted()
  41. /// \details Pointers to CloudAllocator and CloudClientCallback can be stored by the system if desired. If a callback is not provided to OnGetReponse(), OnSubscriptionNotification(), OnSubscriptionDataDeleted(), the callback passed here will be used instead.
  42. /// \param[in] _allocator An instance of CloudAllocator
  43. /// \param[in] _callback An instance of CloudClientCallback
  44. virtual void SetDefaultCallbacks(CloudAllocator *_allocator, CloudClientCallback *_callback);
  45. /// \brief Uploads data to the cloud
  46. /// \details Data uploaded to the cloud will be stored by the server sent to, identified by \a systemIdentifier.
  47. /// As long as you are connected to this server, the data will persist. Queries for that data by the Get() operation will
  48. /// return the RakNetGUID and SystemAddress of the uploader, as well as the data itself.
  49. /// Furthermore, if any clients are subscribed to the particular CloudKey passed, those clients will get update notices that the data has changed
  50. /// Passing data with the same \a cloudKey more than once will overwrite the prior value.
  51. /// This call will silently fail if CloudServer::SetMaxUploadBytesPerClient() is exceeded
  52. /// \param[in] cloudKey Identifies the data being uploaded
  53. /// \param[in] data A pointer to data to upload. This pointer does not need to persist past the call
  54. /// \param[in] dataLengthBytes The length in bytes of \a data
  55. /// \param[in] systemIdentifier A remote system running CloudServer that we are already connected to.
  56. virtual void Post(CloudKey *cloudKey, const unsigned char *data, uint32_t dataLengthBytes, RakNetGUID systemIdentifier);
  57. /// \brief Releases one or more data previously uploaded with Post()
  58. /// \details If a remote system has subscribed to one or more of the \a keys uploaded, they will get ID_CLOUD_SUBSCRIPTION_NOTIFICATION notifications containing the last value uploaded before deletions
  59. /// \param[in] cloudKey Identifies the data to release. It is possible to remove uploads from multiple Post() calls at once.
  60. /// \param[in] systemIdentifier A remote system running CloudServer that we are already connected to.
  61. virtual void Release(DataStructures::List<CloudKey> &keys, RakNetGUID systemIdentifier);
  62. /// \brief Gets data from the cloud
  63. /// \details For a given query containing one or more keys, return data that matches those keys.
  64. /// The values will be returned in the ID_CLOUD_GET_RESPONSE packet, which should be passed to OnGetReponse() and will invoke CloudClientCallback::OnGet()
  65. /// CloudQuery::startingRowIndex is used to skip the first n values that would normally be returned..
  66. /// CloudQuery::maxRowsToReturn is used to limit the number of rows returned. The number of rows returned may also be limited by CloudServer::SetMaxBytesPerDownload();
  67. /// CloudQuery::subscribeToResults if set to true, will cause ID_CLOUD_SUBSCRIPTION_NOTIFICATION to be returned to us when any of the keys in the query are updated or are deleted.
  68. /// ID_CLOUD_GET_RESPONSE will be returned even if subscribing to the result list. Only later updates will return ID_CLOUD_SUBSCRIPTION_NOTIFICATION.
  69. /// Calling Get() with CloudQuery::subscribeToResults false, when you are already subscribed, does not remove the subscription. Use Unsubscribe() for this.
  70. /// Resubscribing using the same CloudKey but a different or no \a specificSystems overwrites the subscribed systems for those keys.
  71. /// \param[in] cloudQuery One or more keys, and optional parameters to perform with the Get
  72. /// \param[in] systemIdentifier A remote system running CloudServer that we are already connected to.
  73. /// \param[in] specificSystems It is possible to get or subscribe to updates only for specific uploading CloudClient instances. Pass the desired instances here. The overload that does not have the specificSystems parameter is treated as subscribing to all updates from all clients.
  74. virtual bool Get(CloudQuery *cloudQuery, RakNetGUID systemIdentifier);
  75. virtual bool Get(CloudQuery *cloudQuery, DataStructures::List<RakNetGUID> &specificSystems, RakNetGUID systemIdentifier);
  76. virtual bool Get(CloudQuery *cloudQuery, DataStructures::List<CloudQueryRow*> &specificSystems, RakNetGUID systemIdentifier);
  77. /// \brief Unsubscribe from updates previously subscribed to using Get() with the CloudQuery::subscribeToResults set to true
  78. /// The \a keys and \a specificSystems parameters are logically treated as AND when checking subscriptions on the server
  79. /// The overload that does not take specificSystems unsubscribes to all passed keys, regardless of system
  80. /// You cannot unsubscribe specific systems when previously subscribed to updates from any system. To do this, first Unsubscribe() from all systems, and call Get() with the \a specificSystems parameter explicilty listing the systems you want to subscribe to.
  81. virtual void Unsubscribe(DataStructures::List<CloudKey> &keys, RakNetGUID systemIdentifier);
  82. virtual void Unsubscribe(DataStructures::List<CloudKey> &keys, DataStructures::List<RakNetGUID> &specificSystems, RakNetGUID systemIdentifier);
  83. virtual void Unsubscribe(DataStructures::List<CloudKey> &keys, DataStructures::List<CloudQueryRow*> &specificSystems, RakNetGUID systemIdentifier);
  84. /// \brief Call this when you get ID_CLOUD_GET_RESPONSE
  85. /// If \a callback or \a allocator are 0, the default callbacks passed to SetDefaultCallbacks() are used
  86. /// \param[in] packet Packet structure returned from RakPeerInterface
  87. /// \param[in] _callback Callback to be called from the function containing output parameters. If 0, default is used.
  88. /// \param[in] _allocator Allocator to be used to allocate data. If 0, default is used.
  89. virtual void OnGetReponse(Packet *packet, CloudClientCallback *_callback=0, CloudAllocator *_allocator=0);
  90. /// \brief Call this when you get ID_CLOUD_GET_RESPONSE
  91. /// Different form of OnGetReponse that returns to a structure that you pass, instead of using a callback
  92. /// You are responsible for deallocation with this form
  93. /// If \a allocator is 0, the default callback passed to SetDefaultCallbacks() are used
  94. /// \param[out] cloudQueryResult A pointer to a structure that will be filled out with data
  95. /// \param[in] packet Packet structure returned from RakPeerInterface
  96. /// \param[in] _allocator Allocator to be used to allocate data. If 0, default is used.
  97. virtual void OnGetReponse(CloudQueryResult *cloudQueryResult, Packet *packet, CloudAllocator *_allocator=0);
  98. /// \brief Call this when you get ID_CLOUD_SUBSCRIPTION_NOTIFICATION
  99. /// If \a callback or \a allocator are 0, the default callbacks passed to SetDefaultCallbacks() are used
  100. /// \param[in] packet Packet structure returned from RakPeerInterface
  101. /// \param[in] _callback Callback to be called from the function containing output parameters. If 0, default is used.
  102. /// \param[in] _allocator Allocator to be used to allocate data. If 0, default is used.
  103. virtual void OnSubscriptionNotification(Packet *packet, CloudClientCallback *_callback=0, CloudAllocator *_allocator=0);
  104. /// \brief Call this when you get ID_CLOUD_SUBSCRIPTION_NOTIFICATION
  105. /// Different form of OnSubscriptionNotification that returns to a structure that you pass, instead of using a callback
  106. /// You are responsible for deallocation with this form
  107. /// If \a allocator is 0, the default callback passed to SetDefaultCallbacks() are used
  108. /// \param[out] wasUpdated If true, the row was updated. If false, it was deleted. \a result will contain the last value just before deletion
  109. /// \param[out] row A pointer to a structure that will be filled out with data
  110. /// \param[in] packet Packet structure returned from RakPeerInterface
  111. /// \param[in] _allocator Allocator to be used to allocate data. If 0, default is used.
  112. virtual void OnSubscriptionNotification(bool *wasUpdated, CloudQueryRow *row, Packet *packet, CloudAllocator *_allocator=0);
  113. /// If you never specified an allocator, and used the non-callback form of OnGetReponse(), deallocate cloudQueryResult with this function
  114. virtual void DeallocateWithDefaultAllocator(CloudQueryResult *cloudQueryResult);
  115. /// If you never specified an allocator, and used the non-callback form of OnSubscriptionNotification(), deallocate row with this function
  116. virtual void DeallocateWithDefaultAllocator(CloudQueryRow *row);
  117. protected:
  118. PluginReceiveResult OnReceive(Packet *packet);
  119. CloudClientCallback *callback;
  120. CloudAllocator *allocator;
  121. CloudAllocator unsetDefaultAllocator;
  122. };
  123. /// \ingroup CLOUD_GROUP
  124. /// Parses ID_CLOUD_GET_RESPONSE and ID_CLOUD_SUBSCRIPTION_NOTIFICATION in a convenient callback form
  125. class RAK_DLL_EXPORT CloudClientCallback
  126. {
  127. public:
  128. CloudClientCallback() {}
  129. virtual ~CloudClientCallback() {}
  130. /// \brief Called in response to ID_CLOUD_GET_RESPONSE
  131. /// \param[out] result Contains the original query passed to Get(), and a list of rows returned.
  132. /// \param[out] deallocateRowsAfterReturn CloudQueryResult::rowsReturned will be deallocated after the function returns by default. Set to false to not deallocate these pointers. The pointers are allocated through CloudAllocator.
  133. virtual void OnGet(RakNet::CloudQueryResult *result, bool *deallocateRowsAfterReturn) {(void) result; (void) deallocateRowsAfterReturn;}
  134. /// \brief Called in response to ID_CLOUD_SUBSCRIPTION_NOTIFICATION
  135. /// \param[out] result Contains the row updated
  136. /// \param[out] wasUpdated If true, the row was updated. If false, it was deleted. \a result will contain the last value just before deletion
  137. /// \param[out] deallocateRowAfterReturn \a result will be deallocated after the function returns by default. Set to false to not deallocate these pointers. The pointers are allocated through CloudAllocator.
  138. virtual void OnSubscriptionNotification(RakNet::CloudQueryRow *result, bool wasUpdated, bool *deallocateRowAfterReturn) {(void) result; (void) wasUpdated; (void) deallocateRowAfterReturn;}
  139. };
  140. } // namespace RakNet
  141. #endif
  142. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号