Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <list>
- #include <iostream>
- #include <functional>
- #include <tuple>
- template<typename... Values> class Signal
- {
- private:
- std::list<std::function<void(Values...)>> fns;
- public:
- void bind(std::function<void(Values...)> fn)
- {
- fns.push_back(fn);
- }
- void emit(Values... values)
- {
- for (auto it = fns.begin(); it != fns.end(); ++it)
- {
- (*it)(values...);
- }
- }
- void operator()(Values... values)
- {
- emit(values...);
- }
- };
- template<typename T> class Property
- {
- public:
- Property(const T& value):m_value(value){}
- void setValue(const T& value)
- {
- if(m_value != value)
- {
- m_value = value;
- m_valueChanged.emit(value);
- onValueChanged.emit();
- }
- }
- const T& operator=(const T& value)
- {
- setValue(value);
- return value;
- }
- operator T() const { return m_value;}
- T getValue() const { return m_value;};
- void bindTo(Property<T>& p)
- {
- p.m_valueChanged.bind(std::function<void(const T&)>(std::bind(&Property::setValue, this, std::placeholders::_1)));
- setValue(p);
- }
- Signal<> onValueChanged;
- private:
- T m_value;
- Signal<const T&> m_valueChanged;
- };
- template<typename T,typename... Args>
- class PropertyFunction
- {
- public:
- PropertyFunction(std::function<T(Args...)> func, Args... args)
- : m_tuple()
- , m_function(func)
- , m_signal()
- {
- recursiveBind<0>(args...);
- }
- template<int i,typename T1,typename... RecArgs>
- void recursiveBind(Property<T1>* p, RecArgs... args)
- {
- //push_back p place i
- p->onValueChanged.bind(std::function<void(void)>(std::bind(&PropertyFunction::update, this)));
- std::get<i>(m_tuple) = p;
- recursiveBind<i+1>(args...);
- }
- template<int i = sizeof...(Args)>
- void recursiveBind(){}
- void update(){recursiveCall();}
- void recursiveCall()
- {
- recursiveCall<1>(std::get<0>(m_tuple));
- }
- template<int i, typename... RecArgs1>
- void recursiveCall(RecArgs1... args)
- {
- //p.onValueChanged.bind();
- //pop_back
- recursiveCall<i+1>(args...,std::get<i>(m_tuple));
- }
- template<int i = sizeof...(Args)>
- void recursiveCall(Args... args)
- {
- std::cout << "new value : " << m_function(args...) << std::endl;
- }
- std::tuple<Args...> m_tuple;
- std::function<T(Args...)> m_function;
- Signal<T> m_signal;
- };
- #define STD_FUNCTION_1(T,P0,EXP, NAME) PropertyFunction<T,decltype(&(P0)))> NAME([](decltype(&(P0)) (P0)) -> T EXP ,&(P0))
- #define STD_FUNCTION_2(T,P0,P1,EXP, NAME) PropertyFunction<T,decltype(&(P0)),decltype(&(P1))> NAME([](decltype(&(P0)) (P0),decltype(&(P1)) (P1)) -> T EXP ,&(P0),&(P1))
- #define STD_FUNCTION_3(T,P0,P1,P2,EXP, NAME) PropertyFunction<T,decltype(&(P0)),decltype(&(P1)),decltype(&(P2))> NAME([](decltype(&(P0)) (P0),decltype(&(P1)) (P1),decltype(&(P2)) (P2)) -> T EXP ,&(P0),&(P1),&(P2))
- int main(int argc, char** argv)
- {
- // Signal<> onEvent;
- // onEvent.bind([]() { std::cout << "Event emited \n";});
- // onEvent.emit();
- Property<double> p = 3.0;
- Property<double> p1 = 4.0;
- //PropertyFunction<double, decltype(&p),decltype(&p1)> test([](decltype(&p) p,decltype(&p1) p1) -> double{return p->getValue()+p1->getValue();},&p,&p1);
- STD_FUNCTION_2(double, p, p1, {return p->getValue()*p1->getValue();},test);
- std::cout << "1 "<< p1<<" \n";
- p1.bindTo(p);
- std::cout << "2 "<< p1<<" \n";
- p = 5.0;
- std::cout << "3 "<< p1<<" \n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement