Advertisement
Guest User

Property binding c++

a guest
Dec 27th, 2013
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.30 KB | None | 0 0
  1. #include <list>
  2. #include <iostream>
  3. #include <functional>
  4. #include <tuple>
  5.  
  6. template<typename... Values> class Signal
  7. {
  8. private:
  9.     std::list<std::function<void(Values...)>> fns;
  10. public:
  11.     void bind(std::function<void(Values...)> fn)
  12.     {
  13.         fns.push_back(fn);
  14.     }
  15.     void emit(Values... values)
  16.     {
  17.         for (auto it = fns.begin(); it != fns.end(); ++it)
  18.         {
  19.             (*it)(values...);
  20.         }
  21.     }
  22.    
  23.     void operator()(Values... values)
  24.     {
  25.         emit(values...);
  26.     }
  27. };
  28.  
  29. template<typename T> class Property
  30. {
  31. public:
  32.     Property(const T& value):m_value(value){}
  33.     void setValue(const T& value)
  34.     {
  35.         if(m_value != value)
  36.         {
  37.             m_value = value;
  38.             m_valueChanged.emit(value);
  39.             onValueChanged.emit();
  40.         }
  41.  
  42.     }
  43.     const T& operator=(const T& value)
  44.     {
  45.         setValue(value);
  46.         return value;
  47.     }
  48.     operator T() const { return m_value;}
  49.    
  50.     T getValue() const { return m_value;};
  51.    
  52.     void bindTo(Property<T>& p)
  53.     {
  54.         p.m_valueChanged.bind(std::function<void(const T&)>(std::bind(&Property::setValue, this, std::placeholders::_1)));
  55.         setValue(p);
  56.     }
  57.    
  58.     Signal<> onValueChanged;
  59.        
  60. private:
  61.     T m_value;
  62.     Signal<const T&> m_valueChanged;
  63. };
  64.  
  65. template<typename T,typename... Args>
  66. class PropertyFunction
  67. {
  68. public:
  69.     PropertyFunction(std::function<T(Args...)> func, Args... args)
  70.     : m_tuple()
  71.     , m_function(func)
  72.     , m_signal()
  73.     {
  74.         recursiveBind<0>(args...);
  75.     }
  76.    
  77.     template<int i,typename T1,typename... RecArgs>
  78.     void recursiveBind(Property<T1>* p, RecArgs... args)
  79.     {
  80.         //push_back p place i
  81.         p->onValueChanged.bind(std::function<void(void)>(std::bind(&PropertyFunction::update, this)));
  82.         std::get<i>(m_tuple) = p;
  83.         recursiveBind<i+1>(args...);
  84.     }
  85.    
  86.     template<int i = sizeof...(Args)>
  87.     void recursiveBind(){}
  88.    
  89.     void update(){recursiveCall();}
  90.    
  91.     void recursiveCall()
  92.     {
  93.         recursiveCall<1>(std::get<0>(m_tuple));
  94.     }
  95.    
  96.     template<int i, typename... RecArgs1>
  97.     void recursiveCall(RecArgs1... args)
  98.     {
  99.         //p.onValueChanged.bind();
  100.         //pop_back
  101.         recursiveCall<i+1>(args...,std::get<i>(m_tuple));
  102.     }
  103.    
  104.     template<int i = sizeof...(Args)>
  105.     void recursiveCall(Args... args)
  106.     {
  107.         std::cout << "new value : " << m_function(args...) << std::endl;
  108.     }
  109.  
  110.     std::tuple<Args...> m_tuple;
  111.     std::function<T(Args...)> m_function;
  112.     Signal<T>   m_signal;
  113.    
  114. };
  115.  
  116. #define STD_FUNCTION_1(T,P0,EXP, NAME) PropertyFunction<T,decltype(&(P0)))> NAME([](decltype(&(P0)) (P0)) -> T EXP ,&(P0))
  117. #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))
  118. #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))
  119.  
  120.  
  121. int main(int argc, char** argv)
  122. {
  123. //  Signal<> onEvent;
  124. //  onEvent.bind([]() { std::cout << "Event emited \n";});
  125. //  onEvent.emit();
  126.    
  127.     Property<double> p = 3.0;
  128.     Property<double> p1 = 4.0;
  129.     //PropertyFunction<double, decltype(&p),decltype(&p1)> test([](decltype(&p) p,decltype(&p1) p1) -> double{return p->getValue()+p1->getValue();},&p,&p1);
  130.     STD_FUNCTION_2(double, p, p1, {return p->getValue()*p1->getValue();},test);
  131.     std::cout << "1 "<< p1<<" \n";
  132.     p1.bindTo(p);
  133.     std::cout << "2 "<< p1<<" \n";
  134.     p = 5.0;
  135.     std::cout << "3 "<< p1<<" \n";
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement