18 Commits
0.1.0 ... 0.4.0

Author SHA1 Message Date
6ab7be7799 [RELEASE] create release 0.4.0 2016-09-12 21:06:37 +02:00
afca4fd646 [DEV] update to future lutin 2.0 2016-09-12 21:07:12 +02:00
31e74185c8 [DEV] update dev tag version 2016-08-30 22:54:08 +02:00
8b97705cb1 [RELEASE] create release 0.3.0 2016-08-30 22:54:08 +02:00
7f9b6b01c5 [DEV] remove ISignal in profit of Signal ==> simplify API 2016-08-04 21:28:40 +02:00
bf72807cef [DEV] add possibility to tag a signal periodic and remove log on it event 2016-08-03 21:45:17 +02:00
a2209a6a0e [DEBUG] correct missing include after update ememory 2016-07-18 02:05:14 +02:00
73f02160b5 [DEV] update new ememory::SharedPtr 2016-07-15 21:22:11 +02:00
ea6e306ee6 [STYLE] remove a space 2016-07-13 21:18:01 +02:00
59ad3091d3 [DEV] update the change on 'enum' to 'enum class' 2016-04-29 23:16:07 +02:00
d03c58a66b [CI] remove warning 2016-04-28 22:13:40 +02:00
6e7619a4e9 [DOC] better doc 2016-04-08 22:26:40 +02:00
0ff8ca484a [DOC] Finish documentation 2016-04-07 21:07:11 +02:00
83d77a1ba9 [DOC] add a basic sample with all assiciated doc and tutorial 2016-04-05 23:45:34 +02:00
3b41672f37 [DEV] change API internal signal => signal'S' 2016-04-05 22:41:25 +02:00
c3c833632b [DOC] compleate function documentation and change API for interface 2016-04-04 23:22:34 +02:00
47ad66bc89 [DEV] use doxygen documentation 2016-03-30 21:40:01 +02:00
05cd1f5cd8 [DEV] add monk file 2016-03-23 22:33:46 +01:00
41 changed files with 1147 additions and 833 deletions

View File

@@ -63,14 +63,14 @@ before_script:
- ./ci/build_send.py --tag=$TAG --status=START;
script:
- lutin -w -j4 -C -P -t$TARGET -c $BUILDER $COMPILATOR_OPTION $BUS -m $CONF $GCOV $DISABLE_PACKAGE esignal-test; STATUS=$?
- lutin -w -j4 -C -P -t$TARGET -c $BUILDER $COMPILATOR_OPTION $BUS -m $CONF $GCOV $DISABLE_PACKAGE esignal-*; STATUS=$?
- ./ci/build_send.py --tag=$TAG --status="$STATUS";
after_script:
- if [ "$GCOV" != "" ]; then
./ci/warning_send.py --find-path ./out/Linux_x86_64/$CONF/build/$BUILDER/esignal/;
fi
- ./out/Linux_x86_64/$CONF/staging/$BUILDER/esignal-test/esignal-test.app/bin/esignal-test --etk-log-level=3 | tee out_test.txt
- lutin -w -j4 -C -P -t$TARGET -c $BUILDER $COMPILATOR_OPTION $BUS -m $CONF $GCOV $DISABLE_PACKAGE esignal-test?run:--elog-level=3 | tee out_test.txt
- if [ "$GCOV" != "" ]; then
./ci/test_send.py --file=out_test.txt;
lutin -C -P -t $TARGET -c $BUILDER $COMPILATOR_OPTION $BUS -m $CONF -p esignal?gcov;

1
authors.txt Normal file
View File

@@ -0,0 +1 @@
MR Edouard DUPIN <yui.heero@gmail.com>

72
doc/build.md Normal file
View File

