From cf7a3d1f2f5cb6f66cb24717b0254f2b5595aabb Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Sat, 20 Feb 2016 14:48:15 +0100 Subject: [PATCH] [DOC] add basic comment on all class --- esignal/Base.h | 28 ++++---- esignal/Connection.h | 32 ++++++---- esignal/ISignal.h | 17 +++-- esignal/LockSharedPtrRef.h | 56 ++++++++++++---- esignal/RefCount.h | 31 ++++++--- esignal/Signal.h | 128 ++++++++++++++++++++++++------------- 6 files changed, 192 insertions(+), 100 deletions(-) diff --git a/esignal/Base.h b/esignal/Base.h index b926753..95d670e 100644 --- a/esignal/Base.h +++ b/esignal/Base.h @@ -18,29 +18,33 @@ #include namespace esignal { - #undef __class__ - #define __class__ "Signal" class Base { protected: - LockSharedPtrRef m_shared; - static size_t s_uid; + LockSharedPtrRef m_shared; //!< Reference counter on itself. + static size_t s_uid; //!< blobal id of the signal (STATIC) public: + //! @brief Basic constructor: Base(); - // copy constructor: + //! @brief Copy constructor: Base(const Base&) = delete; - // copy operator: - //Base& operator=(Base) = delete; - //Base& operator=(const Base& _obj) = delete; - // Move constructor + //! @brief Move constructor Base(Base&& _obj) = delete; - // Move operator - //Base& operator=(Base&& _obj) = delete; virtual ~Base(); + /** + * @brief get name of the signal + */ virtual void disconnect(const std::shared_ptr& _obj); virtual void disconnect(std::size_t _uid) = 0; - + /** + * @brief Get name of the signal. + * @return requested name. + */ virtual const std::string& getName() const; + /** + * @brief Get decription of the signal. + * @return requested decription. + */ virtual const std::string& getDescription() const; }; std::ostream& operator <<(std::ostream& _os, const esignal::Base& _obj); diff --git a/esignal/Connection.h b/esignal/Connection.h index 9806886..6cf743e 100644 --- a/esignal/Connection.h +++ b/esignal/Connection.h @@ -17,23 +17,29 @@ #include namespace esignal { - + /** + * @brief connection on the signal (disconnect it whe removed) + */ class Connection { public: + //! @brief Constructor (no link) Connection(): m_signalRefUnique(), m_uid(0) { } + //! @brief Constructor (link) Connection(const LockSharedPtrRef& _ref, std::size_t _id): m_signalRefUnique(_ref), m_uid(_id) { } + //! @brief Move Constructor Connection(Connection&& _obj): m_signalRefUnique(_obj.m_signalRefUnique), m_uid(_obj.m_uid) { _obj.m_uid = 0; } + //! @brief Move operator. Connection& operator=(Connection&& _obj) { disconnect(); m_signalRefUnique = _obj.m_signalRefUnique; @@ -41,29 +47,31 @@ namespace esignal { _obj.m_uid = 0; return *this; } - Connection(const Connection&) = delete; // not copyable - Connection& operator=(const Connection&) = delete; // no copy operator - /* - void set(Connection&& _obj) { - disconnect(); - std::swap(m_signalRefUnique, _obj.m_signalRefUnique); - std::swap(m_uid,_obj.m_uid); - } - */ + //! @brief Copy constructor (REMOVED) + Connection(const Connection&) = delete; + //! @brief Copy operator (REMOVED) + Connection& operator=(const Connection&) = delete; + //! @brief Destructor. ~Connection() { m_signalRefUnique.disconnect(m_uid); m_uid = 0; } + //! @brief Disconnect the signal. void disconnect() { m_signalRefUnique.disconnect(m_uid); m_uid = 0; } + /** + * @brief Check if the connection is alive or signal removed + * @return true The signal is connected. + * @return false The signal is NOT connected. + */ bool isConnected() { return m_signalRefUnique.isAlive(); } private: - LockSharedPtrRef m_signalRefUnique; - std::size_t m_uid; + LockSharedPtrRef m_signalRefUnique; //!< reference on the Signal. + std::size_t m_uid; //!< UID of the current connection. }; } diff --git a/esignal/ISignal.h b/esignal/ISignal.h index 0285771..00d86e7 100644 --- a/esignal/ISignal.h +++ b/esignal/ISignal.h @@ -15,14 +15,15 @@ #include namespace esignal { - #undef __class__ - #define __class__ "ISignal" + /** + * @brief Sigla same as @ref esignal::Signal withe a name and a description to manage a list of signals. + */ template class ISignal : public Signal { protected: - esignal::Interface& m_signalInterfaceLink; - std::string m_name; - std::string m_description; + esignal::Interface& m_signalInterfaceLink; //!< interface of the signal manager. + std::string m_name; //!< name of the signal. + std::string m_description; //!< description of the signal. public: /** * @brief Create a signal with a specific type. @@ -45,14 +46,12 @@ namespace esignal { virtual ~ISignal() { m_signalInterfaceLink.signalRemove(this); } - const std::string& getName() const { + virtual const std::string& getName() const { return m_name; } - const std::string& getDescription() const { + virtual const std::string& getDescription() const { return m_description; } }; - #undef __class__ - #define __class__ nullptr } diff --git a/esignal/LockSharedPtrRef.h b/esignal/LockSharedPtrRef.h index 9d8f6dc..f3dc5c2 100644 --- a/esignal/LockSharedPtrRef.h +++ b/esignal/LockSharedPtrRef.h @@ -19,12 +19,20 @@ namespace esignal { extern size_t s_uid; - + /** + * @brief shared ptr that permeit to lock access of the internal data (it does not manage the allication and remove of the data). + * @todo Change this with atomic_shared_ptr<> when availlable. + * @input[in] TYPE Type of the internal data + */ template class LockSharedPtrRef { public: - RefCount* m_counter; + RefCount* m_counter; //!< Access on the reference counter public: + /** + * @brief Basic contructor (with the object to ref count) + * @param[in] _pointer Pointer on the data (default nullptr) + */ LockSharedPtrRef(TYPE* _pointer=nullptr) : m_counter(nullptr) { if (_pointer != nullptr) { @@ -32,7 +40,10 @@ namespace esignal { m_counter->inc(); } } - // copy constructor: + /** + * @brief Copy contructor + * @param[in] _obj object to copy + */ LockSharedPtrRef(const LockSharedPtrRef& _obj) : m_counter(_obj.m_counter) { if (m_counter == nullptr) { @@ -40,8 +51,11 @@ namespace esignal { } m_counter->inc(); } - // copy operator: - //LockSharedPtrRef& operator=(LockSharedPtrRef) = delete; + /** + * @brief Copy operator (It copy the counter and increment the it). + * @param[in] _obj objetc to copy. + * @return Reference of this + */ LockSharedPtrRef& operator=(const LockSharedPtrRef& _obj) { if (&_obj == this) { return *this; @@ -57,19 +71,21 @@ namespace esignal { m_counter->inc(); return *this; } - // Move constructor + /** + * @brief Contructor (move) + * @param[in] _obj move object + */ LockSharedPtrRef(LockSharedPtrRef&& _obj) : m_counter(std::move(_obj.m_counter)) { } - // Move operator - #if 1 - LockSharedPtrRef& operator=(LockSharedPtrRef&& _obj) = delete; - #else - LockSharedPtrRef& operator=(LockSharedPtrRef&& _obj) { - m_counter = std::move(_obj.m_counter); - } - #endif + /** + * @brief Copy operator (force move) ==> removed + */ + LockSharedPtrRef& operator=(LockSharedPtrRef&& _obj) = delete; + /** + * @brief Destructor of the class (decrement the counter and remove it if it is the last one...) + */ ~LockSharedPtrRef() { if (m_counter == nullptr) { return; @@ -81,11 +97,18 @@ namespace esignal { delete m_counter; m_counter = nullptr; } + /** + * @brief Remove the data on the conter reference (it does not exist anymore) + */ void removeData() { if (m_counter != nullptr) { m_counter->remove(); } } + /** + * @brief Call disconnect on the parameter class with lock prevention + * @param[in] _uid ID to dicsonnect on the sub element + */ void disconnect(std::size_t _uid) { if (m_counter == nullptr) { return; @@ -97,6 +120,11 @@ namespace esignal { } m_counter->unlock(); } + /** + * @brief Check if the value is availlable + * @return true The data is availlable + * @return false The data has been removed + */ bool isAlive() { return m_counter != nullptr; } diff --git a/esignal/RefCount.h b/esignal/RefCount.h index 1abe675..fe4b86b 100644 --- a/esignal/RefCount.h +++ b/esignal/RefCount.h @@ -15,44 +15,52 @@ #include namespace esignal { - + /** + * @brief Ref counting tool. + */ template class RefCount { + private: + std::mutex m_lock; //!< mutex on the refcounting element + int64_t m_count; //!< number of element connected + TYPE* m_data; //!< Pointer on the refconting data public: - std::mutex m_lock; - int64_t m_count; - TYPE* m_data; - public: + //!< generic constructor RefCount(TYPE* _data) : m_count(0), m_data(_data) { // nothing to do. } - // copy constructor: + //! @brief Copy constructor (REMOVED) RefCount(const RefCount&) = delete; - // copy operator: + //! @brief Copy operator (REMOVED) RefCount& operator=(RefCount) = delete; + //! @previous RefCount& operator=(const RefCount& _obj) = delete; - // Move constructor + //! @brief Move constructor (REMOVED) RefCount(RefCount&& _obj) = delete; - // Move operator + //! @brief Move operator (REMOVED) RefCount& operator=(RefCount&& _obj) = delete; - public: + //! @brief Destructor ~RefCount() { m_data = nullptr; } public: + //!< @brief Lock the interface void lock() { m_lock.lock(); } + //!< @brief Unlock the interface void unlock() { m_lock.unlock(); } + //!< @brief Increment the ref-counting void inc() { lock(); m_count++; unlock(); } + //!< @brief Decrement the ref-counting int64_t dec() { int64_t val; lock(); @@ -61,14 +69,17 @@ namespace esignal { unlock(); return val; } + //!< @brief Get number of connected int64_t getCount() const { return m_count; } + //!< @brief Remove the data void remove() { lock(); m_data = nullptr; unlock(); } + //!< @brief Get the recoreded data TYPE* get() { return m_data; } diff --git a/esignal/Signal.h b/esignal/Signal.h index a5f7837..d84f5e0 100644 --- a/esignal/Signal.h +++ b/esignal/Signal.h @@ -20,44 +20,58 @@ #include namespace esignal { - - #undef __class__ - #define __class__ "Signal" + /** + * @brief Basic signal base + * @param[in] Args... Argument of the signal + */ template class Signal : public esignal::Base { public: - using Observer = std::function; - int32_t m_callInProgress; + using Observer = std::function; //!< Define an Observer: function pointer + protected: + int32_t m_callInProgress; //!< know if we are in a recursive loop public: - Signal() : + //! @brief Basic constructor + Signal(): m_callInProgress(0) { } - // copy constructor: + //! @brief Copy constructor (REMOVED) Signal(const Signal&) = delete; - // copy operator: + //! @brief Copy operator (REMOVED) Signal& operator=(Signal) = delete; Signal& operator=(const Signal& _obj) = delete; - // Move constructor + //! @brief Move constructor (REMOVED) Signal(Signal&& _obj) = delete; - // Move operator + //! @brief Move operator Signal& operator=(Signal&& _obj) = delete; private: + /** + * @brief Executor: Class to manage the UID and basic value of an observer + */ class Executor { public: - Observer m_observer; - bool m_removed; - size_t m_uid; + Observer m_observer; //!< Observer to call when needed (if not removed). + bool m_removed; //!< the executor has been removed. + size_t m_uid; //!< unique ID of the signal (used to remove it). public: + /** + * @brief Basic constructor. + * @param[in] _observer Observer to call. + */ Executor(Observer&& _observer): m_removed(false), m_uid(0) { m_uid = s_uid++; m_observer = std::move(_observer); } - + //! @brief virtual destructor. virtual ~Executor() = default; public: + /** + * @brief Emit the data on the observer. + * @param[in] _values... Multiple value needed to send on observers + */ virtual void emit(Args... _values) { if (m_removed == true) { return; @@ -71,19 +85,33 @@ namespace esignal { } }; protected: - std::vector> m_executors; + std::vector> m_executors; //!< List of all executors. private: + /** + * @brief Executor specific to the Shared_ptr caller that does not want to worry about the removing of the signal. + * @param[in] Args... Argument of the signal + */ class ExecutorShared : public Executor { protected: - std::weak_ptr m_object; + std::weak_ptr m_object; //!< a weak reference on the object to verify that it is alive public: + /** + * @brief shared constructor. + * @param[in] _object A weak reference of the object. + * @param[in] _observer Observer to call. + */ ExecutorShared(std::weak_ptr _object, Observer&& _observer) : Executor(std::move(_observer)), m_object(_object) { } public: + /** + * @brief Emit the data on the observer. + * @param[in] _values... Multiple value needed to send on observers + */ virtual void emit(Args... _values) { + // TODO: maybe an error if the object is not manage by the same thread. std::shared_ptr destObject = m_object.lock(); if (destObject == nullptr) { Executor::m_removed = true; @@ -101,6 +129,10 @@ namespace esignal { } }; public: + /** + * @brief Connect an observer on the signal. + * @param[in] _observer Observer to call. + */ template< class ObserverType > Connection connect(ObserverType&& _observer ) { std::unique_ptr executer(new Executor(std::forward(_observer))); @@ -108,25 +140,27 @@ namespace esignal { m_executors.push_back(std::move(executer)); return Connection(Base::m_shared, uid); } + /** + * @brief Connect an function member on the signal. + * @param[in] _class Object on whe we need to call. + * @param[in] _func Function to call. + * @param[in] _arg Argument optinnal the user want to add. + */ template - Connection connect(classType* _class, Func _f, Arg... _arg) { + Connection connect(classType* _class, Func _func, Arg... _arg) { std::unique_ptr executer(new Executor([=]( auto&&... cargs ){ - (*_class.*_f)(cargs..., _arg... ); + (*_class.*_func)(cargs..., _arg... ); })); std::size_t uid = executer->m_uid; m_executors.push_back(std::move(executer)); return Connection(Base::m_shared, uid); } - /* - template - void connect(const std::shared_ptr& _class, Func _f, Arg... _arg) { - classType* tmp = _class.get(); - std::unique_ptr executer(new ExecutorShared(_class, [=]( auto&&... cargs ){ - (*tmp.*_f)(cargs..., _arg... ); - })); - m_executors.push_back(std::move(executer)); - } - */ + /** + * @brief Connect an function member on the signal with the shared_ptr object. + * @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr. + * @param[in] _func Function to call. + * @param[in] _arg Argument optinnal the user want to add. + */ template void connect(const std::shared_ptr& _class, void (TYPE::*_func)(const Args&..., Arg...), Arg... _args) { std::shared_ptr obj2 = std::dynamic_pointer_cast(_class); @@ -141,21 +175,17 @@ namespace esignal { })); m_executors.push_back(std::move(executer)); } - /* - template - void bind(const std::shared_ptr& _class, Func _f, const Arg&... _arg) { - std::unique_ptr executer(new ExecutorShared(_class, [=]( auto&&... cargs ){ - (*_class.*_f)(cargs..., _arg... ); - })); - m_executors.push_back(std::move(executer)); - } - */ public: + /** + * @brief Emit data on the signal. + * @param[in] _args Argument data to emit. + */ template< class... CallArgs> - void emit( CallArgs&&... args) { + void emit(CallArgs&&... _args) { + // TODO : Add protection ... but how ... m_callInProgress++; for (size_t iii=0; iii < m_executors.size(); ++iii) { - m_executors[iii]->emit(args...); + m_executors[iii]->emit(_args...); } if (m_callInProgress == 1) { auto it = m_executors.begin(); @@ -170,6 +200,10 @@ namespace esignal { } m_callInProgress--; } + /** + * @brief Disconnect an observer of the signal. + * @param[in] _uid Unique id of the signal. + */ void disconnect(std::size_t _uid) { for (size_t iii=0; iii < m_executors.size(); ++iii) { if (m_executors[iii]->m_uid == _uid) { @@ -179,20 +213,28 @@ namespace esignal { } } public: + /** + * @brief Get the number of observers connected on the signal. + * @return The count of observer. + */ size_t size() const { return m_executors.size(); } - + /** + * @brief Check if we have a connected observers. + * @return true More than one observers. + * @return false No observers. + */ bool empty() const { return m_executors.empty(); } - + /** + * @brief Clear all connectd observers. + */ void clear() { m_executors.clear(); } }; - #undef __class__ - #define __class__ nullptr }