#ifndef USERATTRIBUTESMANAGER_H #define USERATTRIBUTESMANAGER_H #include #include #include #include #include namespace UserAttributes { class AttributeRequest : public QObject { Q_OBJECT public: struct RequestInfo { struct ParamInfo{ QList mNoRetryErrCodes; //if received err code is not in the list failed will be changed to true bool mNeedsRetry = true; bool mIsPending = false; ParamInfo(const std::function& func, QList errCodes) : mNoRetryErrCodes(errCodes) , requestFunc(func) { Q_ASSERT(!errCodes.isEmpty()); } ParamInfo(const std::function& func) : requestFunc(func) { } void setNeedsRetry(int errCode); void setPending(bool isPending); std::function requestFunc; }; QMap> mParamInfo; //key: params available for this request QMap mChangedTypes; RequestInfo(QMap> pInfo, QMap cTypes) : mParamInfo(pInfo) , mChangedTypes(cTypes) { } }; typedef AttributeRequest::RequestInfo::ParamInfo ParamInfo; typedef QMap> ParamInfoMap; AttributeRequest(const QString& userEmail) : mUserEmail(userEmail), mRequestInfo(QMap>(), QMap()){} virtual void onRequestFinish(mega::MegaApi *api, mega::MegaRequest *request, mega::MegaError *e) = 0; virtual void requestAttribute()= 0; void forceRequestAttribute() const; virtual bool isAttributeReady() const = 0; virtual RequestInfo fillRequestInfo() = 0; bool attributeRequestNeedsRetry(int attribute) const; bool isAttributeRequestPending(int attribute) const; bool isRequestPending() const; const QString& getEmail() const {return mUserEmail;} void requestUserAttribute(int attribute); const RequestInfo& getRequestInfo() const {return mRequestInfo;} void initRequestInfo(){mRequestInfo = fillRequestInfo();} protected: QString mUserEmail; RequestInfo mRequestInfo; }; class UserAttributesManager : public mega::MegaListener { public: static UserAttributesManager& instance() { static UserAttributesManager instance; return instance; } void reset(); template std::shared_ptr requestAttribute(const char* user_email = nullptr) { QString userEmail = QString::fromUtf8(user_email); QString mapKey = getKey(userEmail); auto classType = QString::fromUtf8(AttributeClass::staticMetaObject.className()); auto userRequests = mRequests.values(mapKey); foreach(auto& request, userRequests) { auto requestType = QString::fromUtf8(request->metaObject()->className()); if(requestType == classType) { foreach(auto paramType, request->getRequestInfo().mParamInfo.keys()) { request->requestUserAttribute(paramType); } return std::dynamic_pointer_cast(request); } } auto request = std::make_shared(userEmail); request->initRequestInfo(); mRequests.insert(mapKey, std::static_pointer_cast(request)); request->requestAttribute(); return request; } void updateEmptyAttributesByUser(const char* user_email); private: friend class AttributeRequest; void onRequestFinish(mega::MegaApi *api, mega::MegaRequest *incoming_request, mega::MegaError *e) override; void onUsersUpdate(mega::MegaApi *, mega::MegaUserList *users) override; void forceRequestAttribute(const AttributeRequest*) const; explicit UserAttributesManager(); QString getKey(const QString& userEmail) const; std::unique_ptr mDelegateListener; QMultiMap> mRequests; }; } #endif // USERATTRIBUTESMANAGER_H