Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 6th, 2012  |  syntax: None  |  size: 6.01 KB  |  hits: 18  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. Trying to create a new eventHandler using >> overloaded operator, lost myself trying to figure out the required syntax
  2. link >> new eventHandler(&App::testFunction, App);
  3.        
  4. class Link
  5. {
  6. public:
  7.     eventListener* EventListener;
  8.     Link()
  9.     {
  10.         this->EventListener = new eventListener();
  11.     }  
  12.  
  13.     // PROBLEM
  14.     // I am lost here, tried different syntaxes but with no success
  15.     //template<template<class G> class T, class F>
  16.  
  17.     template <class T>
  18.     Link operator>>=(T& ev)
  19.     {
  20.         cout << "something";
  21.          // Here there is no way to declare the proper eventHandler
  22.         eventHandler<?>* event = (eventHandler<?>)ev;
  23.          // I need something like T<F>
  24.         event->eventName = 'onTest';
  25.         this->eventListener->add(event);
  26.         return *this;
  27. }
  28.  
  29. };
  30.  
  31. template<class T, class F>
  32. T operator>>(T& lhs, F& rhs)
  33. {
  34.     return T(lhs)>>=rhs;
  35. }
  36.  
  37. class App
  38. {
  39. public:
  40.     void testFunction(e evt)
  41.     {
  42.         cout << "it works!" << "n";
  43.     }
  44. };
  45.  
  46. int main()
  47. {
  48.     App* app = new App;
  49.     Link* link = new link;
  50.     Link link1;
  51.  
  52.     eventHandler<App>* ev = new eventHandler<App>(app, &App::testFunction);
  53.     link1 >> ev;    
  54.  
  55.     // this line should echo "it works!"
  56.     link1.EventListener->triggerEvent("onTest");
  57.  
  58.     // PART 2
  59.     // HOW CAN I USE?
  60.     // link >> ev;
  61.     // when link is a Link*
  62.  
  63.     return 0;
  64. }
  65.        
  66. #include <iostream>
  67. #include <stdio.h>
  68. #include "events/events.h"
  69. using namespace std;
  70.  
  71. class Link
  72. {
  73. public:
  74.     eventListener* EventListener;
  75.  
  76. public:
  77.     Link()
  78.     {
  79.         this->EventListener = new eventListener();
  80.     }  
  81.  
  82.     template<class T>
  83.     Link operator>>=(const T& ev)
  84.     {
  85.         ev->eventName = "onReceive";
  86.         this->EventListener->add(ev);
  87.         return *this;
  88.     }
  89. };
  90.  
  91. template<class T, class F>
  92. T operator>>(T& lhs, const F& rhs)
  93. {
  94.     return T(lhs)<<=rhs;
  95. }
  96.  
  97. class App
  98. {
  99. public:
  100.     void testReceive(e evt)
  101.     {
  102.         cout << "it works" << "n" << evt.value;
  103.     }
  104.  
  105. };
  106.  
  107. class demo
  108. {
  109. public:
  110.     Link* parent;
  111.     void testit(char* msg)
  112.     {
  113.         parent->EventListener->triggerEvent("onReceive", this, msg);
  114.     }
  115. };
  116.  
  117. int main()
  118. {
  119.     App* app = new App;
  120.     Link link;
  121.  
  122.     eventHandler<App>* ev = new eventHandler<App>(app, &App::testReceive);
  123.     link >> ev;
  124.  
  125.     demo d;
  126.     d.parent = &link;
  127.     // should output "it works!"
  128.     d.testit("here");
  129.  
  130.     return 0;
  131. }
  132.        
  133. #ifndef EVENTS_H
  134. #define EVENTS_H
  135. #include <stdio.h>
  136. #include <string.h>
  137. #include "clist.h"
  138. #include <string>
  139.  
  140. enum scope {global = 0, scoped};
  141.  
  142. struct e
  143. {
  144.     void* target;
  145.     void* value;
  146. };
  147.  
  148. class efunctor //abstract
  149. {
  150. public:
  151.     std::string eventname;
  152.     virtual void operator()(e evt)
  153.     { }
  154.  
  155.     virtual void Call(e evt)
  156.     { }
  157.  
  158. };
  159.  
  160. template <class T>
  161. class eventHandler : public efunctor
  162. {
  163. private:
  164.     T* scope;
  165.     void (T::*eventMethod)(e);
  166. public:
  167.     std::string name;
  168.     std::string eventname;
  169.     eventHandler(std::string eventnam, T* objscope,  void(T::*func)(e))
  170.     {
  171.         this->scope = objscope;
  172.         this->eventMethod = func;
  173.         this->eventname = eventnam;
  174.     }
  175.  
  176.     eventHandler(T* objscope,  void(T::*func)(e))
  177.     {
  178.         this->scope = objscope;
  179.         this->eventMethod = func;
  180.     }
  181.  
  182.     eventHandler(void(T::*func)(e))
  183.     {
  184.         this->eventMethod = func;
  185.     }
  186.  
  187.     void operator()(e evt)
  188.     {
  189.         (scope->*eventMethod)(evt);
  190.     }          
  191.  
  192.     void Call(e evt)
  193.     {
  194.         (scope->*eventMethod)(evt);
  195.     }
  196. };
  197.  
  198. class eventListener
  199. {
  200. private:
  201.     clist< clist<efunctor* > > methods;
  202. public:
  203.  
  204.     template <class T>
  205.     void add(T other)
  206.     {
  207.         other->name = ToString(this->methods[other->eventname].length());
  208.         methods[other->eventname][methods[other->eventname].length()] = other;
  209.     }
  210.  
  211.     template <class T>
  212.     void remove(T other)
  213.     {
  214.         methods[other->eventname]->remove(other->name);
  215.     }
  216.  
  217.     template <class F>
  218.     void triggerEvent(std::string name, void* target, F result)
  219.     {
  220.         e evt;
  221.         evt.target = target;
  222.         evt.value = (char*)result;
  223.         for(methods[name].iterateStart();
  224.                     !methods[name].eoi();
  225.                     methods[name].next())
  226.         {
  227.             (*(methods[name].getCurrentIteration()))(evt);
  228.         }
  229.     }
  230. };
  231. #endif
  232.        
  233. event<void(std::string)> onTest;
  234.        
  235. onTest >> std::bind(std::mem_fn(&App::testFunction), std::ref(app), _1);
  236.        
  237. #include <iostream>
  238. #include <memory>
  239. #include <algorithm>
  240. #include <vector>
  241.  
  242. struct event_base
  243. {
  244.     virtual ~event_base() {}
  245.     virtual void call(std::string const&) = 0;
  246. };
  247.  
  248. template <typename T>
  249. struct event: event_base
  250. {
  251.     event(T* o, void (T::*m)(std::string const&)):
  252.         object(o),
  253.         member(m)
  254.     {
  255.     }
  256.  
  257. private:
  258.     void call(std::string const& arg) {
  259.         (this->object->*member)(arg);
  260.     }
  261.     T*   object;
  262.     void (T::*member)(std::string const&);
  263. };
  264.  
  265.  
  266. template <typename T>
  267. event_base* make_event(T* object, void (T::*member)(std::string const&)) {
  268.     return new event<T>(object, member);
  269. }
  270.  
  271. class event_listener
  272. {
  273. public:
  274.     ~event_listener() { std::for_each(events.begin(), events.end(), &deleter); }
  275.     void add(event_base* event) { this->events.push_back(event); }
  276.     void trigger(std::string const& argument) const {
  277.         for (std::vector<event_base*>::const_iterator it(events.begin()), end(events.end());
  278.              it != end; ++it) {
  279.             (*it)->call(argument);
  280.         }
  281.     }
  282.  
  283. private:
  284.     static void deleter(event_base* ptr) { delete ptr; }
  285.     std::vector<event_base*> events;
  286. };
  287.  
  288. class Link
  289. {
  290. public:
  291.     event_listener listener;
  292.     void operator>>= (event_base* ev) { this->listener.add(ev); }
  293. };
  294.  
  295. void operator<< (Link& link, event_base* ev) {
  296.     link >>= ev;
  297. }
  298.  
  299. class App
  300. {
  301. public:
  302.     void onTest(std::string const& arg) { std::cout << "App::onTest(" << arg << ")n"; }
  303. };
  304.  
  305. int main()
  306. {
  307.     std::auto_ptr<Link> link(new Link);
  308.     std::auto_ptr<App>  app(new App);
  309.  
  310.     *link << make_event(app.get(), &App::onTest);
  311.     link->listener.trigger("hello event");
  312. }
  313.        
  314. template<typename T>
  315. const link &operator>>=(const eventHandler<T>& ev)
  316. {
  317.     ev->eventName = "onTest";
  318.     this->EventListener = &ev;
  319. }