[DEV] add missing test
This commit is contained in:
parent
84d5614a66
commit
3772d04916
152
esignal/ISignal.h
Normal file
152
esignal/ISignal.h
Normal file
@ -0,0 +1,152 @@
|
||||
/**
|
||||
* @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>
|
||||
|
||||
namespace esignal {
|
||||
#undef __class__
|
||||
#define __class__ "Signal<T>"
|
||||
template<typename T> class Signal : public esignal::Base {
|
||||
private:
|
||||
std::vector<std::pair<std::weak_ptr<void>,
|
||||
std::function<void(const T&)>>> m_callerList; // current list of binded element
|
||||
std::vector<std::pair<std::weak_ptr<void>,
|
||||
std::function<void(const T&)>>> m_callerListInCallback; // temporaty list (when add one in call process)
|
||||
std::vector<std::function<void(const T&)>> m_callerListDirect; // current list of binded element
|
||||
std::vector<std::function<void(const T&)>> m_callerListDirectInCallback; // temporaty list (when add one in call process)
|
||||
public:
|
||||
/**
|
||||
* @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.
|
||||
* @param[in] _periodic Customisation of the log display tag at true to down debug lebel at verbose.
|
||||
*/
|
||||
Signal(esignal::Interface& _signalInterfaceLink,
|
||||
const std::string& _name,
|
||||
const std::string& _description = "",
|
||||
bool _periodic = false);
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~Signal();
|
||||
/**
|
||||
* @brief Bind a callback function to the current signal (generic methis (simplest))
|
||||
* @param[in] _obj Shared pointer on the caller object
|
||||
* @param[in] _func Link on the fuction that might be called (inside a class)
|
||||
* @example signalXXXX.bind(shared_from_this(), &ClassName::onCallbackXXX);
|
||||
*/
|
||||
template<class TYPE_CLASS, class TYPE, typename... TArgs>
|
||||
void bind(std::shared_ptr<TYPE_CLASS> _obj, void (TYPE::*_func)(const T&, TArgs...), TArgs... _args2) {
|
||||
std::shared_ptr<TYPE> obj2 = std::dynamic_pointer_cast<TYPE>(_obj);
|
||||
if (obj2 == nullptr) {
|
||||
ESIGNAL_ERROR("Can not bind signal ...");
|
||||
return;
|
||||
}
|
||||
if (m_callInProgress == 0) {
|
||||
m_callerList.push_back(std::make_pair(std::weak_ptr<void>(_obj), std::bind(_func, obj2.get(), std::placeholders::_1, std::forward<TArgs>(_args2)...)));
|
||||
} else {
|
||||
m_callerListInCallback.push_back(std::make_pair(std::weak_ptr<void>(_obj), std::bind(_func, obj2.get(), std::placeholders::_1, std::forward<TArgs>(_args2)...)));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Advanced binding a callback function to the current signal.
|
||||
* @param[in] _obj Shared pointer on the caller object
|
||||
* @param[in] _func functor to call (do it yourself)
|
||||
* @example signalXXXX.connect(shared_from_this(), std::bind(&ClassName::onCallbackXXX, this, std::placeholders::_1));
|
||||
*/
|
||||
void connect(std::shared_ptr<void> _obj, std::function<void(const T&)> _function );
|
||||
//! @previous
|
||||
void connect(std::function<void(const T&)> _function );
|
||||
/**
|
||||
* @brief Check if an object is registered in the Signal
|
||||
* @param[in] _obj shared pointer on the object
|
||||
* @return true The object is connected at this signal.
|
||||
* @return false The object is NOT connected on this signal.
|
||||
*/
|
||||
bool isRegistered(std::shared_ptr<void> _obj);
|
||||
/**
|
||||
* @brief remove link on the signal.
|
||||
* @param[in] _obj shared pointer on the removing object
|
||||
*/
|
||||
void release(std::shared_ptr<void> _obj);
|
||||
/**
|
||||
* @brief Generate a signal on all interface listening.
|
||||
* @param[in] _data data to emit
|
||||
*/
|
||||
void emit(const T& _data);
|
||||
size_t getNumberConnected();
|
||||
};
|
||||
#undef __class__
|
||||
#define __class__ "Signal<void>"
|
||||
template<> class Signal<void> : public esignal::Base {
|
||||
private:
|
||||
std::vector<std::pair<std::weak_ptr<void>, std::function<void()>>> m_callerList;
|
||||
std::vector<std::pair<std::weak_ptr<void>, std::function<void()>>> m_callerListInCallback;
|
||||
std::vector<std::function<void()>> m_callerListDirect;
|
||||
std::vector<std::function<void()>> m_callerListDirectInCallback;
|
||||
public:
|
||||
/**
|
||||
* @brief Create a signal with a specific 'void' type.
|
||||
* @param[in] _signalInterfaceLink reference on the signal lister.
|
||||
* @param[in] _name Static name of the signal.
|
||||
* @param[in] _description Description of the signal.
|
||||
* @param[in] _periodic Customisation of the log display tag at true to down debug lebel at verbose.
|
||||
*/
|
||||
Signal(esignal::Interface& _signalInterfaceLink,
|
||||
const std::string& _name,
|
||||
const std::string& _description = "",
|
||||
bool _periodic = false);
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~Signal();
|
||||
/**
|
||||
* @brief Bind a callback function to the current signal (generic methis (simplest))
|
||||
* @param[in] _obj Shared pointer on the caller object
|
||||
* @param[in] _func Link on the fuction that might be called (inside a class)
|
||||
* @example signalXXXX.connect(shared_from_this(), &ClassName::onCallbackXXX);
|
||||
*/
|
||||
template<class TYPE_CLASS, class TYPE, typename... TArgs>
|
||||
void bind(std::shared_ptr<TYPE_CLASS> _obj, void (TYPE::*_func)(TArgs...), TArgs... args2) {
|
||||
std::shared_ptr<TYPE> obj2 = std::dynamic_pointer_cast<TYPE>(_obj);
|
||||
if (obj2 == nullptr) {
|
||||
ESIGNAL_ERROR("Can not bind signal ...");
|
||||
return;
|
||||
}
|
||||
if (m_callInProgress == 0) {
|
||||
m_callerList.push_back(std::make_pair(std::weak_ptr<void>(_obj), std::bind(_func, obj2.get(), std::forward<TArgs>(args2)...)));
|
||||
} else {
|
||||
m_callerListInCallback.push_back(std::make_pair(std::weak_ptr<void>(_obj), std::bind(_func, obj2.get(), std::forward<TArgs>(args2)...)));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Advanced binding a callback function to the current signal.
|
||||
* @param[in] _obj Shared pointer on the caller object
|
||||
* @param[in] _func functor to call (do it yourself)
|
||||
* @example signalXXXX.connect(shared_from_this(), std::bind(&ClassName::onCallbackXXX, this, std::placeholders::_1));
|
||||
*/
|
||||
void connect(std::shared_ptr<void> _obj, std::function<void()> _function);
|
||||
//! @previous
|
||||
void connect(std::function<void()> _function);
|
||||
/**
|
||||
* @brief remove link on the signal.
|
||||
* @param[in] _obj shared pointer on the removing object
|
||||
*/
|
||||
void release(std::shared_ptr<void> _obj);
|
||||
void emit();
|
||||
size_t getNumberConnected();
|
||||
};
|
||||
#undef __class__
|
||||
#define __class__ nullptr
|
||||
}
|
||||
|
38
lutin_esignal-test.py
Normal file
38
lutin_esignal-test.py
Normal file
@ -0,0 +1,38 @@
|
||||
#!/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 "TEST"
|
||||
|
||||
def get_desc():
|
||||
return "e-signal test software"
|
||||
|
||||
def get_licence():
|
||||
return "APACHE-2"
|
||||
|
||||
def get_compagny_type():
|
||||
return "com"
|
||||
|
||||
def get_compagny_name():
|
||||
return "atria-soft"
|
||||
|
||||
def get_maintainer():
|
||||
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
|
||||
|
||||
def create(target, module_name):
|
||||
my_module = module.Module(__file__, module_name, get_type())
|
||||
my_module.add_src_file([
|
||||
'test/main.cpp',
|
||||
'test/test_signal_void.cpp',
|
||||
'test/test_signal_arg.cpp',
|
||||
'test/test_signal_args.cpp',
|
||||
])
|
||||
my_module.add_module_depend(['esignal', 'gtest', 'test-debug'])
|
||||
return my_module
|
||||
|
33
test/main.cpp
Normal file
33
test/main.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#define NAME "Empty"
|
||||
|
||||
#include <etk/types.h>
|
||||
#include <etk/etk.h>
|
||||
#include <test-debug/debug.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "etktest"
|
||||
|
||||
int main(int _argc, const char *_argv[]) {
|
||||
::testing::InitGoogleTest(&_argc, const_cast<char **>(_argv));
|
||||
etk::init(_argc, _argv);
|
||||
for (int32_t iii=0; iii<_argc ; ++iii) {
|
||||
std::string data = _argv[iii];
|
||||
if ( data == "-h"
|
||||
|| data == "--help") {
|
||||
TEST_PRINT("esvg-test - help : ");
|
||||
TEST_PRINT(" " << _argv[0] << " [options]");
|
||||
TEST_PRINT(" No optiions ...");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//etk::initDefaultFolder("esvg-test");
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
140
test/test_signal_arg.cpp
Normal file
140
test/test_signal_arg.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#define NAME "SingleArg"
|
||||
#include <gtest/gtest.h>
|
||||
#include <esignal/Signal.h>
|
||||
#include <esignal/Interface.h>
|
||||
#include <memory>
|
||||
#include <test-debug/debug.h>
|
||||
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "test_signal_arg"
|
||||
/*
|
||||
class TestSingleArg : public esignal::Interface {
|
||||
public:
|
||||
esignal::Signal<int32_t> signalInt32;
|
||||
|
||||
TestSingleArg() :
|
||||
signalInt32(*this, "value-int", "Select value change integer") {
|
||||
|
||||
}
|
||||
void emit() {
|
||||
TEST_DEBUG("Emit signal int32 : value=22");
|
||||
signalInt32.emit(22);
|
||||
}
|
||||
};
|
||||
|
||||
class TestConnect : public std::enable_shared_from_this<TestConnect> {
|
||||
public:
|
||||
int32_t m_valueInt32;
|
||||
public:
|
||||
TestConnect():
|
||||
m_valueInt32(0) {
|
||||
|
||||
}
|
||||
void connect(TestSingleArg& _remote) {
|
||||
TEST_DEBUG("connect on signalInt32");
|
||||
_remote.signalInt32.bind(shared_from_this(), &TestConnect::onCallbackInt);
|
||||
}
|
||||
void onCallbackInt(const int32_t& _value) {
|
||||
TEST_DEBUG("onCallbackInt " << _value);
|
||||
m_valueInt32 = _value;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
class TestConnect {
|
||||
public:
|
||||
TestConnect() {
|
||||
|
||||
}
|
||||
void display_values_4( int a, float b, char c) {
|
||||
std::cout << " 4444 " << a << " " << b << " " << c << std::endl;
|
||||
}
|
||||
void display_values_5( int a, float b, char c, std::string _plopppp) {
|
||||
std::cout << " 5555 " << a << " " << b << " " << c << " " << _plopppp << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
class TestConnectShared : public std::enable_shared_from_this<TestConnectShared>{
|
||||
public:
|
||||
TestConnectShared() {
|
||||
|
||||
}
|
||||
void display_values_6( int a, float b, char c) {
|
||||
std::cout << " 6666 " << a << " " << b << " " << c << std::endl;
|
||||
}
|
||||
void display_values_7( int a, float b, char c, std::string _plopppp) {
|
||||
std::cout << " 7777 " << a << " " << b << " " << c << " " << _plopppp << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Func, class... Arg>
|
||||
auto complete_args(Func _f, Arg... _arg) {
|
||||
return [=]( auto&&... cargs ){ return _f( cargs..., _arg... ); };
|
||||
}
|
||||
|
||||
|
||||
template<class pointer, class Func, class... Arg>
|
||||
auto complete_class(pointer* _class, Func _f, Arg... _arg) {
|
||||
return [=]( auto&&... cargs ){
|
||||
//_class->*_f(cargs..., _arg...);
|
||||
(*_class.*_f)(cargs..., _arg...);
|
||||
};
|
||||
}
|
||||
|
||||
TEST(test_signal_arg, checkType) {
|
||||
/*
|
||||
TestSingleArg baseClass;
|
||||
std::shared_ptr<TestConnect> connectedClass = std::make_shared<TestConnect>();
|
||||
connectedClass->connect(baseClass);
|
||||
baseClass.emit();
|
||||
EXPECT_EQ(connectedClass->m_valueInt32, 22);
|
||||
*/
|
||||
esignal::Signal<int, float, char> signal;
|
||||
// ----------------------------------------------------
|
||||
auto display_values_1 = []( int a, float b, char c){
|
||||
std::cout << " 1111 " << a << " " << b << " " << c << " " << std::endl;
|
||||
};
|
||||
signal.connect(display_values_1);
|
||||
|
||||
// ----------------------------------------------------
|
||||
auto display_values_2 = []( int a, float b, char c, int w ){
|
||||
std::cout << " 2222 " << a << " " << b << " " << c << " " << w << std::endl;
|
||||
};
|
||||
signal.connect( complete_args( display_values_2, 72 ) );
|
||||
|
||||
// ----------------------------------------------------
|
||||
TestConnect connectedClass;
|
||||
signal.connect( [&](int a, float b, char c) {
|
||||
connectedClass.display_values_4(a,b,c);}
|
||||
);
|
||||
/*
|
||||
signal.connect( [&](auto && ... _cargs) {
|
||||
connectedClass.display_values_3(_cargs);}
|
||||
);
|
||||
*/
|
||||
signal.connect(&connectedClass, &TestConnect::display_values_4);
|
||||
signal.connect(&connectedClass, &TestConnect::display_values_5, "coucou");
|
||||
|
||||
std::shared_ptr<TestConnectShared> connectedClassShared = std::make_shared<TestConnectShared>();
|
||||
signal.connect(connectedClassShared, &TestConnectShared::display_values_6);
|
||||
signal.connect(connectedClassShared, &TestConnectShared::display_values_7, "coucou");
|
||||
|
||||
|
||||
//signal.connect( complete_class(&connectedClass, &TestConnect::display_values_3) );
|
||||
//signal.connect( TestConnect::display_values_3(&connectedClass) );
|
||||
|
||||
|
||||
// ----------------------------------------------------
|
||||
|
||||
signal.emit( 42, 2.99, 'k');
|
||||
|
||||
}
|
65
test/test_signal_args.cpp
Normal file
65
test/test_signal_args.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#define NAME "SingleArg"
|
||||
#include <gtest/gtest.h>
|
||||
#include <esignal/Signal.h>
|
||||
#include <esignal/Interface.h>
|
||||
#include <memory>
|
||||
#include <test-debug/debug.h>
|
||||
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "test_signal_arg"
|
||||
/*
|
||||
class TestSingleArgs : public esignal::Interface {
|
||||
public:
|
||||
esignal::Signal<int32_t, int32_t> signalInt32;
|
||||
|
||||
TestSingleArgs() :
|
||||
signalInt32(*this, "value-int", "Select value change integer") {
|
||||
|
||||
}
|
||||
void emit() {
|
||||
TEST_DEBUG("Emit signal int32 : value=22,23");
|
||||
signalInt32.emit(22, 23);
|
||||
}
|
||||
};
|
||||
|
||||
class TestConnect : public std::enable_shared_from_this<TestConnect> {
|
||||
public:
|
||||
int32_t m_valueInt32_1;
|
||||
int32_t m_valueInt32_2;
|
||||
public:
|
||||
TestConnect():
|
||||
m_valueInt32_1(0),
|
||||
m_valueInt32_2(0) {
|
||||
|
||||
}
|
||||
void connect(TestSingleArgs& _remote) {
|
||||
TEST_DEBUG("connect on signalInt32");
|
||||
_remote.signalInt32.bind(shared_from_this(), &TestConnect::onCallbackInt);
|
||||
}
|
||||
void onCallbackInt(const int32_t& _value1, const int32_t& _value2) {
|
||||
TEST_DEBUG("onCallbackInt " << _value1 << " " << _value2);
|
||||
m_valueInt32_1 = _value1;
|
||||
m_valueInt32_2 = _value2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST(test_signal_arg, checkType) {
|
||||
TestSingleArgs baseClass;
|
||||
std::shared_ptr<TestConnect> connectedClass = std::make_shared<TestConnect>();
|
||||
connectedClass->connect(baseClass);
|
||||
baseClass.emit();
|
||||
EXPECT_EQ(connectedClass->m_valueInt32_1, 22);
|
||||
EXPECT_EQ(connectedClass->m_valueInt32_2, 23);
|
||||
}
|
||||
|
||||
*/
|
0
test/test_signal_void.cpp
Normal file
0
test/test_signal_void.cpp
Normal file
Loading…
x
Reference in New Issue
Block a user