]> git.stg.codes - stg.git/blobdiff - include/stg/user_property.h
Merge remote-tracking branch 'github/master'
[stg.git] / include / stg / user_property.h
index 9ce57c37de127507c169da5b694682e9de8b5d55..3400abd0494f4a19913f42b0d13790f9bd5beb9a 100644 (file)
@@ -4,10 +4,9 @@
 #include "stg/user_ips.h"
 #include "stg/store.h"
 #include "stg/admin.h"
-#include "stg/notifer.h"
+#include "stg/subscriptions.h"
 #include "stg/admin_conf.h"
 #include "stg/logger.h"
-#include "stg/locker.h"
 #include "stg/settings.h"
 #include "stg/scriptexecuter.h"
 #include "stg/common.h"
 
 #include <unistd.h> // access
 
-extern volatile time_t stgTime;
-
 namespace STG
 {
 //-----------------------------------------------------------------------------
-struct UserPropertyBase {
+struct UserPropertyBase
+{
     virtual ~UserPropertyBase() = default;
     virtual std::string ToString() const = 0;
 };
@@ -35,7 +33,8 @@ struct UserPropertyBase {
 using Registry = std::map<std::string, UserPropertyBase*>;
 //-----------------------------------------------------------------------------
 template<typename T>
-class UserProperty : public UserPropertyBase {
+class UserProperty : public UserPropertyBase
+{
     public:
         explicit UserProperty(T& val);
 
@@ -49,11 +48,10 @@ class UserProperty : public UserPropertyBase {
 
         operator const T&() const noexcept { return value; }
 
-        void AddBeforeNotifier(PropertyNotifierBase<T>* n);
-        void DelBeforeNotifier(const PropertyNotifierBase<T>* n);
-
-        void AddAfterNotifier(PropertyNotifierBase<T>* n);
-        void DelAfterNotifier(const PropertyNotifierBase<T>* n);
+        template <typename F>
+        auto beforeChange(F&& f) { return m_beforeCallbacks.add(std::forward<F>(f)); }
+        template <typename F>
+        auto afterChange(F&& f) { return m_afterCallbacks.add(std::forward<F>(f)); }
 
         time_t ModificationTime() const noexcept { return modificationTime; }
         void   ModifyTime() noexcept;
@@ -62,13 +60,14 @@ class UserProperty : public UserPropertyBase {
     private:
         T& value;
         time_t modificationTime;
-        std::set<PropertyNotifierBase<T>*> beforeNotifiers;
-        std::set<PropertyNotifierBase<T>*> afterNotifiers;
+        Subscriptions<T, T> m_beforeCallbacks;
+        Subscriptions<T, T> m_afterCallbacks;
         std::mutex mutex;
 };
 //-----------------------------------------------------------------------------
 template<typename T>
-class UserPropertyLogged: public UserProperty<T> {
+class UserPropertyLogged: public UserProperty<T>
+{
     public:
         UserPropertyLogged(T& val,
                            const std::string& n,
@@ -112,7 +111,8 @@ class UserPropertyLogged: public UserProperty<T> {
         const Settings& settings;
 };
 //-----------------------------------------------------------------------------
-class UserProperties {
+class UserProperties
+{
     /*
      В этом месте важен порядок следования приватной и открытой частей.
      Это связано с тем, что часть которая находится в публичной секции
@@ -186,9 +186,7 @@ template <typename T>
 inline
 UserProperty<T>::UserProperty(T& val)
     : value(val),
-      modificationTime(stgTime),
-      beforeNotifiers(),
-      afterNotifiers()
+      modificationTime(time(NULL))
 {
 }
 //-----------------------------------------------------------------------------
@@ -196,27 +194,23 @@ template <typename T>
 inline
 void UserProperty<T>::ModifyTime() noexcept
 {
-    modificationTime = stgTime;
+    modificationTime = time(NULL);
 }
 //-----------------------------------------------------------------------------
 template <typename T>
 inline
-void UserProperty<T>::Set(const T& rvalue)
+void UserProperty<T>::Set(const T& rhs)
 {
     std::lock_guard<std::mutex> lock(mutex);
 
     T oldVal = value;
 
-    auto ni = beforeNotifiers.begin();
-    while (ni != beforeNotifiers.end())
-        (*ni++)->Notify(oldVal, rvalue);
+    m_beforeCallbacks.notify(oldVal, rhs);
 
-    value = rvalue;
-    modificationTime = stgTime;
+    value = rhs;
+    modificationTime = time(NULL);
 
-    ni = afterNotifiers.begin();
-    while (ni != afterNotifiers.end())
-        (*ni++)->Notify(oldVal, rvalue);
+    m_afterCallbacks.notify(oldVal, rhs);
 }
 //-----------------------------------------------------------------------------
 template <typename T>
@@ -227,38 +221,6 @@ UserProperty<T>& UserProperty<T>::operator=(const T& newValue)
     return *this;
 }
 //-----------------------------------------------------------------------------
-template <typename T>
-inline
-void UserProperty<T>::AddBeforeNotifier(PropertyNotifierBase<T>* n)
-{
-    std::lock_guard<std::mutex> lock(mutex);
-    beforeNotifiers.insert(n);
-}
-//-----------------------------------------------------------------------------
-template <typename T>
-inline
-void UserProperty<T>::DelBeforeNotifier(const PropertyNotifierBase<T>* n)
-{
-    std::lock_guard<std::mutex> lock(mutex);
-    beforeNotifiers.erase(const_cast<PropertyNotifierBase<T>*>(n));
-}
-//-----------------------------------------------------------------------------
-template <typename T>
-inline
-void UserProperty<T>::AddAfterNotifier(PropertyNotifierBase<T>* n)
-{
-    std::lock_guard<std::mutex> lock(mutex);
-    afterNotifiers.insert(n);
-}
-//-----------------------------------------------------------------------------
-template <typename T>
-inline
-void UserProperty<T>::DelAfterNotifier(const PropertyNotifierBase<T>* n)
-{
-    std::lock_guard<std::mutex> lock(mutex);
-    afterNotifiers.erase(const_cast<PropertyNotifierBase<T>*>(n));
-}
-//-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 template <typename T>
@@ -288,12 +250,12 @@ bool UserPropertyLogged<T>::Set(const T& val,
                                 const Store& store,
                                 const std::string& msg)
 {
-    const auto priv = admin.GetPriv();
+    const auto& priv = admin.priv();
 
-    if ((priv->userConf && !isStat) ||
-        (priv->userStat && isStat) ||
-        (priv->userPasswd && isPassword) ||
-        (priv->userCash && name == "cash"))
+    if ((priv.userConf && !isStat) ||
+        (priv.userStat && isStat) ||
+        (priv.userPasswd && isPassword) ||
+        (priv.userCash && name == "cash"))
     {
         std::stringstream oldVal;
         std::stringstream newVal;
@@ -326,7 +288,7 @@ void UserPropertyLogged<T>::WriteAccessDenied(const std::string& login,
                                               const std::string& parameter)
 {
     stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
-              admin.GetLogStr().c_str(), login.c_str(), parameter.c_str());
+              admin.logStr().c_str(), login.c_str(), parameter.c_str());
 }
 //-------------------------------------------------------------------------
 template <typename T>
@@ -340,7 +302,7 @@ void UserPropertyLogged<T>::WriteSuccessChange(const std::string& login,
                                                const Store& store)
 {
     stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
-              admin.GetLogStr().c_str(),
+              admin.logStr().c_str(),
               login.c_str(),
               parameter.c_str(),
               oldValue.c_str(),
@@ -350,7 +312,7 @@ void UserPropertyLogged<T>::WriteSuccessChange(const std::string& login,
     for (size_t i = 0; i < settings.GetFilterParamsLog().size(); ++i)
         if (settings.GetFilterParamsLog()[i] == "*" || strcasecmp(settings.GetFilterParamsLog()[i].c_str(), parameter.c_str()) == 0)
         {
-            store.WriteUserChgLog(login, admin.GetLogin(), admin.GetIP(), parameter, oldValue, newValue, msg);
+            store.WriteUserChgLog(login, admin.login(), admin.IP(), parameter, oldValue, newValue, msg);
             return;
         }
 }
@@ -366,7 +328,7 @@ void UserPropertyLogged<T>::OnChange(const std::string& login,
 
     if (access(filePath.c_str(), X_OK) == 0)
     {
-        const auto execString = "\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin.GetLogin() + "\" \"" + admin.GetIPStr() + "\"";
+        const auto execString = "\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin.login() + "\" \"" + admin.IPStr() + "\"";
         ScriptExec(execString.c_str());
     }
     else