22// Created by Syl Morrison on 13/04/2025.
33//
44
5- #ifndef MOSTLYHARMLESS_DATABASEPROPERTYLISTENER_H
6- #define MOSTLYHARMLESS_DATABASEPROPERTYLISTENER_H
5+ #ifndef MOSTLYHARMLESS_DATABASEPROPERTYWATCHER_H
6+ #define MOSTLYHARMLESS_DATABASEPROPERTYWATCHER_H
77#include < mostly_harmless/data/mostlyharmless_DatabaseState.h>
88#include < mostly_harmless/mostlyharmless_Concepts.h>
99#include < mostly_harmless/utils/mostlyharmless_Timer.h>
@@ -16,50 +16,70 @@ namespace mostly_harmless::data {
1616 * @tparam T Any type satisfying DatabaseStorageType
1717 */
1818 template <DatabaseStorageType T>
19- class DatabasePropertyListener final {
19+ class DatabasePropertyWatcher final {
2020 private:
2121 struct Private {};
2222
2323 public:
2424 /* *
2525 * @private
2626 */
27- DatabasePropertyListener (Private, DatabaseState&& databaseState, std::string_view name, int pollFrequencyMs, std::function<void (const T&)>&& callback) : m_databaseState(std::move(databaseState)),
28- m_propertyNameToWatch (name),
29- m_callback(callback) {
30- m_proxyThis = utils::Proxy<DatabasePropertyListener<T>>::create (this );
27+ DatabasePropertyWatcher (Private, DatabaseState&& databaseState, std::string_view name, int pollFrequencyMs, std::function<void (const T&)>&& callback) : m_databaseState(std::move(databaseState)),
28+ m_propertyNameToWatch (name),
29+ m_pollFrequencyMs(pollFrequencyMs),
30+ m_callback(std::move(callback)) {
31+ m_proxyThis = utils::Proxy<DatabasePropertyWatcher<T>>::create (this );
3132 auto proxyCopy = m_proxyThis;
3233 m_timer.action = [this , proxyCopy]() -> void {
3334 if (!proxyCopy->isValid ()) {
3435 return ;
3536 }
3637 timerCallback ();
3738 };
38- m_timer.run (pollFrequencyMs );
39+ m_timer.run (m_pollFrequencyMs );
3940 }
4041
42+ /* *
43+ * Non copyable
44+ */
45+ DatabasePropertyWatcher (const DatabasePropertyWatcher& /* other*/ ) = delete;
46+ /* *
47+ * Non moveable
48+ */
49+ DatabasePropertyWatcher (DatabasePropertyWatcher&& /* other*/ ) noexcept = delete;
50+
4151 /* *
4252 * @private
4353 */
44- ~DatabasePropertyListener () noexcept {
54+ ~DatabasePropertyWatcher () noexcept {
4555 m_proxyThis->null ();
4656 }
4757
4858 /* *
49- * Attempts to create a DatabasePropertyListener for the given property name.
59+ * Non copyable
60+ */
61+ auto operator =(const DatabasePropertyWatcher& /* other*/ ) -> DatabasePropertyWatcher = delete ;
62+
63+ /* *
64+ * Non moveable
65+ */
66+ auto operator =(DatabasePropertyWatcher&& /* other*/ ) noexcept -> DatabasePropertyWatcher = delete ;
67+
68+ /* *
69+ * Attempts to create a DatabasePropertyWatcher for the given property name.
5070 * As sqlite requires database access across different processes to each have their own unique connection, we first call `DatabaseState::duplicate` to create a new connection specifically for this thread.
51- * @param databaseState A const reference to the database connection to duplicate for this PropertyListener .
71+ * @param databaseState A const reference to the database connection to duplicate for this PropertyWatcher .
5272 * @param propertyName The name of the property to watch.
5373 * @param pollFrequencyMs The interval in milliseconds to poll the database for changes at.
5474 * @param callback A lambda to be invoked from a background timer thread on property value change.
55- * @return A DatabasePropertyListener for the given property name if successful, nullopt otherwise.
75+ * @return A DatabasePropertyWatcher for the given property name if successful, nullptr otherwise.
5676 */
57- static auto tryCreate (const DatabaseState& databaseState, std::string_view propertyName, int pollFrequencyMs, std::function<void (const T&)>&& callback) -> std::optional<DatabasePropertyListener > {
77+ static auto tryCreate (const DatabaseState& databaseState, std::string_view propertyName, int pollFrequencyMs, std::function<void (const T&)>&& callback) -> std::unique_ptr<DatabasePropertyWatcher > {
5878 auto databaseCopyOpt = databaseState.duplicate ();
5979 if (!databaseCopyOpt) {
60- return {} ;
80+ return nullptr ;
6181 }
62- return std::make_optional<DatabasePropertyListener <T>>(Private{}, std::move (*databaseCopyOpt), propertyName, pollFrequencyMs, std::move (callback));
82+ return std::make_unique<DatabasePropertyWatcher <T>>(Private{}, std::move (*databaseCopyOpt), propertyName, pollFrequencyMs, std::move (callback));
6383 }
6484
6585
@@ -73,12 +93,7 @@ namespace mostly_harmless::data {
7393 assert (false );
7494 return ;
7595 }
76- auto hasChanged{ false };
77- if (!m_previousValue.has_value ()) {
78- hasChanged = true ;
79- } else {
80- hasChanged = *m_previousValue != *getRes;
81- }
96+ const auto hasChanged = m_previousValue != getRes;
8297 m_previousValue = *getRes;
8398 if (!hasChanged) {
8499 return ;
@@ -88,10 +103,11 @@ namespace mostly_harmless::data {
88103
89104 DatabaseState m_databaseState;
90105 std::string m_propertyNameToWatch;
106+ int m_pollFrequencyMs;
91107 std::function<void (const T&)> m_callback;
92- std::shared_ptr<utils::Proxy<DatabasePropertyListener <T>>> m_proxyThis;
108+ std::shared_ptr<utils::Proxy<DatabasePropertyWatcher <T>>> m_proxyThis;
93109 utils::Timer m_timer;
94110 std::optional<T> m_previousValue{};
95111 };
96112} // namespace mostly_harmless::data
97- #endif // MOSTLYHARMLESS_DATABASEPROPERTYLISTENER_H
113+ #endif // MOSTLYHARMLESS_DATABASEPROPERTYWATCHER_H
0 commit comments