@@ -0,0 +1,72 @@
Build lib & build sample {#esignal_build}
========================
@tableofcontents
Download: {#esignal_build_download}
=========
esignal use some tools to manage source and build it:
lutin (build-system): {#esignal_build_download_lutin}
---------------------
```{.sh}
pip install lutin --user
# optionnal dependency of lutin (manage image changing size for application release
pip install pillow --user
```
dependency: {#esignal_build_download_dependency}
-----------
```{.sh}
mkdir framework
cd framework
git clone https://github.com/atria-soft/elog.git
git clone https://github.com/atria-soft/etk.git
git clone https://github.com/atria-soft/ememory.git
cd ..
```
sources: {#esignal_build_download_sources}
--------
```{.sh}
cd framework
git clone https://github.com/atria-soft/esignal.git
cd ..
```
Build: {#esignal_build_build}
======
library: {#esignal_build_build_library}
--------
```{.sh}
lutin -mdebug esignal
```
Sample: {#esignal_build_build_sample}
-------
```{.sh}
lutin -mdebug esignal-sample
lutin -mdebug esignal-test
```
Or simple:
```{.sh}
lutin -mdebug esignal-*
```
Run sample: {#esignal_build_run_sample}
===========
```{.sh}
lutin -mdebug esignal-sample?run
```

54
doc/mainpage.md Normal file
View File

@@ -0,0 +1,54 @@
ESIGNAL library {#mainpage}
===============
@tableofcontents
What is ESIGNAL, and how can I use it? {#esignal_mainpage_what}
======================================
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_mainpage_language}
=============================
ESIGNAL is written in C++.
Are there any licensing restrictions? {#esignal_mainpage_restriction}
=====================================
ESIGNAL is **FREE software** and _all sub-library are FREE and staticly linkable !!!_
License (APACHE-2.0) {#esignal_mainpage_license}
====================
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.
Other pages {#eproperty_mainpage_sub_page}
===========
- @ref esignal_build
- @ref esignal_tutorial
- [**ewol coding style**](http://atria-soft.github.io/ewol/ewol_coding_style.html)

112
doc/tutorial.md Normal file
View File

@@ -0,0 +1,112 @@
Tutorial {#esignal_tutorial}
========
@tableofcontents
Declare a Signal: {#esignal_declare}
=================
Declaring a signal is really simple, just include the esignal file:
@snippet sampleAll.cpp esignal_sample_declare
You can now declare your signals. We have basicly declare some basic signal type:
- void
- bool
- std::string / std::u32string
- int8_t / int16_t / int32_t / int64_t
- uint8_t / uint16_t / uint32_t / uint64_t
- float / double
- vec2 / bvec2 / ivec2 / uivec2
- vec3 / bvec3 / ivec3 / uivec3
- etk::Color<unsigned char,4>
- etk::Color<unsigned char,3>
- etk::Color<float,4>
- etk::Color<float,3>
To declare a signal with 'void' type:
@snippet sampleAll.cpp esignal_sample_declare_void
To declare a signal with 'int32_t' type:
@snippet sampleAll.cpp esignal_sample_declare_int
To declare a signal with 'string' type:
@snippet sampleAll.cpp esignal_sample_declare_string
Connecting on a signal {#esignal_connection}
======================
We have some way to connect on a signals depending on where we do the connection.
Connection and basic emition {#esignal_connection_base}
----------------------------
Declare the signal:
@snippet sampleAll.cpp esignal_sample_connection_simple_connection_declare
Declare a generic fuction:
@snippet sampleAll.cpp esignal_sample_connection_simple_extern_function
Connect a generic function:
@snippet sampleAll.cpp esignal_sample_connection_simple_connection_function
Or simply connect a lambda function:
@snippet sampleAll.cpp esignal_sample_connection_simple_connection_lambda
And now, we can emit a simple signal:
@snippet sampleAll.cpp esignal_sample_connection_simple_emit
You can see that all connection return a esignal::Connection value. This is an handle that can not be copiable, but only movable, While this handle is alive, the connection is allive too.
The to remove a connection, we only need to remive the handle or call the esignal::Connection::disconnect fucntion.
To disconnect a signal, it is very simple:
@snippet sampleAll.cpp esignal_sample_connection_simple_disconnect
This Will generate this simple sample code:
@snippet sampleAll.cpp esignal_sample_connection_simple
Connection on class member function {#esignal_connection_class}
-----------------------------------
Declare class fuction:
@snippet sampleAll.cpp esignal_sample_class_connection_callback
For direct connection, you need to have a 'const ref' on the parameter (internal helper design) to bind on the signal
Now you can nonnect the functions:
@snippet sampleAll.cpp esignal_sample_class_connection_callback_connect
This Will generate this simple sample code:
@snippet sampleAll.cpp esignal_sample_class_connection
Connection on std::shared_ptr<class> member function {#esignal_connection_shared}
----------------------------------------------------
std::hared_ptr have intrinsec knoledge of alive pointer, then, if you do not need to remove connection while the shared_ptr is alive, just connect it like:
@snippet sampleAll.cpp esignal_sample_shared_connection
Create new Signal {#esignal_create}
=================
If the signal is not in the list: @ref esignal_declare, you need to declare it yourself. This is due to optimise the compilation time,
in C++ when we inserte many template with all the implementation, the compilation time increase, the we decide to optimise the build time.
Create a new custum signal:
@snippet sampleAll.cpp esignal_sample_new_declare
Connect on the Signal:
@snippet sampleAll.cpp esignal_sample_new_lambda
Emit a Signal:
@snippet sampleAll.cpp esignal_sample_new_emit
This might work good, but at this point the compilation is OK, but not the linking ==> we need to declare the implementation of the signal:
@snippet sampleAll.cpp esignal_sample_new_register
This Will generate this simple sample code:
@snippet sampleAll.cpp esignal_sample_new

34
doxy_esignal.py Normal file
View File

@@ -0,0 +1,34 @@
#!/usr/bin/python
import os
import doxy.module as module
import doxy.debug as debug
import doxy.tools as tools
def create(target, module_name):
my_module = module.Module(__file__, module_name)
my_module.set_version("version.txt")
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.add_path([
module_name,
"doc",
])
my_module.add_sample_path([
"sample",
])
my_module.add_depend([
'etk',
'ememory',
])
my_module.add_exclude_symbols([
'*operator<<*',
])
my_module.add_exclude_file([
'debug.h',
])
my_module.add_file_patterns([
'*.h',
'*.md',
])
return my_module

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -6,34 +6,63 @@
* @license APACHE v2.0 (see license file)
*/
#include <memory>
#include <ememory/memory.h>
#include <esignal/debug.h>
#include <esignal/Interface.h>
#include <esignal/Base.h>
size_t esignal::Base::s_uid = 1;
int64_t esignal::Base::s_uidSignalEmit = 1;
size_t esignal::BaseInternal::s_uid = 1;
int64_t esignal::BaseInternal::s_uidSignalEmit = 1;
esignal::Base::Base(ObserverConnection _countObs) :
m_shared(this),
m_connectionObserver(_countObs) {
void esignal::BaseInternal::setPeriodic(bool _state) {
m_periodic = _state;
}
const std::string& esignal::BaseInternal::getName() const {
return m_name;
}
void esignal::BaseInternal::setName(const std::string& _name) {
m_name = _name;
}
const std::string& esignal::BaseInternal::getDescription() const {
return m_description;
}
void esignal::BaseInternal::setDescription(const std::string& _desc) {
m_description = _desc;
}
esignal::Base::Base() :
m_data(nullptr) {
}
esignal::Base::~Base() {
m_shared.removeData();
m_data.reset();
}
const std::string& esignal::Base::getName() const {
if (m_data != nullptr) {
return m_data->getName();
}
static std::string noValue;
return noValue;
}
const std::string& esignal::Base::getDescription() const {
if (m_data != nullptr) {
return m_data->getDescription();
}
static std::string noValue;
return noValue;
}
void esignal::Base::setPeriodic(bool _state) {
if (m_data != nullptr) {
m_data->setPeriodic(_state);
}
}
std::ostream& esignal::operator <<(std::ostream& _os, const esignal::Base& _obj) {
_os << _obj.getName();

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -8,38 +8,114 @@
#pragma once
#include <functional>
#include <memory>
#include <ememory/memory.h>
#include <esignal/debug.h>
#include <esignal/Base.h>
#include <functional>
#include <type_traits>
#include <utility>
#include <mutex>
#include <esignal/LockSharedPtrRef.h>
/**
* @brief esignal global interface for all signal implementation
*/
namespace esignal {
class Base {
class BaseInternal : public ememory::EnableSharedFromThis<esignal::BaseInternal> {
public:
using ObserverConnection = std::function<void(size_t)>; //!< Define an Observer of the number of observer
protected:
esignal::LockSharedPtrRef<esignal::Base> m_shared; //!< Reference counter on itself.
bool m_periodic; //!< The signal is periodic ==> no log with this signal ... (no really needed)
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<72>t<EFBFBD>ry of the connection handle basic
std::string m_name; //!< name of the signal.
std::string m_description; //!< description of the signal.
public:
//! @brief Basic constructor:
Base(ObserverConnection _countObs = nullptr);
/**
* @brief Basic constructor:
* @param[in] _countObs Observer on the number of connection availlable
*/
BaseInternal(ObserverConnection _countObs) :
m_connectionObserver(_countObs) {
}
virtual ~BaseInternal() = default;
/**
* @brief Disconnect the shared_ptr form the Signal
* @param[in] _obj Link with the object to check
*/
virtual void disconnectShared(const ememory::SharedPtr<void>& _obj) = 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.
*/
const std::string& getName() const;
/**
* @brief Set name of the signal.
* @param[in] _name new name.
*/
void setName(const std::string& _name);
/**
* @brief Get decription of the signal.
* @return requested decription.
*/
const std::string& getDescription() const;
/**
* @brief Set decription of the signal.
* @param[in] _desc new decription.
*/
void setDescription(const std::string& _desc);
/**
* @brief Tag the signal as periodic...
* @param[in] _state state of the periodic element
*/
void setPeriodic(bool _state);
/**
* @brief Get the number of observers connected on the signal.
* @return The count of observer.
*/
virtual size_t size() const = 0;
/**
* @brief Check if we have a connected observers.
* @return true More than one observers.
* @return false No observers.
*/
virtual bool empty() const = 0;
/**
* @brief Clear all connectd observers.
*/
virtual void clear() = 0;
};
/**
* @brief Base signal interface for esignal::Signal (permit to create abstract list of signals...)
*/
class Base {
protected:
ememory::SharedPtr<esignal::BaseInternal> m_data;
public:
/**
* @brief Basic constructor:
*/
Base();
//! @brief Copy constructor:
Base(const Base&) = delete;
//! @brief Move constructor
Base(Base&& _obj) = delete;
Base(Base&&) = delete;
/**
* @brief Virtualize the destructor
* @internal
*/
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;
virtual void disconnectShared(const ememory::SharedPtr<void>& _obj) = 0;
/**
* @brief Get name of the signal.
* @return requested name.
@@ -50,7 +126,13 @@ namespace esignal {
* @return requested decription.
*/
virtual const std::string& getDescription() const;
/**
* @brief Tag the signal as periodic...
* @param[in] _state state of the periodic element
*/
void setPeriodic(bool _state);
};
//! @not-in-doc
std::ostream& operator <<(std::ostream& _os, const esignal::Base& _obj);
#ifdef DEBUG
const char* logIndent(int32_t _iii);

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -9,40 +9,55 @@
#include <esignal/Connection.h>
esignal::Connection::Connection():
m_signalRefUnique(), m_uid(0) {
m_data(nullptr),
m_uid(0) {
}
esignal::Connection::Connection(const esignal::LockSharedPtrRef<esignal::Base>& _ref, std::size_t _id):
m_signalRefUnique(_ref),
esignal::Connection::Connection(ememory::SharedPtr<esignal::BaseInternal> _ref, size_t _id):
m_data(_ref),
m_uid(_id) {
}
esignal::Connection::Connection(esignal::Connection&& _obj):
m_signalRefUnique(_obj.m_signalRefUnique),
m_data(_obj.m_data),
m_uid(_obj.m_uid) {
_obj.m_uid = 0;
_obj.m_data.reset();
}
esignal::Connection& esignal::Connection::operator=(esignal::Connection&& _obj) {
disconnect();
m_signalRefUnique = _obj.m_signalRefUnique;
m_data = _obj.m_data;
m_uid = _obj.m_uid;
_obj.m_uid = 0;
_obj.m_data.reset();
return *this;
}
esignal::Connection::~Connection() {
m_signalRefUnique.disconnect(m_uid);
ememory::SharedPtr<esignal::BaseInternal> ref = m_data.lock();
if (ref == nullptr) {
return;
}
ref->disconnect(m_uid);
m_data.reset();
m_uid = 0;
}
void esignal::Connection::disconnect() {
m_signalRefUnique.disconnect(m_uid);
ememory::SharedPtr<esignal::BaseInternal> ref = m_data.lock();
if (ref == nullptr) {
return;
}
ref->disconnect(m_uid);
m_data.reset();
m_uid = 0;
}
bool esignal::Connection::isConnected() {
return m_signalRefUnique.isAlive();
return m_data.useCount() != 0
&& m_uid != 0;
}

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -8,35 +8,56 @@
#pragma once
#include <functional>
#include <memory>
#include <ememory/memory.h>
#include <esignal/debug.h>
#include <esignal/Base.h>
#include <functional>
#include <type_traits>
#include <utility>
#include <mutex>
namespace esignal {
/**
* @brief connection on the signal (disconnect it whe removed)
*/
class Connection {
private:
ememory::WeakPtr<esignal::BaseInternal> m_data;
size_t m_uid; //!< UID of the current connection.
public:
//! @brief Constructor (no link)
/**
* @brief Constructor (no link)
*/
Connection();
//! @brief Constructor (link)
Connection(const esignal::LockSharedPtrRef<esignal::Base>& _ref, std::size_t _id);
//! @brief Move Constructor
/**
* @brief Constructor (link)
* @param[in] _ref Reference ID of the Signal extern handle
* @param[in] _id Id of the Connection handle
*/
Connection(ememory::SharedPtr<esignal::BaseInternal> _ref, size_t _id);
/**
* @brief Move Constructor
* @param[in] _obj Connection Object to move
*/
Connection(Connection&& _obj);
//! @brief Move operator.
/**
* @brief Move operator.
* @param[in] _obj Connection Object to move
* @return Local reference on the local object (moved)
*/
Connection& operator=(Connection&& _obj);
//! @brief Copy constructor (REMOVED)
/**
* @brief Copy constructor (REMOVED)
*/
Connection(const Connection&) = delete;
//! @brief Copy operator (REMOVED)
/**
* @brief Copy operator (REMOVED)
* @return Reference on this
*/
Connection& operator=(const Connection&) = delete;
//! @brief Destructor.
/**
* @brief Destructor.
*/
~Connection();
//! @brief Disconnect the signal.
/**
* @brief Disconnect the signal.
*/
void disconnect();
/**
* @brief Check if the connection is alive or signal removed
@@ -44,9 +65,6 @@ namespace esignal {
* @return false The signal is NOT connected.
*/
bool isConnected();
private:
esignal::LockSharedPtrRef<esignal::Base> m_signalRefUnique; //!< reference on the Signal.
std::size_t m_uid; //!< UID of the current connection.
};
}

View File

@@ -1,73 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <functional>
#include <memory>
#include <esignal/debug.h>
#include <esignal/Base.h>
#include <esignal/Signal.h>
#include <esignal/Interface.h>
#undef __class__
#define __class__ "ISignal<T_ARGS>"
namespace esignal {
/**
* @brief Sigla same as @ref esignal::Signal withe a name and a description to manage a list of signals.
*/
template<class... T_ARGS>
class ISignal : public Signal<T_ARGS...> {
protected:
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.
* @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] _name Static name of the signal.
* @param[in] _description Description of the signal.
*/
template<class CLASS_TYPE, class FUNC_TYPE>
ISignal(CLASS_TYPE* _signalInterfaceLink,
FUNC_TYPE _func,
const std::string& _name,
const std::string& _description);
ISignal(esignal::Interface* _signalInterfaceLink,
const std::string& _name,
const std::string& _description);
/**
* @brief Destructor.
*/
virtual ~ISignal();
virtual const std::string& getName() const;
virtual const std::string& getDescription() const;
};
}
template<class... T_ARGS>
template<class CLASS_TYPE, class FUNC_TYPE>
esignal::ISignal<T_ARGS...>::ISignal(CLASS_TYPE* _class,
FUNC_TYPE _func,
const std::string& _name,
const std::string& _description) :
esignal::Signal<T_ARGS...>(_class, _func),
m_signalInterfaceLink(_class),
m_name(_name),
m_description(_description) {
// add a reference on the current signal ...
if (m_signalInterfaceLink != nullptr) {
m_signalInterfaceLink->signalAdd(this);
}
}
#undef __class__
#define __class__ nullptr

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -9,39 +9,16 @@
#include <vector>
#include <map>
#include <esignal/InterfaceData.h>
namespace esignal {
class Base;
/**
* @brief Interface to collect the Signal list (for abstarction connection)
* It create a simple "signals" member that permit to access at the signalproperties.
*/
class Interface {
friend class esignal::Base; // to register parameter in the list.
private:
std::vector<esignal::Base*> m_list; //!< list of availlable Parameters
public:
/**
* @brief Constructor.
*/
Interface();
/**
* @brief Destructor.
*/
virtual ~Interface();
/**
* @brief Register a parameter class pointer in the List of parameters
* @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);
/**
* @brief Get All the signal list:
* @return vector on all the signals names
*/
std::vector<std::string> signalGetAll() 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);
esignal::InterfaceData signals; //!< Interface to access at all signals properties...
};
}

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -6,21 +6,21 @@
* @license APACHE v2.0 (see license file)
*/
#include <memory>
#include <ememory/memory.h>
#include <esignal/debug.h>
#include <esignal/Interface.h>
#include <esignal/InterfaceData.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 ememory::SharedPtr<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);
}
}

54
esignal/InterfaceData.h Normal file
View File

@@ -0,0 +1,54 @@
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <vector>
#include <map>
namespace esignal {
class Base;
/**
* @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.
*/
InterfaceData();
/**
* @brief Destructor.
*/
virtual ~InterfaceData();
/**
* @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 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> getAll() const;
/**
* @brief Remove binding on all event class.
* @param[in] _sharedPtr sharedPtr to unlink (no type needed ...).
*/
void disconnect(const ememory::SharedPtr<void>& _sharedPtr);
};
}

View File

@@ -1,77 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <esignal/RefCount.h>
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
*/
template<class TYPE>
class LockSharedPtrRef {
public:
// TODO : Remove data from refcounter ...==>
// esignal::RefCount* m_counter; //!< Access on the reference counter
// TYPE* m_data; //!< Pointer on the data
esignal::RefCount<TYPE>* 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);
/**
* @brief Copy contructor
* @param[in] _obj object to copy
*/
LockSharedPtrRef(const LockSharedPtrRef<TYPE>& _obj);
/**
* @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<TYPE>& _obj);
/**
* @brief Contructor (move)
* @param[in] _obj move object
*/
LockSharedPtrRef(LockSharedPtrRef<TYPE>&& _obj);
/**
* @brief Copy operator (force move) ==> removed
*/
LockSharedPtrRef& operator=(LockSharedPtrRef<TYPE>&& _obj) = delete;
/**
* @brief Destructor of the class (decrement the counter and remove it if it is the last one...)
*/
~LockSharedPtrRef();
/**
* @brief Remove the data on the conter reference (it does not exist anymore)
*/
void removeData();
/**
* @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);
/**
* @brief Check if the value is availlable
* @return true The data is availlable
* @return false The data has been removed
*/
bool isAlive();
private:
/**
* @remove reference on the refcounter...
*/
void rmShared();
};
}

View File

@@ -1,54 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <utility>
#include <mutex>
namespace esignal {
/**
* @brief Ref counting tool.
*/
template<class TYPE>
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:
//!< generic constructor
RefCount(TYPE* _data);
//! @brief Copy constructor (REMOVED)
RefCount(const RefCount&) = delete;
//! @brief Copy operator (REMOVED)
RefCount& operator=(RefCount) = delete;
//! @previous
RefCount& operator=(const RefCount& _obj) = delete;
//! @brief Move constructor (REMOVED)
RefCount(RefCount&& _obj) = delete;
//! @brief Move operator (REMOVED)
RefCount& operator=(RefCount&& _obj) = delete;
//! @brief Destructor
~RefCount();
public:
//!< @brief Lock the interface
void lock();
//!< @brief Unlock the interface
void unlock();
//!< @brief Increment the ref-counting
void inc();
//!< @brief Decrement the ref-counting
int64_t dec();
//!< @brief Get number of connected
int64_t getCount() const;
//!< @brief Remove the data
void remove();
//!< @brief Get the recoreded data
TYPE* get();
};
}

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -9,47 +9,31 @@
#include <functional>
#include <memory>
#include <ememory/memory.h>
#include <esignal/debug.h>
#include <esignal/Base.h>
#include <esignal/LockSharedPtrRef.h>
#include <esignal/RefCount.h>
#include <esignal/Connection.h>
#include <functional>
#include <type_traits>
#include <utility>
#include <mutex>
#undef __class__
#define __class__ "Signal<T_ARGS>"
#include <esignal/Interface.h>
namespace esignal {
/**
* @brief Basic signal base
* @param[in] Args... Argument of the signal
*/
template<class... T_ARGS>
class Signal : public esignal::Base {
class SignalInternal : public esignal::BaseInternal {
public:
using Observer = std::function<void(const T_ARGS&...)>; //!< Define an Observer: function pointer
protected:
int32_t m_callInProgress; //!< know if we are in a recursive loop
public:
/**
* @brief Basic constructor
* @param[in] _countObs Local observer to know the count of connection on the signal.
* @brief Basic constructor:
* @param[in] _countObs Observer on the number of connection availlable
*/
Signal(ObserverConnection _countObs=nullptr);
template<class CLASS_TYPE, class FUNC_TYPE>
Signal(CLASS_TYPE* _class, FUNC_TYPE _func);
//! @brief Copy constructor (REMOVED)
Signal(const Signal&) = delete;
//! @brief Copy operator (REMOVED)
Signal& operator=(Signal) = delete;
Signal& operator=(const Signal& _obj) = delete;
//! @brief Move constructor (REMOVED)
Signal(Signal&& _obj) = delete;
//! @brief Move operator
Signal& operator=(Signal&& _obj) = delete;
SignalInternal(ObserverConnection _countObs):
esignal::BaseInternal(_countObs),
m_callInProgress(0) {
}
private:
/**
* @brief Executor: Class to manage the UID and basic value of an observer
@@ -80,38 +64,38 @@ namespace esignal {
* @return true The Executor depend on this shared_ptr
* @return false The Executor does not depend on this shared_ptr
*/
virtual bool isSharedPtr(const std::shared_ptr<void>& _obj);
virtual bool isSharedPtr(const ememory::SharedPtr<void>& _obj);
};
protected:
std::vector<std::unique_ptr<Executor>> 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] T_ARGS... Argument of the signal
*/
class ExecutorShared : public Executor {
protected:
std::weak_ptr<void> m_object; //!< a weak reference on the object to verify that it is alive
ememory::WeakPtr<void> 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<void> _object, Observer&& _observer);
ExecutorShared(ememory::WeakPtr<void> _object, Observer&& _observer);
public:
/**
* @brief Emit the data on the observer.
* @param[in] _values... Multiple value needed to send on observers
*/
virtual void emit(const T_ARGS&... _values);
void emit(const T_ARGS&... _values) override;
public:
virtual bool isSharedPtr(const std::shared_ptr<void>& _obj);
bool isSharedPtr(const ememory::SharedPtr<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 +104,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,65 +114,226 @@ 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,
void connect(const ememory::SharedPtr<PARENT_CLASS_TYPE>& _class,
void (CLASS_TYPE::*_func)(const T_ARGS&..., FUNC_ARGS_TYPE...),
FUNC_ARGS_TYPE... _args);
public:
/**
* @brief Emit data on the signal.
* @param[in] _args Argument data to emit.
*/
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:
void disconnect(size_t _uid) override;
void disconnectShared(const ememory::SharedPtr<void>& _obj) override;
size_t size() const override;
bool empty() const override;
void clear() override;
};
/**
* @brief Basic signal base
* @param[in] Args... Argument of the signal
*/
template<class... T_ARGS>
class Signal : public esignal::Base {
protected:
esignal::Interface* m_signalInterfaceLink; //!< interface of the signal manager.
public:
/**
* @brief Disconnect an observer of the signal.
* @param[in] _uid Unique id of the signal.
* @brief Basic constructor with connection observer
* @param[in] _countObs 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.
*/
void disconnect(std::size_t _uid);
void disconnectShared(const std::shared_ptr<void>& _obj);
Signal(esignal::BaseInternal::ObserverConnection _countObs=nullptr,
const std::string& _name="",
const std::string& _description="");
/**
* @brief Basic constructor with connection interface
* @param[in] _signalInterfaceLink reference on the signal lister.
* @param[in] _name Static name of the signal.
* @param[in] _description Description of the signal.
*/
Signal(esignal::Interface* _signalInterfaceLink,
const std::string& _name,
const std::string& _description);
/**
* @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.
* @param[in] _name Static name of the signal.
* @param[in] _description Description of the signal.
*/
template<class CLASS_TYPE,
class FUNC_TYPE,
typename std::enable_if<std::is_base_of<esignal::Interface, CLASS_TYPE>::value
, int>::type = 0>
Signal(CLASS_TYPE* _class,
FUNC_TYPE _func,
const std::string& _name,
const std::string& _description);
template<class CLASS_TYPE,
class FUNC_TYPE,
typename std::enable_if<!std::is_base_of<esignal::Interface, CLASS_TYPE>::value
, int>::type = 0>
Signal(CLASS_TYPE* _class,
FUNC_TYPE _func,
const std::string& _name="",
const std::string& _description="");
//! @brief Copy constructor (REMOVED)
Signal(const Signal&) = delete;
/**
* @brief Copy operator (REMOVED)
* @return Reference on this
*/
Signal& operator=(Signal) = delete;
/**
* @brief Copy operator (REMOVED)
* @return Reference on this
*/
Signal& operator=(const Signal&) = delete;
//! @brief Move constructor (REMOVED)
Signal(Signal&&) = delete;
/**
* @brief Move operator (REMOVED)
* @return Reference on this
*/
Signal& operator=(Signal&&) = delete;
/**
* @brief Destructor.
*/
virtual ~Signal();
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) {
if (m_data == nullptr) {
return esignal::Connection();
}
ememory::SharedPtr<esignal::SignalInternal<T_ARGS...>> pointer = ememory::staticPointerCast<esignal::SignalInternal<T_ARGS...>>(m_data);
return pointer->connect(std::forward<OBSERVER_TYPE>(_observer));
}
/**
* @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] _args 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,
FUNC_TYPE _func,
FUNC_ARGS_TYPE... _args) {
if (m_data == nullptr) {
return esignal::Connection();
}
ememory::SharedPtr<esignal::SignalInternal<T_ARGS...>> pointer = ememory::staticPointerCast<esignal::SignalInternal<T_ARGS...>>(m_data);
return pointer->connect(_class, _func, std::forward<FUNC_ARGS_TYPE>(_args)...);
}
/**
* @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] _args Argument optinnal the user want to add.
*/
template<class PARENT_CLASS_TYPE, class CLASS_TYPE, typename... FUNC_ARGS_TYPE>
void connect(const ememory::SharedPtr<PARENT_CLASS_TYPE>& _class,
void (CLASS_TYPE::*_func)(const T_ARGS&..., FUNC_ARGS_TYPE...),
FUNC_ARGS_TYPE... _args) {
if (m_data == nullptr) {
return;
}
ememory::SharedPtr<esignal::SignalInternal<T_ARGS...>> pointer = ememory::staticPointerCast<esignal::SignalInternal<T_ARGS...>>(m_data);
return pointer->connect(_class, _func, std::forward<FUNC_ARGS_TYPE>(_args)...);
}
public:
/**
* @brief Emit data on the signal.
* @param[in] _args Argument data to emit.
*/
void emit(const T_ARGS&... _args) {
if (m_data == nullptr) {
return;
}
ememory::SharedPtr<esignal::SignalInternal<T_ARGS...>> pointer = ememory::staticPointerCast<esignal::SignalInternal<T_ARGS...>>(m_data);
return pointer->emit(std::forward<const T_ARGS&>(_args)...);
}
public:
/**
* @brief Disconnect the shared_ptr form the Signal
* @param[in] _obj Link with the object to check
*/
void disconnectShared(const ememory::SharedPtr<void>& _obj) override {
if (m_data == nullptr) {
return;;
}
m_data->disconnectShared(_obj);
}
/**
* @brief Get the number of observers connected on the signal.
* @return The count of observer.
*/
size_t size() const;
size_t size() const {
if (m_data == nullptr) {
return 0;
}
return m_data->size();
}
/**
* @brief Check if we have a connected observers.
* @return true More than one observers.
* @return false No observers.
*/
bool empty() const;
bool empty() const {
if (m_data == nullptr) {
return true;
}
return m_data->empty();
}
/**
* @brief Clear all connectd observers.
*/
void clear();
void clear() {
if (m_data == nullptr) {
return;
}
m_data->clear();
}
};
}
template<class... T_ARGS>
template< class OBSERVER_TYPE >
esignal::Connection esignal::Signal<T_ARGS...>::connect(OBSERVER_TYPE&& _observer ) {
template<class OBSERVER_TYPE >
esignal::Connection esignal::SignalInternal<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());
}
ESIGNAL_DEBUG(" '" << getName() << "' new count: " << m_executors.size());
return esignal::Connection(Base::m_shared, uid);
return esignal::Connection(sharedFromThis(), uid);
}
template<class... T_ARGS>
template<class CLASS_TYPE, class FUNC_TYPE, class... FUNC_ARGS_TYPE>
esignal::Connection esignal::Signal<T_ARGS...>::connect(CLASS_TYPE* _class,
FUNC_TYPE _func,
FUNC_ARGS_TYPE... _arg) {
esignal::Connection esignal::SignalInternal<T_ARGS...>::connect(CLASS_TYPE* _class,
FUNC_TYPE _func,
FUNC_ARGS_TYPE... _arg) {
ESIGNAL_DEBUG("esignal: '" << getName() << "' try connect: '" << getName() << "' (reference)");
if (_class == nullptr) {
ESIGNAL_ERROR(" '" << getName() << "' Class pointer in nullptr");
@@ -196,26 +342,26 @@ 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());
}
ESIGNAL_DEBUG(" '" << getName() << "' new count: " << m_executors.size());
return Connection(Base::m_shared, uid);
return Connection(sharedFromThis(), uid);
}
template<class... T_ARGS>
template<class PARENT_CLASS_TYPE, class CLASS_TYPE, typename... FUNC_ARGS_TYPE>
void esignal::Signal<T_ARGS...>::connect(const std::shared_ptr<PARENT_CLASS_TYPE>& _class,
void (CLASS_TYPE::*_func)(const T_ARGS&..., FUNC_ARGS_TYPE...),
FUNC_ARGS_TYPE... _args) {
void esignal::SignalInternal<T_ARGS...>::connect(const ememory::SharedPtr<PARENT_CLASS_TYPE>& _class,
void (CLASS_TYPE::*_func)(const T_ARGS&..., FUNC_ARGS_TYPE...),
FUNC_ARGS_TYPE... _args) {
ESIGNAL_DEBUG("esignal: '" << getName() << "' try connect: '" << getName() << "' (weak pointer)");
if (_class == nullptr) {
ESIGNAL_ERROR(" '" << getName() << "' Class pointer in nullptr");
return;
}
std::shared_ptr<CLASS_TYPE> obj2 = std::dynamic_pointer_cast<CLASS_TYPE>(_class);
ememory::SharedPtr<CLASS_TYPE> obj2 = ememory::dynamicPointerCast<CLASS_TYPE>(_class);
if (obj2 == nullptr) {
ESIGNAL_ERROR("Can not connect signal ...");
return;
@@ -233,13 +379,54 @@ void esignal::Signal<T_ARGS...>::connect(const std::shared_ptr<PARENT_CLASS_TYPE
}
template<class... T_ARGS>
template<class CLASS_TYPE, class FUNC_TYPE>
template<class CLASS_TYPE,
class FUNC_TYPE,
typename std::enable_if<std::is_base_of<esignal::Interface, CLASS_TYPE>::value
, int>::type>
esignal::Signal<T_ARGS...>::Signal(CLASS_TYPE* _class,
FUNC_TYPE _func):
esignal::Base([=](size_t _val){(*_class.*_func)(_val);}),
m_callInProgress(0) {
FUNC_TYPE _func,
const std::string& _name,
const std::string& _description):
m_signalInterfaceLink(nullptr) {
// nothing to do
if (_func != nullptr) {
esignal::Base::m_data = ememory::makeShared<esignal::SignalInternal<T_ARGS...>>([=](size_t _val){(*_class.*_func)(_val);});
} else {
esignal::Base::m_data = ememory::makeShared<esignal::SignalInternal<T_ARGS...>>(nullptr);
}
if (esignal::Base::m_data != nullptr) {
esignal::Base::m_data->setName(_name);
esignal::Base::m_data->setDescription(_description);
}
m_signalInterfaceLink = _class;
// add a reference on the current signal ...
if (m_signalInterfaceLink != nullptr) {
m_signalInterfaceLink->signals.add(this);
}
}
template<class... T_ARGS>
template<class CLASS_TYPE,
class FUNC_TYPE,
typename std::enable_if<!std::is_base_of<esignal::Interface, CLASS_TYPE>::value
, int>::type>
esignal::Signal<T_ARGS...>::Signal(CLASS_TYPE* _class,
FUNC_TYPE _func,
const std::string& _name,
const std::string& _description):
m_signalInterfaceLink(nullptr) {
// nothing to do
if (_func != nullptr) {
esignal::Base::m_data = ememory::makeShared<esignal::SignalInternal<T_ARGS...>>([=](size_t _val){(*_class.*_func)(_val);});
} else {
esignal::Base::m_data = ememory::makeShared<esignal::SignalInternal<T_ARGS...>>(nullptr);
}
if (esignal::Base::m_data != nullptr) {
esignal::Base::m_data->setName(_name);
esignal::Base::m_data->setDescription(_description);
}
}
#undef __class__
#define __class__ nullptr
#define ESIGNAL_DECLARE_SIGNAL(...) \
template class esignal::Signal<__VA_ARGS__>; \
template class esignal::SignalInternal<__VA_ARGS__>;

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved

View File

@@ -1,51 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <esignal/details/ISignal.hxx>
#include <etk/types.h>
#include <etk/math/Vector2D.h>
#include <etk/math/Vector3D.h>
#include <etk/Color.h>
#undef __class__
#define __class__ "ISignal<void>"
// void generic signal
template class esignal::ISignal<>;
// std generic signal
template class esignal::ISignal<bool>;
template class esignal::ISignal<std::string>;
#if __CPP_VERSION__ >= 2011
template class esignal::ISignal<std::u32string>;
#endif
template class esignal::ISignal<int64_t>;
template class esignal::ISignal<int32_t>;
template class esignal::ISignal<int16_t>;
template class esignal::ISignal<int8_t>;
template class esignal::ISignal<uint64_t>;
template class esignal::ISignal<uint32_t>;
template class esignal::ISignal<uint16_t>;
template class esignal::ISignal<uint8_t>;
template class esignal::ISignal<float>;
template class esignal::ISignal<double>;
// etk generic vetor 2D
template class esignal::ISignal<vec2>;
template class esignal::ISignal<bvec2>;
template class esignal::ISignal<ivec2>;
template class esignal::ISignal<uivec2>;
// etk generic vetor 3D
template class esignal::ISignal<vec3>;
template class esignal::ISignal<bvec3>;
template class esignal::ISignal<ivec3>;
template class esignal::ISignal<uivec3>;
// etk generic color
template class esignal::ISignal<etk::Color<unsigned char,4>>;
template class esignal::ISignal<etk::Color<unsigned char,3>>;
template class esignal::ISignal<etk::Color<float,4>>;
template class esignal::ISignal<etk::Color<float,3>>;

View File

@@ -1,48 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#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,
const std::string& _description):
m_signalInterfaceLink(_signalInterfaceLink),
m_name(_name),
m_description(_description) {
// add a reference on the current signal ...
if (m_signalInterfaceLink != nullptr) {
m_signalInterfaceLink->signalAdd(this);
}
}
template<class... T_ARGS>
esignal::ISignal<T_ARGS...>::~ISignal() {
if (m_signalInterfaceLink != nullptr) {
m_signalInterfaceLink->signalRemove(this);
}
}
template<class... T_ARGS>
const std::string& esignal::ISignal<T_ARGS...>::getName() const {
return m_name;
}
template<class... T_ARGS>
const std::string& esignal::ISignal<T_ARGS...>::getDescription() const {
return m_description;
}
#undef __class__
#define __class__ nullptr

View File

@@ -1,16 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <esignal/debug.h>
#include <esignal/details/LockSharedPtrRef.hxx>
#include <esignal/Base.h>
// only one really needed ...
template class esignal::LockSharedPtrRef<esignal::Base>;

View File

@@ -1,117 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <esignal/LockSharedPtrRef.h>
#include <esignal/debug.h>
template<class TYPE>
esignal::LockSharedPtrRef<TYPE>::LockSharedPtrRef(TYPE* _pointer) :
m_counter(nullptr) {
ESIGNAL_VERBOSE("LockSharedPtrRef new [START] " << int64_t(_pointer));
if (_pointer != nullptr) {
m_counter = new RefCount<TYPE>(_pointer);
m_counter->inc();
}
ESIGNAL_VERBOSE("LockSharedPtrRef new [STOP]");
}
template<class TYPE>
esignal::LockSharedPtrRef<TYPE>::LockSharedPtrRef(const LockSharedPtrRef<TYPE>& _obj) :
m_counter(_obj.m_counter) {
ESIGNAL_VERBOSE("LockSharedPtrRef new [START] ref ...");
if (m_counter == nullptr) {
return;
}
m_counter->inc();
ESIGNAL_VERBOSE("LockSharedPtrRef new [STOP]");
}
template<class TYPE>
esignal::LockSharedPtrRef<TYPE>& esignal::LockSharedPtrRef<TYPE>::operator=(const esignal::LockSharedPtrRef<TYPE>& _obj) {
ESIGNAL_VERBOSE("LockSharedPtrRef copy [START]");
if (&_obj == this) {
ESIGNAL_VERBOSE("LockSharedPtrRef copy [STOP] auto-copy");
return *this;
}
if (m_counter != nullptr) {
m_counter->dec();
m_counter = nullptr;
}
m_counter = _obj.m_counter;
if (m_counter == nullptr) {
ESIGNAL_VERBOSE("LockSharedPtrRef copy [STOP] no counter");
return *this;
}
m_counter->inc();
ESIGNAL_VERBOSE("LockSharedPtrRef copy [STOP]");
return *this;
}
template<class TYPE>
esignal::LockSharedPtrRef<TYPE>::LockSharedPtrRef(LockSharedPtrRef<TYPE>&& _obj) :
m_counter(std::move(_obj.m_counter)) {
ESIGNAL_VERBOSE("LockSharedPtrRef move [DONE]");
}
template<class TYPE>
esignal::LockSharedPtrRef<TYPE>::~LockSharedPtrRef() {
ESIGNAL_VERBOSE("LockSharedPtrRef delete [START]");
rmShared();
ESIGNAL_VERBOSE("LockSharedPtrRef delete [STOP]");
}
template<class TYPE>
void esignal::LockSharedPtrRef<TYPE>::rmShared() {
ESIGNAL_VERBOSE("LockSharedPtrRef rmShared [START]");
if (m_counter == nullptr) {
return;
}
int64_t count = m_counter->dec();
if (count > 0) {
m_counter = nullptr;
return;
}
delete m_counter;
m_counter = nullptr;
ESIGNAL_VERBOSE("LockSharedPtrRef rmShared [STOP]");
}
template<class TYPE>
void esignal::LockSharedPtrRef<TYPE>::removeData() {
ESIGNAL_VERBOSE("LockSharedPtrRef removeData [START]");
if (m_counter != nullptr) {
m_counter->remove();
}
ESIGNAL_VERBOSE("LockSharedPtrRef removeData [STOP]");
}
template<class TYPE>
void esignal::LockSharedPtrRef<TYPE>::disconnect(std::size_t _uid) {
ESIGNAL_VERBOSE("LockSharedPtrRef disconnect [START] " << _uid);
if (m_counter == nullptr) {
ESIGNAL_VERBOSE("LockSharedPtrRef disconnect [STOP] No counter");
return;
}
m_counter->lock();
TYPE* val = m_counter->get();
if (val != nullptr) {
val->disconnect(_uid);
}
m_counter->unlock();
rmShared();
ESIGNAL_VERBOSE("LockSharedPtrRef disconnect [STOP]");
}
template<class TYPE>
bool esignal::LockSharedPtrRef<TYPE>::isAlive() {
ESIGNAL_VERBOSE("LockSharedPtrRef isAlive [DONE] ");
return m_counter != nullptr;
}

View File

@@ -1,16 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <esignal/debug.h>
#include <esignal/details/RefCount.hxx>
#include <esignal/Base.h>
// only one really needed ...
template class esignal::RefCount<esignal::Base>;

View File

@@ -1,80 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <esignal/RefCount.h>
#include <esignal/debug.h>
template<class TYPE>
esignal::RefCount<TYPE>::RefCount(TYPE* _data) :
m_count(0),
m_data(_data) {
ESIGNAL_VERBOSE(int64_t(this) << " RefCount New : " << int64_t(_data));
// nothing to do.
}
template<class TYPE>
esignal::RefCount<TYPE>::~RefCount() {
ESIGNAL_VERBOSE(int64_t(this) << " RefCount delete");
m_data = nullptr;
}
template<class TYPE>
void esignal::RefCount<TYPE>::lock() {
ESIGNAL_VERBOSE(int64_t(this) << " RefCount LOCK [START]");
m_lock.lock();
ESIGNAL_VERBOSE(int64_t(this) << " RefCount LOCK [STOP]");
}
template<class TYPE>
void esignal::RefCount<TYPE>::unlock() {
ESIGNAL_VERBOSE(int64_t(this) << " RefCount UN-LOCK [START]");
m_lock.unlock();
ESIGNAL_VERBOSE(int64_t(this) << " RefCount UN-LOCK [STOP]");
}
template<class TYPE>
void esignal::RefCount<TYPE>::inc() {
ESIGNAL_VERBOSE(int64_t(this) << " RefCount INC [START] " << m_count);
lock();
m_count++;
unlock();
ESIGNAL_VERBOSE(int64_t(this) << " RefCount INC [STOP] " << m_count);
}
template<class TYPE>
int64_t esignal::RefCount<TYPE>::dec() {
ESIGNAL_VERBOSE(int64_t(this) << " RefCount DEC [START] " << m_count);
int64_t val;
lock();
m_count--;
val = m_count;
unlock();
ESIGNAL_VERBOSE(int64_t(this) << " RefCount DEC [STOP] " << m_count);
return val;
}
template<class TYPE>
int64_t esignal::RefCount<TYPE>::getCount() const {
ESIGNAL_VERBOSE(int64_t(this) << " RefCount get count " << m_count);
return m_count;
}
template<class TYPE>
void esignal::RefCount<TYPE>::remove() {
ESIGNAL_VERBOSE(int64_t(this) << " RefCount remove [START]");
lock();
m_data = nullptr;
unlock();
ESIGNAL_VERBOSE(int64_t(this) << " RefCount remove [STOP]");
}
template<class TYPE>
TYPE* esignal::RefCount<TYPE>::get() {
return m_data;
}

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -11,41 +11,40 @@
#include <etk/math/Vector3D.h>
#include <etk/Color.h>
#undef __class__
#define __class__ "Signal<void>"
// void generic signal
template class esignal::Signal<>;
ESIGNAL_DECLARE_SIGNAL();
// std generic signal
template class esignal::Signal<bool>;
template class esignal::Signal<std::string>;
ESIGNAL_DECLARE_SIGNAL(bool);
ESIGNAL_DECLARE_SIGNAL(std::string);
#if __CPP_VERSION__ >= 2011
template class esignal::Signal<std::u32string>;
ESIGNAL_DECLARE_SIGNAL(std::u32string);
#endif
template class esignal::Signal<int64_t>;
template class esignal::Signal<int32_t>;
template class esignal::Signal<int16_t>;
template class esignal::Signal<int8_t>;
ESIGNAL_DECLARE_SIGNAL(int64_t);
ESIGNAL_DECLARE_SIGNAL(int32_t);
ESIGNAL_DECLARE_SIGNAL(int16_t);
ESIGNAL_DECLARE_SIGNAL(int8_t);
template class esignal::Signal<uint64_t>;
template class esignal::Signal<uint32_t>;
template class esignal::Signal<uint16_t>;
template class esignal::Signal<uint8_t>;
ESIGNAL_DECLARE_SIGNAL(uint64_t);
ESIGNAL_DECLARE_SIGNAL(uint32_t);
ESIGNAL_DECLARE_SIGNAL(uint16_t);
ESIGNAL_DECLARE_SIGNAL(uint8_t);
template class esignal::Signal<float>;
template class esignal::Signal<double>;
ESIGNAL_DECLARE_SIGNAL(float);
ESIGNAL_DECLARE_SIGNAL(double);
// etk generic vetor 2D
template class esignal::Signal<vec2>;
template class esignal::Signal<bvec2>;
template class esignal::Signal<ivec2>;
template class esignal::Signal<uivec2>;
ESIGNAL_DECLARE_SIGNAL(vec2);
ESIGNAL_DECLARE_SIGNAL(bvec2);
ESIGNAL_DECLARE_SIGNAL(ivec2);
ESIGNAL_DECLARE_SIGNAL(uivec2);
// etk generic vetor 3D
template class esignal::Signal<vec3>;
template class esignal::Signal<bvec3>;
template class esignal::Signal<ivec3>;
template class esignal::Signal<uivec3>;
ESIGNAL_DECLARE_SIGNAL(vec3);
ESIGNAL_DECLARE_SIGNAL(bvec3);
ESIGNAL_DECLARE_SIGNAL(ivec3);
ESIGNAL_DECLARE_SIGNAL(uivec3);
// etk generic color
template class esignal::Signal<etk::Color<unsigned char,4>>;
template class esignal::Signal<etk::Color<unsigned char,3>>;
template class esignal::Signal<etk::Color<float,4>>;
template class esignal::Signal<etk::Color<float,3>>;
ESIGNAL_DECLARE_SIGNAL(etk::Color<unsigned char,4>);
ESIGNAL_DECLARE_SIGNAL(etk::Color<unsigned char,3>);
ESIGNAL_DECLARE_SIGNAL(etk::Color<float,4>);
ESIGNAL_DECLARE_SIGNAL(etk::Color<float,3>);

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -9,29 +9,61 @@
#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),
m_callInProgress(0) {
// nothing to do
template<class... T_ARGS>
esignal::Signal<T_ARGS...>::~Signal() {
if (m_signalInterfaceLink != nullptr) {
m_signalInterfaceLink->signals.remove(this);
}
}
template<typename... T_ARGS>
esignal::Signal<T_ARGS...>::Signal(esignal::BaseInternal::ObserverConnection _countObs,
const std::string& _name,
const std::string& _description):
esignal::Base(),
m_signalInterfaceLink(nullptr) {
// create internal data assiciated:
m_data = ememory::makeShared<esignal::SignalInternal<T_ARGS...>>(std::move(_countObs));
if (esignal::Base::m_data != nullptr) {
esignal::Base::m_data->setName(_name);
esignal::Base::m_data->setDescription(_description);
}
}
template<class... T_ARGS>
esignal::Signal<T_ARGS...>::Signal(esignal::Interface* _signalInterfaceLink,
const std::string& _name,
const std::string& _description):
m_signalInterfaceLink(_signalInterfaceLink) {
// create internal data assiciated:
m_data = ememory::makeShared<esignal::SignalInternal<T_ARGS...>>(nullptr);
if (esignal::Base::m_data != nullptr) {
esignal::Base::m_data->setName(_name);
esignal::Base::m_data->setDescription(_description);
}
// add a reference on the current signal ...
if (m_signalInterfaceLink != nullptr) {
m_signalInterfaceLink->signals.add(this);
}
}
template<typename... T_ARGS>
void esignal::Signal<T_ARGS...>::emit(const T_ARGS&... _args) {
void esignal::SignalInternal<T_ARGS...>::emit(const T_ARGS&... _args) {
#ifdef DEBUG
int32_t tmpID = s_uidSignalEmit++;
#endif
// TODO : Add protection ... but how ...
m_callInProgress++;
ESIGNAL_DEBUG(esignal::logIndent(m_callInProgress-1) << " signal{" << tmpID << "} : '" << getName() << "' ***/" << m_executors.size());
for (size_t iii=0; iii < m_executors.size(); ++iii) {
ESIGNAL_VERBOSE(esignal::logIndent(m_callInProgress-1) << " {" << tmpID << "} : " << iii);
m_executors[iii]->emit(_args...);
if (m_periodic == false) {
ESIGNAL_DEBUG(esignal::logIndent(m_callInProgress-1) << " signal{" << tmpID << "} : '" << getName() << "' ***/" << m_executors.size());
for (size_t iii=0; iii < m_executors.size(); ++iii) {
ESIGNAL_VERBOSE(esignal::logIndent(m_callInProgress-1) << " {" << tmpID << "} : " << iii);
m_executors[iii]->emit(_args...);
}
} else {
for (size_t iii=0; iii < m_executors.size(); ++iii) {
m_executors[iii]->emit(_args...);
}
}
if (m_callInProgress == 1) {
bool haveRemove = false;
@@ -55,7 +87,7 @@ void esignal::Signal<T_ARGS...>::emit(const T_ARGS&... _args) {
}
template<typename... T_ARGS>
void esignal::Signal<T_ARGS...>::removeIfPossible() {
void esignal::SignalInternal<T_ARGS...>::removeIfPossible() {
if (m_callInProgress != 0) {
return;
}
@@ -78,7 +110,7 @@ void esignal::Signal<T_ARGS...>::removeIfPossible() {
}
template<typename... T_ARGS>
void esignal::Signal<T_ARGS...>::disconnect(std::size_t _uid) {
void esignal::SignalInternal<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;
@@ -89,7 +121,7 @@ void esignal::Signal<T_ARGS...>::disconnect(std::size_t _uid) {
}
template<typename... T_ARGS>
void esignal::Signal<T_ARGS...>::disconnectShared(const std::shared_ptr<void>& _obj) {
void esignal::SignalInternal<T_ARGS...>::disconnectShared(const ememory::SharedPtr<void>& _obj) {
for (size_t iii=0; iii < m_executors.size(); ++iii) {
if (m_executors[iii]->isSharedPtr(_obj) == true) {
m_executors[iii]->m_removed = true;
@@ -99,17 +131,17 @@ void esignal::Signal<T_ARGS...>::disconnectShared(const std::shared_ptr<void>& _
}
template<typename... T_ARGS>
size_t esignal::Signal<T_ARGS...>::size() const {
size_t esignal::SignalInternal<T_ARGS...>::size() const {
return m_executors.size();
}
template<typename... T_ARGS>
bool esignal::Signal<T_ARGS...>::empty() const {
bool esignal::SignalInternal<T_ARGS...>::empty() const {
return m_executors.empty();
}
template<typename... T_ARGS>
void esignal::Signal<T_ARGS...>::clear() {
void esignal::SignalInternal<T_ARGS...>::clear() {
for (size_t iii=0; iii < m_executors.size(); ++iii) {
m_executors[iii]->m_removed = true;
}
@@ -118,7 +150,7 @@ void esignal::Signal<T_ARGS...>::clear() {
template<typename... T_ARGS>
esignal::Signal<T_ARGS...>::Executor::Executor(Observer&& _observer):
esignal::SignalInternal<T_ARGS...>::Executor::Executor(Observer&& _observer):
m_removed(false),
m_uid(0) {
m_uid = s_uid++;
@@ -126,7 +158,7 @@ esignal::Signal<T_ARGS...>::Executor::Executor(Observer&& _observer):
}
template<typename... T_ARGS>
void esignal::Signal<T_ARGS...>::Executor::emit(const T_ARGS&... _values) {
void esignal::SignalInternal<T_ARGS...>::Executor::emit(const T_ARGS&... _values) {
if (m_removed == true) {
return;
}
@@ -138,7 +170,7 @@ void esignal::Signal<T_ARGS...>::Executor::emit(const T_ARGS&... _values) {
}
template<typename... T_ARGS>
bool esignal::Signal<T_ARGS...>::Executor::isSharedPtr(const std::shared_ptr<void>& _obj) {
bool esignal::SignalInternal<T_ARGS...>::Executor::isSharedPtr(const ememory::SharedPtr<void>& _obj) {
return false;
}
@@ -146,16 +178,16 @@ bool esignal::Signal<T_ARGS...>::Executor::isSharedPtr(const std::shared_ptr<voi
template<typename... T_ARGS>
esignal::Signal<T_ARGS...>::ExecutorShared::ExecutorShared(std::weak_ptr<void> _object, Observer&& _observer) :
esignal::SignalInternal<T_ARGS...>::ExecutorShared::ExecutorShared(ememory::WeakPtr<void> _object, Observer&& _observer) :
Executor(std::move(_observer)),
m_object(_object) {
}
template<typename... T_ARGS>
void esignal::Signal<T_ARGS...>::ExecutorShared::emit(const T_ARGS&... _values) {
void esignal::SignalInternal<T_ARGS...>::ExecutorShared::emit(const T_ARGS&... _values) {
// TODO: maybe an error if the object is not manage by the same thread.
std::shared_ptr<void> destObject = m_object.lock();
ememory::SharedPtr<void> destObject = m_object.lock();
if (destObject == nullptr) {
Executor::m_removed = true;
return;
@@ -171,8 +203,8 @@ void esignal::Signal<T_ARGS...>::ExecutorShared::emit(const T_ARGS&... _values)
}
template<typename... T_ARGS>
bool esignal::Signal<T_ARGS...>::ExecutorShared::isSharedPtr(const std::shared_ptr<void>& _obj) {
std::shared_ptr<void> destObject = m_object.lock();
bool esignal::SignalInternal<T_ARGS...>::ExecutorShared::isSharedPtr(const ememory::SharedPtr<void>& _obj) {
ememory::SharedPtr<void> destObject = m_object.lock();
if (destObject == nullptr) {
return true;
}
@@ -181,8 +213,3 @@ bool esignal::Signal<T_ARGS...>::ExecutorShared::isSharedPtr(const std::shared_p
}
return false;
}
#undef __class__
#define __class__ nullptr

34
lutin_esignal-sample.py Normal file
View File

@@ -0,0 +1,34 @@
#!/usr/bin/python
import lutin.module as module
import lutin.tools as tools
import datetime
def get_type():
return "BINARY"
def get_sub_type():
return "SAMPLE"
def get_desc():
return "e-signal sample 1"
def get_licence():
return "APACHE-2"
def get_compagny_type():
return "com"
def get_compagny_name():
return "atria-soft"
def get_maintainer():
return "authors.txt"
def create(target, module_name):
my_module = module.Module(__file__, module_name, get_type())
my_module.add_src_file([
'sample/sampleAll.cpp'
])
my_module.add_depend(['esignal', 'test-debug'])
return my_module

View File

@@ -23,7 +23,7 @@ def get_compagny_name():
return "atria-soft"
def get_maintainer():
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
return "authors.txt"
def create(target, module_name):
my_module = module.Module(__file__, module_name, get_type())
@@ -37,6 +37,6 @@ def create(target, module_name):
'test/test_signal_static_func.cpp',
'test/test_isignal.cpp'
])
my_module.add_module_depend(['esignal', 'gtest', 'test-debug'])
my_module.add_depend(['esignal', 'gtest', 'test-debug'])
return my_module

View File

@@ -22,42 +22,37 @@ def get_compagny_name():
return "atria-soft"
def get_maintainer():
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
return "authors.txt"
def get_version():
return [0,1,"dev"]
return "version.txt"
def create(target, module_name):
my_module = module.Module(__file__, module_name, get_type())
my_module.add_extra_compile_flags()
my_module.add_extra_flags()
my_module.add_src_file([
'esignal/debug.cpp',
'esignal/Connection.cpp',
'esignal/Interface.cpp',
'esignal/InterfaceData.cpp',
'esignal/Base.cpp',
'esignal/details/LockSharedPtrRef.cpp',
'esignal/details/RefCount.cpp',
'esignal/details/Signal.cpp',
'esignal/details/ISignal.cpp',
])
my_module.add_header_file([
'esignal/debug.h',
'esignal/Interface.h',
'esignal/InterfaceData.h',
'esignal/Base.h',
'esignal/Signal.h',
'esignal/ISignal.h',
'esignal/LockSharedPtrRef.h',
'esignal/RefCount.h',
'esignal/Connection.h',
'esignal/details/Signal.hxx',
'esignal/details/ISignal.hxx',
'esignal/details/LockSharedPtrRef.hxx',
'esignal/details/RefCount.hxx',
])
my_module.compile_version("c++", 2011)
my_module.add_module_depend(['etk'])
my_module.add_depend([
'etk',
'ememory'
])
my_module.add_path(tools.get_current_path(__file__))
my_module.compile_flags('c++', [
my_module.add_flag('c++', [
"-DESIGNAL_VERSION=\"\\\"" + tools.version_to_string(get_version()) + "\\\"\""
])
my_module.add_tools(['esignal-test'])

19
monk_esignal.py Normal file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/python
import monkModule
import monkTools as tools
import os
def get_desc():
return "E-signal simple signal syncronous library"
def create():
# module name is 'ewol' and type binary.
myModule = monkModule.Module(__file__, 'esignal', 'LIBRARY')
# enable doculentation :
myModule.set_website("http://atria-soft.github.io/esignal/")
myModule.set_website_sources("http://github.com/atria-soft/esignal/")
myModule.set_path(os.path.join(tools.get_current_path(__file__), "esignal"))
myModule.set_path_general_doc(os.path.join(tools.get_current_path(__file__), "doc"))
# add the currrent module at the
return myModule

156
sample/sampleAll.cpp Normal file
View File

@@ -0,0 +1,156 @@
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/etk.h>
#include <test-debug/debug.h>
//! [esignal_sample_declare]
#include <esignal/Signal.h>
//! [esignal_sample_declare]
void declareSignals() {
//! [esignal_sample_declare_int]
esignal::Signal<int32_t> signalInt;
//! [esignal_sample_declare_int]
//! [esignal_sample_declare_void]
esignal::Signal<> signalVoid;
//! [esignal_sample_declare_void]
//! [esignal_sample_declare_string]
esignal::Signal<std::string> signalString;
//! [esignal_sample_declare_string]
}
//! [esignal_sample_connection_simple]
//! [esignal_sample_connection_simple_extern_function]
void localCallBack(int32_t _val) {
TEST_PRINT("Callback Local the value is : " << _val);
}
//! [esignal_sample_connection_simple_extern_function]
void basicConnection() {
// Create the signal
//! [esignal_sample_connection_simple_connection_declare]
esignal::Signal<int32_t> signalValue;
//! [esignal_sample_connection_simple_connection_declare]
// Connect the signal function
//! [esignal_sample_connection_simple_connection_function]
esignal::Connection con1 = signalValue.connect(&localCallBack);
//! [esignal_sample_connection_simple_connection_function]
// Connect the signal Lambda
//! [esignal_sample_connection_simple_connection_lambda]
esignal::Connection con2 = signalValue.connect(
[](int32_t _val) {
TEST_PRINT("Callback 1 the value is : " << _val);
});
//! [esignal_sample_connection_simple_connection_lambda]
// Emit the signal
//! [esignal_sample_connection_simple_emit]
signalValue.emit(1001001);
//! [esignal_sample_connection_simple_emit]
// Disconnect the connection n°1
//! [esignal_sample_connection_simple_disconnect]
con1.disconnect();
//! [esignal_sample_connection_simple_disconnect]
// Second emit to check disconnection
signalValue.emit(2002002);
}
//! [esignal_sample_connection_simple]
//*********************************************************************************************
//! [esignal_sample_class_connection]
//! [esignal_sample_class_connection_callback]
class TmpClass {
public:
void localCallBack(const int32_t& _val) {
TEST_PRINT("Callback Local the value is : " << _val);
}
void localCallBackSecond(const int32_t& _val, const std::string& _otherValue) {
TEST_PRINT("Callback 2 Local the value is : " << _val << " with perso: '" << _otherValue << "'");
}
};
//! [esignal_sample_class_connection_callback]
void classConnection() {
// Create the signal
esignal::Signal<int32_t> signalValue;
// Declare the class
TmpClass myClass;
// Connect signals
//! [esignal_sample_class_connection_callback_connect]
esignal::Connection con1 = signalValue.connect(&myClass, &TmpClass::localCallBack);
esignal::Connection con2 = signalValue.connect(&myClass, &TmpClass::localCallBackSecond, "Hello, HowAreYou");
//! [esignal_sample_class_connection_callback_connect]
// Emit sample signals
signalValue.emit(4004004);
}
//! [esignal_sample_class_connection]
//! [esignal_sample_shared_connection]
void sharedConnection() {
// Create the signal
esignal::Signal<int32_t> signalValue;
// Declare the class
ememory::SharedPtr<TmpClass> myClassShared = ememory::makeShared<TmpClass>();
// Connect signals
signalValue.connect(myClassShared, &TmpClass::localCallBack);
// Emit sample signals
signalValue.emit(7007007);
}
//! [esignal_sample_shared_connection]
//! [esignal_sample_new]
void newSignal() {
// Declare new signal
//! [esignal_sample_new_declare]
esignal::Signal<int32_t, std::string> signalCustum;
//! [esignal_sample_new_declare]
// Connect a lambda
//! [esignal_sample_new_lambda]
esignal::Connection con2 = signalCustum.connect(
[](int32_t _val, std::string _val2) {
TEST_PRINT("lambda callback: " << _val << " vel2=" << _val2);
});
//! [esignal_sample_new_lambda]
// Example emit
//! [esignal_sample_new_emit]
signalCustum.emit(1001001, "plop");
//! [esignal_sample_new_emit]
}
// do it in a single C++: Implementation of signal
//! [esignal_sample_new_register]
#include <esignal/details/Signal.hxx>
ESIGNAL_DECLARE_SIGNAL(int32_t, std::string);
//! [esignal_sample_new_register]
//! [esignal_sample_new]
int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv);
TEST_INFO("declare [START] ***************************");
declareSignals();
TEST_INFO("declare [STOP] ***************************");
TEST_INFO("Basic connection [START] ***************************");
basicConnection();
TEST_INFO("Basic connection [STOP] ***************************");
TEST_INFO("class connection [START] ***************************");
classConnection();
TEST_INFO("class connection [STOP] ***************************");
TEST_INFO("shared_ptr connection [START] ***************************");
sharedConnection();
TEST_INFO("shared_ptr connection [STOP] ***************************");
return 0;
}

View File

@@ -8,6 +8,7 @@
#include <esignal/details/Signal.hxx>
#include <etk/types.h>
template class esignal::Signal<int32_t, std::string>;
ESIGNAL_DECLARE_SIGNAL(int32_t, std::string);

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -12,9 +12,6 @@
#include <test-debug/debug.h>
#include <gtest/gtest.h>
#undef __class__
#define __class__ "esignal-test"
int main(int _argc, const char *_argv[]) {
::testing::InitGoogleTest(&_argc, const_cast<char **>(_argv));
etk::init(_argc, _argv);

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -8,20 +8,17 @@
#define NAME "SingleArg"
#include <gtest/gtest.h>
#include <esignal/ISignal.h>
#include <esignal/Signal.h>
#include <esignal/Interface.h>
#include <memory>
#include <ememory/memory.h>
#include <test-debug/debug.h>
#undef __class__
#define __class__ "test_isignal"
class testISignal : public esignal::Interface {
public:
esignal::ISignal<int32_t> m_signalInt;
esignal::ISignal<std::string> m_signalString;
esignal::ISignal<float> m_signalFloat;
esignal::Signal<int32_t> m_signalInt;
esignal::Signal<std::string> m_signalString;
esignal::Signal<float> m_signalFloat;
public:
size_t m_count;
testISignal():
@@ -88,7 +85,7 @@ TEST(test_isignal_counter, localbasicNameDesc) {
EXPECT_EQ(localClass.m_signalString.getDescription(), "desc string");
}
class testCallbackIShared : public std::enable_shared_from_this<testCallbackIShared> {
class testCallbackIShared : public ememory::EnableSharedFromThis<testCallbackIShared> {
public:
testCallbackIShared() {
}
@@ -103,25 +100,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.signals.getAll(), list);
}
TEST(test_isignal_counter, localbasicInterfaceDisconnectNullPtr) {
testISignal localClass;
localClass.signalDisconnect(nullptr);
localClass.signals.disconnect(nullptr);
}
TEST(test_isignal_counter, localbasicInterfaceDisconnectSharedPtr) {
testISignal localClass;
std::shared_ptr<testCallbackIShared> tmp = std::make_shared<testCallbackIShared>();
localClass.signalDisconnect(tmp);
ememory::SharedPtr<testCallbackIShared> tmp = ememory::makeShared<testCallbackIShared>();
localClass.signals.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.signals.disconnect(tmp);
EXPECT_EQ(localClass.m_signalInt.size(), 0);
EXPECT_EQ(localClass.m_signalInt.empty(), true);
}

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -10,12 +10,9 @@
#include <gtest/gtest.h>
#include <esignal/Signal.h>
#include <esignal/Interface.h>
#include <memory>
#include <ememory/memory.h>
#include <test-debug/debug.h>
#undef __class__
#define __class__ "test_signal_class_func"
class testCallback {
public:
int32_t m_int32;

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -10,12 +10,9 @@
#include <gtest/gtest.h>
#include <esignal/Signal.h>
#include <esignal/Interface.h>
#include <memory>
#include <ememory/memory.h>
#include <test-debug/debug.h>
#undef __class__
#define __class__ "test_signal_counter"
class testCounter {
public:
esignal::Signal<std::string> m_signal;

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -10,13 +10,9 @@
#include <gtest/gtest.h>
#include <esignal/Signal.h>
#include <esignal/Interface.h>
#include <memory>
#include <ememory/memory.h>
#include <test-debug/debug.h>
#undef __class__
#define __class__ "test_signal_static_func"
static esignal::Signal<int32_t>* signalll;
static int32_t tmpRetInt32 = 0;

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -10,13 +10,10 @@
#include <gtest/gtest.h>
#include <esignal/Signal.h>
#include <esignal/Interface.h>
#include <memory>
#include <ememory/memory.h>
#include <test-debug/debug.h>
#undef __class__
#define __class__ "test_signal_class_func"
class testCallbackShared : public std::enable_shared_from_this<testCallbackShared> {
class testCallbackShared : public ememory::EnableSharedFromThis<testCallbackShared> {
public:
int32_t m_int32;
std::string m_string;
@@ -77,7 +74,7 @@ class testCallbackShared : public std::enable_shared_from_this<testCallbackShare
m_string = _b + _char;
}
void callbackDisconnect(esignal::Signal<>* _signal) {
_signal->disconnectShared(shared_from_this());
_signal->disconnectShared(sharedFromThis());
}
};
@@ -87,7 +84,7 @@ void removeObserver(size_t _count) {
}
TEST(test_signal_shared_ptr_func, localNullClass) {
std::shared_ptr<testCallbackShared> localClass;
ememory::SharedPtr<testCallbackShared> localClass;
esignal::Signal<> signal(&removeObserver);
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -99,7 +96,7 @@ TEST(test_signal_shared_ptr_func, localNullClass) {
/*
Impossible case ...
TEST(test_signal_shared_ptr_func, localNullFunction) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -111,7 +108,7 @@ TEST(test_signal_shared_ptr_func, localNullFunction) {
}
*/
TEST(test_signal_shared_ptr_func, localFunctionVoid) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -123,7 +120,7 @@ TEST(test_signal_shared_ptr_func, localFunctionVoid) {
}
TEST(test_signal_shared_ptr_func, localFunctionInt32) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<int32_t> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -139,7 +136,7 @@ TEST(test_signal_shared_ptr_func, localFunctionInt32) {
}
TEST(test_signal_shared_ptr_func, localFunctionConstInt32) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<int32_t> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -151,7 +148,7 @@ TEST(test_signal_shared_ptr_func, localFunctionConstInt32) {
}
TEST(test_signal_shared_ptr_func, localFunctionString) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<std::string> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -167,7 +164,7 @@ TEST(test_signal_shared_ptr_func, localFunctionString) {
}
TEST(test_signal_shared_ptr_func, localFunctionConstString) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<std::string> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -179,7 +176,7 @@ TEST(test_signal_shared_ptr_func, localFunctionConstString) {
}
TEST(test_signal_shared_ptr_func, localFunctionIntString) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<int32_t, std::string> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -196,7 +193,7 @@ TEST(test_signal_shared_ptr_func, localFunctionIntString) {
}
TEST(test_signal_shared_ptr_func, localFunctionConstIntString) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<int32_t, std::string> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -209,7 +206,7 @@ TEST(test_signal_shared_ptr_func, localFunctionConstIntString) {
}
TEST(test_signal_shared_ptr_func, localFunctionMixedIntString) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<int32_t, std::string> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -227,7 +224,7 @@ TEST(test_signal_shared_ptr_func, localFunctionMixedIntString) {
TEST(test_signal_shared_ptr_func, localFunctionConstIntStringPolyArg) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<int32_t, std::string> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -249,7 +246,7 @@ class testCallbackSharedHerited : public testCallbackShared {
TEST(test_signal_shared_ptr_func, localFunctionHerited) {
std::shared_ptr<testCallbackSharedHerited> localClass = std::make_shared<testCallbackSharedHerited>();
ememory::SharedPtr<testCallbackSharedHerited> localClass = ememory::makeShared<testCallbackSharedHerited>();
esignal::Signal<int32_t, std::string> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -263,7 +260,7 @@ TEST(test_signal_shared_ptr_func, localFunctionHerited) {
TEST(test_signal_shared_ptr_func, disconnect) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<int32_t> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -279,7 +276,7 @@ TEST(test_signal_shared_ptr_func, disconnect) {
TEST(test_signal_shared_ptr_func, connect_disconnect_multiple) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<int32_t> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -305,7 +302,7 @@ TEST(test_signal_shared_ptr_func, connect_disconnect_multiple) {
TEST(test_signal_shared_ptr_func, disconnect_inCallback) {
std::shared_ptr<testCallbackShared> localClass = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClass = ememory::makeShared<testCallbackShared>();
esignal::Signal<> signal;
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -322,8 +319,8 @@ static void callbackVoid() {
}
TEST(test_signal_shared_ptr_func, localFunctionWeakTest) {
std::shared_ptr<testCallbackShared> localClassA = std::make_shared<testCallbackShared>();
std::shared_ptr<testCallbackShared> localClassB = std::make_shared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClassA = ememory::makeShared<testCallbackShared>();
ememory::SharedPtr<testCallbackShared> localClassB = ememory::makeShared<testCallbackShared>();
esignal::Signal<> signal(&removeObserver);
EXPECT_EQ(signal.size(), 0);
EXPECT_EQ(signal.empty(), true);
@@ -342,7 +339,7 @@ TEST(test_signal_shared_ptr_func, localFunctionWeakTest) {
signal.emit();
EXPECT_EQ(signal.size(), 3);
EXPECT_EQ(signal.empty(), false);
localClassB = std::make_shared<testCallbackShared>();
localClassB = ememory::makeShared<testCallbackShared>();
signal.connect(localClassB, &testCallbackShared::callbackVoid);
EXPECT_EQ(signal.size(), 4);
EXPECT_EQ(signal.empty(), false);

View File

@@ -1,4 +1,4 @@
/**
/** @file
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
@@ -10,13 +10,9 @@
#include <gtest/gtest.h>
#include <esignal/Signal.h>
#include <esignal/Interface.h>
#include <memory>
#include <ememory/memory.h>
#include <test-debug/debug.h>
#undef __class__
#define __class__ "test_signal_static_func"
static int32_t tmpRetInt32 = 0;
static std::string tmpRetString = "";
static bool tmpRetVoid = false;

1
version.txt Normal file
View File

@@ -0,0 +1 @@
0.4.0