[DOC] compleate function documentation and change API for interface

This commit is contained in:
Edouard DUPIN 2016-04-04 23:22:34 +02:00
parent 47ad66bc89
commit c3c833632b
16 changed files with 154 additions and 71 deletions

43
doc/mainpage.md Normal file
View File

@ -0,0 +1,43 @@
ESIGNAL library {#mainpage}
===============
What is ESIGNAL, and how can I use it?
----------------------------------
ESIGNAL, or Ewol signal engine is a simple messaging layer, managing multiple connection and manage disconnection
ESIGNAL is designed for
- Expose signal
- Emit synchronous signal (not send through an event loop but directly)
- Manage versatil connection/disconnection
What languages are supported?
-----------------------------
ESIGNAL is written in C++.
Are there any licensing restrictions?
-------------------------------------
ESIGNAL is **FREE software** and _all sub-library are FREE and staticly linkable !!!_
License (APACHE-2.0)
--------------------
Copyright esignal Edouard DUPIN
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
<http://www.apache.org/licenses/LICENSE-2.0>
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -10,9 +10,13 @@ def create(target, module_name):
my_module.set_title("esignal: Ewol signal interface")
my_module.set_website("http://atria-soft.github.io/" + module_name)
my_module.set_website_sources("http://github.com/atria-soft/" + module_name)
my_module.set_path(os.path.join(tools.get_current_path(__file__), module_name))
my_module.add_path([
module_name,
"doc"
])
my_module.add_module_depend([
'etk'
'etk',
'ememory'
])
return my_module

View File

@ -18,6 +18,9 @@
#include <esignal/LockSharedPtrRef.h>
namespace esignal {
/**
* @brief Base signal interface for esignal::Signal (permit to create abstract list of signals...)
*/
class Base {
public:
using ObserverConnection = std::function<void(size_t)>; //!< Define an Observer of the number of observer
@ -25,7 +28,7 @@ namespace esignal {
esignal::LockSharedPtrRef<esignal::Base> m_shared; //!< Reference counter on itself.
static size_t s_uid; //!< global id of the signal (STATIC)
static int64_t s_uidSignalEmit; //!< global id to emit counting
ObserverConnection m_connectionObserver;
ObserverConnection m_connectionObserver; //!< propriétéry of the connection handle basic
public:
//! @brief Basic constructor:
Base(ObserverConnection _countObs = nullptr);
@ -36,10 +39,15 @@ namespace esignal {
virtual ~Base();
/**
* @brief get name of the signal
* @brief Disconnect the shared_ptr form the Signal
* @param[in] _obj Link with the object to check
*/
virtual void disconnectShared(const std::shared_ptr<void>& _obj) = 0;
virtual void disconnect(std::size_t _uid) = 0;
/**
* @brief Disconnect an observer of the signal.
* @param[in] _uid Unique id of the signal connection.
*/
virtual void disconnect(size_t _uid) = 0;
/**
* @brief Get name of the signal.
* @return requested name.
@ -51,6 +59,7 @@ namespace esignal {
*/
virtual const std::string& getDescription() const;
};
//! @not_in_doc
std::ostream& operator <<(std::ostream& _os, const esignal::Base& _obj);
#ifdef DEBUG
const char* logIndent(int32_t _iii);

View File

@ -13,7 +13,7 @@ esignal::Connection::Connection():
}
esignal::Connection::Connection(const esignal::LockSharedPtrRef<esignal::Base>& _ref, std::size_t _id):
esignal::Connection::Connection(const esignal::LockSharedPtrRef<esignal::Base>& _ref, size_t _id):
m_signalRefUnique(_ref),
m_uid(_id) {

View File

@ -25,7 +25,7 @@ namespace esignal {
//! @brief Constructor (no link)
Connection();
//! @brief Constructor (link)
Connection(const esignal::LockSharedPtrRef<esignal::Base>& _ref, std::size_t _id);
Connection(const esignal::LockSharedPtrRef<esignal::Base>& _ref, size_t _id);
//! @brief Move Constructor
Connection(Connection&& _obj);
//! @brief Move operator.
@ -46,7 +46,7 @@ namespace esignal {
bool isConnected();
private:
esignal::LockSharedPtrRef<esignal::Base> m_signalRefUnique; //!< reference on the Signal.
std::size_t m_uid; //!< UID of the current connection.
size_t m_uid; //!< UID of the current connection.
};
}

View File

@ -31,7 +31,7 @@ namespace esignal {
/**
* @brief Create a signal with a specific type.
* @param[in] _signalInterfaceLink reference on the signal lister.
* @param[in] _countObs (optionnal) Local observer to know the count of connection on the signal.
* @param[in] _func Local observer to know the count of connection on the signal.
* @param[in] _name Static name of the signal.
* @param[in] _description Description of the signal.
*/
@ -40,6 +40,12 @@ namespace esignal {
FUNC_TYPE _func,
const std::string& _name,
const std::string& _description);
/**
* @brief Create a signal with a specific type.
* @param[in] _signalInterfaceLink reference on the signal lister.
* @param[in] _name Static name of the signal.
* @param[in] _description Description of the signal.
*/
ISignal(esignal::Interface* _signalInterfaceLink,
const std::string& _name,
const std::string& _description);
@ -47,8 +53,8 @@ namespace esignal {
* @brief Destructor.
*/
virtual ~ISignal();
virtual const std::string& getName() const;
virtual const std::string& getDescription() const;
const std::string& getName() const override;
const std::string& getDescription() const override;
};
}
@ -64,7 +70,7 @@ esignal::ISignal<T_ARGS...>::ISignal(CLASS_TYPE* _class,
m_description(_description) {
// add a reference on the current signal ...
if (m_signalInterfaceLink != nullptr) {
m_signalInterfaceLink->signalAdd(this);
m_signalInterfaceLink->signal.add(this);
}
}

View File

@ -11,16 +11,16 @@
#include <esignal/Interface.h>
#include <esignal/Base.h>
esignal::Interface::Interface() {
esignal::InterfaceData::InterfaceData() {
}
esignal::Interface::~Interface() {
esignal::InterfaceData::~InterfaceData() {
m_list.clear();
}
// note this pointer is not allocated and not free at the end of the class
void esignal::Interface::signalAdd(esignal::Base* _pointerOnSignal) {
void esignal::InterfaceData::add(esignal::Base* _pointerOnSignal) {
if (_pointerOnSignal == nullptr) {
ESIGNAL_ERROR("Try to link a nullptr parameters");
return;
@ -28,7 +28,7 @@ void esignal::Interface::signalAdd(esignal::Base* _pointerOnSignal) {
m_list.push_back(_pointerOnSignal);
}
void esignal::Interface::signalRemove(esignal::Base* _pointerOnSignal) {
void esignal::InterfaceData::remove(esignal::Base* _pointerOnSignal) {
auto it = m_list.begin();
while (it != m_list.end()) {
if ( *it == nullptr
@ -40,7 +40,7 @@ void esignal::Interface::signalRemove(esignal::Base* _pointerOnSignal) {
}
}
std::vector<std::string> esignal::Interface::signalGetAll() const {
std::vector<std::string> esignal::InterfaceData::getAll() const {
std::vector<std::string> out;
for (auto &it : m_list) {
if(it != nullptr) {
@ -50,7 +50,7 @@ std::vector<std::string> esignal::Interface::signalGetAll() const {
return out;
}
void esignal::Interface::signalDisconnect(const std::shared_ptr<void>& _object) {
void esignal::InterfaceData::disconnect(const std::shared_ptr<void>& _object) {
if (_object == nullptr) {
ESIGNAL_ERROR("Input ERROR nullptr pointer Object ...");
return;
@ -62,3 +62,5 @@ void esignal::Interface::signalDisconnect(const std::shared_ptr<void>& _object)
it->disconnectShared(_object);
}
}

View File

@ -12,36 +12,51 @@
namespace esignal {
class Base;
class Interface {
friend class esignal::Base; // to register parameter in the list.
/**
* @brief Interface data to collect the Signal list (for abstarction connection)
*/
class InterfaceData {
private:
std::vector<esignal::Base*> m_list; //!< list of availlable Parameters
public:
/**
* @brief Constructor.
*/
Interface();
InterfaceData();
/**
* @brief Destructor.
*/
virtual ~Interface();
virtual ~InterfaceData();
/**
* @brief Register a parameter class pointer in the List of parameters
* @brief Register a signal class pointer in the List of signal list
* @note This class does not destroy the parameter pointer!!!
* @param[in] _pointerOnSignal Pointer on the signal that might be added.
*/
void signalAdd(esignal::Base* _pointerOnSignal);
void signalRemove(esignal::Base* _pointerOnSignal);
void add(esignal::Base* _pointerOnSignal);
/**
* @brief Remove a signal class pointer in the List of signal list
* @note This class does not destroy the parameter pointer!!!
* @param[in] _pointerOnSignal Pointer on the signal that might be removed.
*/
void remove(esignal::Base* _pointerOnSignal);
/**
* @brief Get All the signal list:
* @return vector on all the signals names
*/
std::vector<std::string> signalGetAll() const;
std::vector<std::string> getAll() const;
/**
* @brief Remove binding on all event class.
* @param[in] _sharedPtr sharedPtr to unlink (no type needed ...).
*/
void signalDisconnect(const std::shared_ptr<void>& _sharedPtr);
void disconnect(const std::shared_ptr<void>& _sharedPtr);
};
/**
* @brief Interface to collect the Signal list (for abstarction connection)
* It create a simple "signal" member that permit to access at the signalproperties.
*/
class Interface {
public:
esignal::InterfaceData signal; //!< Interface to access at all signal properties...
};
}

View File

@ -13,7 +13,7 @@ namespace esignal {
/**
* @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
* @param TYPE Type of the internal data
*/
template<class TYPE>
class LockSharedPtrRef {
@ -60,7 +60,7 @@ namespace esignal {
* @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);
void disconnect(size_t _uid);
/**
* @brief Check if the value is availlable
* @return true The data is availlable

View File

@ -21,7 +21,10 @@ namespace esignal {
int64_t m_count; //!< number of element connected
TYPE* m_data; //!< Pointer on the refconting data
public:
//!< generic constructor
/**
* @brief generic constructor
* @param[in] _data Data to reference the Refcounting
*/
RefCount(TYPE* _data);
//! @brief Copy constructor (REMOVED)
RefCount(const RefCount&) = delete;
@ -36,19 +39,19 @@ namespace esignal {
//! @brief Destructor
~RefCount();
public:
//!< @brief Lock the interface
//! @brief Lock the interface
void lock();
//!< @brief Unlock the interface
//! @brief Unlock the interface
void unlock();
//!< @brief Increment the ref-counting
//! @brief Increment the ref-counting
void inc();
//!< @brief Decrement the ref-counting
//! @brief Decrement the ref-counting
int64_t dec();
//!< @brief Get number of connected
//! @brief Get number of connected
int64_t getCount() const;
//!< @brief Remove the data
//! @brief Remove the data
void remove();
//!< @brief Get the recoreded data
//! @brief Get the recoreded data
TYPE* get();
};
}

View File

@ -35,10 +35,15 @@ namespace esignal {
int32_t m_callInProgress; //!< know if we are in a recursive loop
public:
/**
* @brief Basic constructor
* @brief Basic constructor with connection observer
* @param[in] _countObs Local observer to know the count of connection on the signal.
*/
Signal(ObserverConnection _countObs=nullptr);
/**
* @brief Basic constructor with connection observer
* @param[in] _class Class which is associated the function to call.
* @param[in] _func Function to call when an observer has connected or disconnected.
*/
template<class CLASS_TYPE, class FUNC_TYPE>
Signal(CLASS_TYPE* _class, FUNC_TYPE _func);
//! @brief Copy constructor (REMOVED)
@ -87,7 +92,6 @@ namespace esignal {
private:
/**
* @brief Executor specific to the Shared_ptr caller that does not want to worry about the removing of the signal.
* @param[in] T_ARGS... Argument of the signal
*/
class ExecutorShared : public Executor {
protected:
@ -106,12 +110,13 @@ namespace esignal {
*/
virtual void emit(const T_ARGS&... _values);
public:
virtual bool isSharedPtr(const std::shared_ptr<void>& _obj);
bool isSharedPtr(const std::shared_ptr<void>& _obj) override;
};
public:
/**
* @brief Connect an observer on the signal.
* @param[in] _observer Observer to call.
* @return Connection handle (connection is removed if the handle is destroy)
*/
template< class OBSERVER_TYPE >
esignal::Connection connect(OBSERVER_TYPE&& _observer);
@ -120,6 +125,7 @@ namespace esignal {
* @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.
* @return Connection handle (connection is removed if the handle is destroy)
*/
template<class CLASS_TYPE, class FUNC_TYPE, class... FUNC_ARGS_TYPE>
esignal::Connection connect(CLASS_TYPE* _class,
@ -129,7 +135,7 @@ namespace esignal {
* @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.
* @param[in] _args Argument optinnal the user want to add.
*/
template<class PARENT_CLASS_TYPE, class CLASS_TYPE, typename... FUNC_ARGS_TYPE>
void connect(const std::shared_ptr<PARENT_CLASS_TYPE>& _class,
@ -142,14 +148,22 @@ namespace esignal {
*/
void emit(const T_ARGS&... _args);
protected:
/**
* @brief Remove observer in the internal list if the user has disconnected
* @note Done only if it is the last caller ...
*/
void removeIfPossible();
public:
/**
* @brief Disconnect an observer of the signal.
* @param[in] _uid Unique id of the signal.
* @param[in] _uid Unique id of the signal connection.
*/
void disconnect(std::size_t _uid);
void disconnectShared(const std::shared_ptr<void>& _obj);
void disconnect(size_t _uid) override;
/**
* @brief Disconnect the shared_ptr form the Signal
* @param[in] _obj Link with the object to check
*/
void disconnectShared(const std::shared_ptr<void>& _obj) override;
/**
* @brief Get the number of observers connected on the signal.
* @return The count of observer.
@ -174,7 +188,7 @@ template< class OBSERVER_TYPE >
esignal::Connection esignal::Signal<T_ARGS...>::connect(OBSERVER_TYPE&& _observer ) {
ESIGNAL_DEBUG("esignal: '" << getName() << "' try connect: '" << getName() << "' (observer)");
std::unique_ptr<Executor> executer(new Executor(std::forward<OBSERVER_TYPE>(_observer)));
std::size_t uid = executer->m_uid;
size_t uid = executer->m_uid;
m_executors.push_back(std::move(executer));
if (m_connectionObserver!=nullptr) {
m_connectionObserver(m_executors.size());
@ -196,7 +210,7 @@ esignal::Connection esignal::Signal<T_ARGS...>::connect(CLASS_TYPE* _class,
std::unique_ptr<Executor> executer(new Executor([=](const T_ARGS& ... _argBase){
(*_class.*_func)(_argBase..., _arg... );
}));
std::size_t uid = executer->m_uid;
size_t uid = executer->m_uid;
m_executors.push_back(std::move(executer));
if (m_connectionObserver != nullptr) {
m_connectionObserver(m_executors.size());

View File

@ -10,9 +10,6 @@
#include <esignal/ISignal.h>
#include <esignal/details/Signal.hxx>
#undef __class__
#define __class__ "ISignal<T_ARGS>"
template<class... T_ARGS>
esignal::ISignal<T_ARGS...>::ISignal(esignal::Interface* _signalInterfaceLink,
const std::string& _name,
@ -22,14 +19,14 @@ esignal::ISignal<T_ARGS...>::ISignal(esignal::Interface* _signalInterfaceLink,
m_description(_description) {
// add a reference on the current signal ...
if (m_signalInterfaceLink != nullptr) {
m_signalInterfaceLink->signalAdd(this);
m_signalInterfaceLink->signal.add(this);
}
}
template<class... T_ARGS>
esignal::ISignal<T_ARGS...>::~ISignal() {
if (m_signalInterfaceLink != nullptr) {
m_signalInterfaceLink->signalRemove(this);
m_signalInterfaceLink->signal.remove(this);
}
}
@ -43,6 +40,3 @@ const std::string& esignal::ISignal<T_ARGS...>::getDescription() const {
return m_description;
}
#undef __class__
#define __class__ nullptr

View File

@ -91,7 +91,7 @@ void esignal::LockSharedPtrRef<TYPE>::removeData() {
}
template<class TYPE>
void esignal::LockSharedPtrRef<TYPE>::disconnect(std::size_t _uid) {
void esignal::LockSharedPtrRef<TYPE>::disconnect(size_t _uid) {
ESIGNAL_VERBOSE("LockSharedPtrRef disconnect [START] " << _uid);
if (m_counter == nullptr) {
ESIGNAL_VERBOSE("LockSharedPtrRef disconnect [STOP] No counter");

View File

@ -9,9 +9,6 @@
#include <esignal/Signal.h>
#undef __class__
#define __class__ "Signal<T_ARGS>"
template<typename... T_ARGS>
esignal::Signal<T_ARGS...>::Signal(ObserverConnection _countObs):
esignal::Base(_countObs),
@ -19,8 +16,6 @@ esignal::Signal<T_ARGS...>::Signal(ObserverConnection _countObs):
// nothing to do
}
template<typename... T_ARGS>
void esignal::Signal<T_ARGS...>::emit(const T_ARGS&... _args) {
#ifdef DEBUG
@ -78,7 +73,7 @@ void esignal::Signal<T_ARGS...>::removeIfPossible() {
}
template<typename... T_ARGS>
void esignal::Signal<T_ARGS...>::disconnect(std::size_t _uid) {
void esignal::Signal<T_ARGS...>::disconnect(size_t _uid) {
for (size_t iii=0; iii < m_executors.size(); ++iii) {
if (m_executors[iii]->m_uid == _uid) {
m_executors[iii]->m_removed = true;
@ -181,8 +176,3 @@ bool esignal::Signal<T_ARGS...>::ExecutorShared::isSharedPtr(const std::shared_p
}
return false;
}
#undef __class__
#define __class__ nullptr

View File

@ -55,7 +55,10 @@ def create(target, module_name):
'esignal/details/RefCount.hxx',
])
my_module.compile_version("c++", 2011)
my_module.add_module_depend(['etk'])
my_module.add_module_depend([
'etk',
'ememory'
])
my_module.add_path(tools.get_current_path(__file__))
my_module.compile_flags('c++', [
"-DESIGNAL_VERSION=\"\\\"" + tools.version_to_string(get_version()) + "\\\"\""

View File

@ -103,25 +103,25 @@ TEST(test_isignal_counter, localbasicInterfaceGetListSignal) {
list.push_back("int");
list.push_back("string");
list.push_back("float");
EXPECT_EQ(localClass.signalGetAll(), list);
EXPECT_EQ(localClass.signal.getAll(), list);
}
TEST(test_isignal_counter, localbasicInterfaceDisconnectNullPtr) {
testISignal localClass;
localClass.signalDisconnect(nullptr);
localClass.signal.disconnect(nullptr);
}
TEST(test_isignal_counter, localbasicInterfaceDisconnectSharedPtr) {
testISignal localClass;
std::shared_ptr<testCallbackIShared> tmp = std::make_shared<testCallbackIShared>();
localClass.signalDisconnect(tmp);
localClass.signal.disconnect(tmp);
EXPECT_EQ(localClass.m_signalInt.size(), 0);
EXPECT_EQ(localClass.m_signalInt.empty(), true);
localClass.m_signalInt.connect(tmp, &testCallbackIShared::callbackConstInt);
EXPECT_EQ(localClass.m_signalInt.size(), 1);
EXPECT_EQ(localClass.m_signalInt.empty(), false);
localClass.m_signalInt.emit(34567);
localClass.signalDisconnect(tmp);
localClass.signal.disconnect(tmp);
EXPECT_EQ(localClass.m_signalInt.size(), 0);
EXPECT_EQ(localClass.m_signalInt.empty(), true);
}